在 TKE 使用 Traefik 流量网关
概述
Traefik 是一款现代化的云原生反向代理工具,与 Nginx 相比具有以下显著优势:
- 同时支持 Kubernetes Ingress API、Traefik CRD 和 Gateway API 三种流量管理配置方式。
- 提供功能丰富的 Dashboard 管理界面,支持路由可视化配置与监控。
- 深度集成 Prometheus 提供完整的 Metrics 数据,便于监控告警。
- 支持丰富的流量治理功能,包括:多版本灰度发布、流量镜像复制、自动签发 Let's Encrypt HTTPS 证书、灵活的中间件机制等。
本文将介绍如何在 TKE 集群中部署 Traefik 并通过多种配置方式管理流量。
安装 Traefik
- 在 TKE 应用市场 搜索
traefik
。 - 单击
traefik
进入应用详情页。 - 单击创建应用。
- 应用名称建议填
traefik
,选择需要安装 traefik 的目标集群。 - 可参考后文的Traefik 参数配置,根据需求配置完参数后,单击创建即可将 traefik 安装到集群中。
- 安装完后在应用管理中找到 traefik 应用,单击应用名称进入应用详情页,在Service中可以查到 traefik 的 CLB 地址信息,将需要用到的域名配置下 DNS 解析,确保域名能解析到 traefik 的 CLB 地址。
后续若想更改配置,可在应用管理中找到 traefik 应用,单击更新应用并编辑参数即可。
Traefik 参数配置
以下是关于安装 Traefik 的一些参数配置建议,可根据需求进行修改。
本文使用 TKE 应用市场安装 traefik,TKE 应用市场安装的应用是 helm chart,其中 traefik 应用搬运自开源社区的 traefik-helm-chart,参数配置(values.yaml
)与社区完全一致(镜像地址除外),如果你通过 helm 来安装,也可以这里的参数配置建议。
启用 CLB 直连 Pod
建议启用 CLB 直连 Pod,这样 CLB 就可以将流量直接转发给 Pod,无需经过 NodePort,延迟更低,且 Traefik 自身可以感知真实源 IP,后端的业务 Pod 可通过 header 获取真实源 IP。
配置方法如下:
service:
annotations:
service.cloud.tencent.com/direct-access: "true"
使用已有的 CLB
如果已经创建了 CLB,可以指定下 CLB 实例 ID,配置方法如下:
更多详情参考 Service 使用已有 CLB。
注意替换 lb-xxx
为已有的 CLB 实例 ID。
service:
annotations:
service.kubernetes.io/tke-existed-lbid: lb-xxx
公网和内网 同时接入
默认创建的是公网 CLB,可通过类似如下配置实现内网和公网双 CLB 同时接入:
自动创建内网 CLB 需指定子网 ID,注意替换 subnet-xxxxxxxx
。
- 自动创建
- 使用已有CLB
ports:
web:
expose:
default: true
internal: true
websecure:
expose:
default: true
internal: true
service:
additionalServices:
internal:
type: LoadBalancer
annotations:
service.kubernetes.io/qcloud-loadbalancer-internal-subnetid: "subnet-xxxxxxxx" # 配置内网 CLB 的子网
需自行创建内网 CLB,获取实例 ID 并替换配置中的 lb-xxx
。
ports:
web:
expose:
default: true
internal: true
websecure:
expose:
default: true
internal: true
service:
additionalServices:
internal:
type: LoadBalancer
annotations:
service.kubernetes.io/tke-existed-lbid: lb-xxx
IPV4 和 IPV6 同时接入
默认创建的是 IPV4 的 CLB,可通过类似如下配置实现 IPV6 和 IPV4 双 CLB 同时接入:
更多详情请参考 在 TKE 上使用 IPv6。
- 自动创建
- 使用已有CLB
ports:
web:
expose:
default: true
ipv6: true
websecure:
expose:
default: true
ipv6: true
service:
additionalServices:
ipv6:
type: LoadBalancer
annotations:
service.kubernetes.io/service.extensiveParameters: '{"AddressIPVersion":"IPv6FullChain"}'
需自行创建 IPV6 的 CLB,获取实例 ID 并替换配置中的 lb-xxx
。
ports:
web:
expose:
default: true
ipv6: true
websecure:
expose:
default: true
ipv6: true
service:
additionalServices:
ipv6:
type: LoadBalancer
annotations:
service.kubernetes.io/tke-existed-lbid: lb-xxx
启用 Gateway API
默认没启用 Gateway API 的支持,可通过以下配置启用:
providers:
kubernetesGateway:
enabled: true
gateway:
enabled: false # 禁用自动创建与 traefik 在相同命名空间的 Gateway 对象,建议自行按需创建(1 个或多个,可跨命名空间)。
如果同时想禁用 Ingress 和 Traefik 自身 CRD 的支持,可以用如下的配置:
providers:
kubernetesGateway:
enabled: true
kubernetesIngress:
enabled: false
kubernetesCRD:
enabled: false
使用 Ingress 管理流量
Traefik 支持使用 Kubernetes 的 Ingress 资源作为动态配置,可直接在集群中创建 Ingress 资源用于对外暴露集群,需要加上指定的 IngressClass(安装 Traefik 时可自定义,默认为 traefik)。示例如下:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec:
ingressClassName: traefik
rules:
- host: traefik.demo.com
http:
paths:
- path: /test
backend:
serviceName: nginx
servicePort: 80
TKE 暂未将 Traefik 产品化,无法直接在 TKE 控制台进行可视化创建 Ingress,需要使用 YAML 进行创建。
使用 Traefik CRD 管理流量
Traefik 不仅支持标准的 Kubernetes Ingress 资源,也支持 Traefik 特有的 CRD 资源,例如 IngressRoute,可以支持更多 Ingress 不具备的高级功能。IngressRoute 使用示例如下:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: test-ingressroute
spec:
entryPoints:
- web
routes:
- match: Host(`traefik.demo.com`) && PathPrefix(`/test`)
kind: Rule
services:
- name: nginx
port: 80
Traefik 更多用法请参见 Traefik 官方文档。
使用 Gateway API 管理流量
Traefik 也支持了 Gateway API,如果你启用了 Gateway API 的支持,就可以用 Gateway API 的方式来管理流量,下面给出示例。
首先创建 Gateway 对象(定义的端口会自动映射到对应的 LoadBalancer Service,通过 CLB 监听器暴露):
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: prod-gw
namespace: prod
spec:
gatewayClassName: traefik # 指定自动创建出来的 GatewayClass 名称
listeners:
- name: http
protocol: HTTP
port: 8000
allowedRoutes:
namespaces:
from: All
再定义转发规则(如 HTTPRoute
),并引用 Gateway 对象:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: foo
namespace: prod
spec:
parentRefs: # 引用 Gateway 对象
- name: prod-gw
namespace: prod
hostnames:
- "foo.example.com"
rules:
- backendRefs:
- name: foo
port: 8000