Traefik 和 Kubernetes¶
Kubernetes Ingress Controller,自定义资源的方式。
资源配置¶
如果你迫不及待了的话,可以先阅读 动态配置 这个部分文档。
Traefik IngressRoute 定义¶
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutes.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRoute
plural: ingressroutes
singular: ingressroute
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutetcps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteTCP
plural: ingressroutetcps
singular: ingressroutetcp
scope: Namespaced
创建了上面的 CRD 对象后,就可以定义 IngressRoute
类型的对象了,例如:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutefoo
spec:
entryPoints:
- web
routes:
# Match 是与基础路由相对应的规则。
# 然后,match 可能是匹配一个路径前缀的简单形式,例如,只是`/bar`开头的,目前只支持 traefik 样式匹配规则。
- match: Host(`foo.com`) && PathPrefix(`/bar`)
# kind 最终可以是 "Rule"、"Path"、"Host"、"Method"、"Header"、"Parameter" 等,以支持更简单形式的匹配规则,但是现在仅仅支持 "Rule"。
kind: Rule
# (可选) priority 优先级消除了相同长度的规则的歧义,用于路由匹配。
priority: 12
services:
- name: whoami
port: 80
# (默认值 1) 带权重的轮询(WRR)策略的权重值。
weight: 1
# (默认为 true) PassHostHeader 控制是否将请求的主机头信息保留在到达代理之前的状态,还是让代理将其设置为目标(后端)主机。
passHostHeader: true
responseForwarding:
# (默认 100ms) 刷新响应正文到客户端之间的间隔。
flushInterval: 100ms
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
name: ingressroutetcpfoo.crd
spec:
entryPoints:
- footcp
routes:
# Match 是与基础路由对应的规则。
- match: HostSNI(`*`)
services:
- name: whoamitcp
port: 8080
中间件¶
为了允许在 IngressRoute
中使用中间件,我们定义了一个 Middleware
类型的 CRD。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: middlewares.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: Middleware
plural: middlewares
singular: middleware
scope: Namespaced
在 Kubernetes 集群中安装了上面的 CRD 资源后,就可以在 IngressRoute
中定义使用它了,例如:
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: stripprefix
namespace: foo
spec:
stripPrefix:
prefixes:
- /stripit
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutebar
spec:
entryPoints:
- web
routes:
- match: Host(`bar.com`) && PathPrefix(`/stripit`)
kind: Rule
services:
- name: whoami
port: 80
middlewares:
- name: stripprefix
namespace: foo
跨 provider 命名空间
由于 Kubernetes 有自己的命名空间的概念,因此要注意不要和 provider 命名空间 的概念混淆了,当中间件的定义来自另一个 provider 时,在这种情况下,在引用资源时指定命名空间是没有任何一样的,将会被忽略掉。
可以查看 中间件部分文档 了解更多关于中间件的信息。
TLS 选项¶
此外,为了允许在 IngressRoute
中使用 TLS 选项,我们为 TLSOptions 类型定义了一个 CRD 资源对象,有关 TLS 选项的详细信息,请参考 TLS 配置选项 文档。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsoptions.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSOption
plural: tlsoptions
singular: tlsoption
scope: Namespaced
TLSOption 类型在 Kubernetes 集群中注册后,便可以在 IngressRoute
中来定义使用了,例如:
apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
name: mytlsoption
namespace: default
spec:
minVersion: VersionTLS12
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutebar
spec:
entryPoints:
- web
routes:
- match: Host(`bar.com`) && PathPrefix(`/stripit`)
kind: Rule
services:
- name: whoami
port: 80
tls:
options:
name: mytlsoption
namespace: default
引用和命名空间
如果没有设置可选的 namespace
属性,则该配置将和 IngressRoute 的命名空间保持一致。
此外,当 TLS 选项的定义来自其他的 Provider 时,跨 provider 的语法(middlewarename@provider
)应该用于引用 TLS 选项,就像在 中间件示例 中的一样。在这种情况下,指定命名空间熟悉没有任何作用,会呗忽略掉。
TLS¶
为了允许 TLS,我们可以使用定义的 Secret
类型的对象,它可以直接在 IngressRoute
中使用:
apiVersion: v1
kind: Secret
metadata:
name: supersecret
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutetls
spec:
entryPoints:
- web
routes:
- match: Host(`foo.com`) && PathPrefix(`/bar`)
kind: Rule
services:
- name: whoami
port: 443
tls:
secretName: supersecret
示例¶
可以查看 Let's Encrypt 的 完整示例。