跳转至

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 的 完整示例