k8s 之 traefik Ingress
一、概念和部署
1、反向代理与负载均衡
Traefik 是一个现代的反向代理和负载均衡器,专为云原生环境设计,它的核心优势在于:
- 自动化动态配置:能自动发现 Kubernetes 集群中的服务(Service)、Ingress 资源、Endpoints 等,并实时更新路由规则,无需手动重启或重新加载配置(解决了 Nginx 的 reload 问题)。
- 原生集成:与 Kubernetes API 深度集成,开箱即用。
- 多语言支持:使用 Go (Golang) 编写,性能优异,部署简单。
- 丰富的后端支持:不仅支持 Kubernetes,还支持 Docker、Consul、etcd、ZooKeeper 等多种服务发现机制。
- 内置 Web Dashboard:提供直观的图形化界面,用于监控流量、查看路由、调试问题。
- 高级部署策略:原生支持金丝雀发布(Canary)、蓝绿部署(Blue/Green)、灰度发布(Gradual Rollout)等复杂的部署模式。
- 组件精简:相较于 Nginx Ingress Controller(通常需要
controller
+default-backend
+ingress-nginx
镜像),Traefik 的架构更为简洁,核心组件通常只有一个,降低了运维复杂性。
目前traefik已经成为主流,并且traefik有漂亮的dashboard界面,配置简单,已经已经深入和prometheus集成,nginx-ingress需要有3个组件镜像,traefik只有2个
特性
|
nginx ingress
|
traefik ingress
|
协议支持
|
http, https, h2, grpc, tcp, udp
|
http, https, h2, grpc, tcp, tls,udp
|
路由匹配
|
host, path
|
host, path, headers, query, path prefix, method,SNI,path regex
|
命名空间支持
|
-
|
共用或指定命名空间
|
部署策略
|
-
|
金丝雀部署、蓝绿部署、灰度部署
|
upstream 探测
|
重试、超时、心跳探测
|
重试、超时、心跳探测、熔断
|
负载均衡算法
|
RR、会话保持、最小连接、最短时间、一致性hash
|
WRR、动态RR、会话保持
|
优点
|
简单易用,易接入
|
Golang编写,部署容易,支持众多后端,内置WebUI,功能强大
|
缺点
|
没有解决nginx reload,插件多,但是扩展性能差
|
没什么缺点,新版本支持UDP
|
补充说明:
1 协议支持:
Traefik: 明确列出了 tls
和 udp
。tls
通常指在 TCP 层之上运行的 TLS 加密隧道,udp
支持非常关键,因为 Nginx Ingress 不支持 UDP 路由。
2 路由匹配:
Traefik: 补充了 SNI
(Server Name Indication),这是实现一个 IP 地址上承载多个 HTTPS 域名的关键技术。同时,支持 path regex
(正则表达式路径匹配),灵活性更高。
3 upstream 探测:
Traefik 补充了 熔断
(Circuit Breaker) 功能,当后端服务连续失败达到阈值时,会暂时停止向该服务发送请求,防止雪崩。
4 负载均衡算法:
Traefik WRR
(Weighted Round Robin) 是加权轮询,允许为不同后端服务设置权重,实现流量分配。
5 优点:
Traefik: 增加了“功能强大”这一总结性优点,强调其作为现代网关的综合能力。
6 缺点:
对于极其简单的场景,其功能可能显得“大材小用”。
早期版本对某些 Kubernetes 特性的支持可能不如 Nginx 成熟(但这已不是主要问题)。 *
在极少数情况下,其动态配置的机制可能会引入轻微的延迟(但通常可忽略)。
2、helm 自动化方式
Ensure that the following requirements are met:
- Kubernetes 1.14+
- Helm version 3.x is installed
1、Add Traefik's chart repository to Helm(域名解析需要添加8.8.8.8)
helm repo add traefik https://helm.traefik.io/traefik
2、You can update the chart repository by running:
helm repo update
3、And install it with the helm
command line:
kubectl create ns traefik-v2 # Install in the namespace "traefik-v2" helm install --namespace=traefik-v2 \ traefik traefik/traefik
4、Exposing the Traefik dashboard(上面指定了ns)
#kubectl port-forward $(kubectl get pods --selector "app.kubernetes.io/name=traefik" --output=name) 9000:9000 --address=$YOUR_IP kubectl get pods --selector "app.kubernetes.io/name=traefik" --output=name -n traefik-v2 pod/traefik-97ffb8895-k6nl2 kubectl port-forward pod/traefik-97ffb8895-k6nl2 -n traefik-v2 9000:9000 --address 192.168.40.130
3、Deployment + Service + RBAC 原始方式
1、创建命名空间
kubectl create namespace traefik
2、RBAC 配置(必需)
traefik-rbac.yaml
apiVersion: v1 kind: ServiceAccount metadata: name: traefik namespace: traefik --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: traefik rules: - apiGroups: [""] resources: - services - endpoints - secrets verbs: ["get", "list", "watch"] - apiGroups: ["extensions", "networking.k8s.io"] resources: - ingresses - ingressclasses verbs: ["get", "list", "watch"] - apiGroups: ["extensions", "networking.k8s.io"] resources: - ingresses/status verbs: ["update"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: traefik roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: traefik subjects: - kind: ServiceAccount name: traefik namespace: traefik
3、部署 Traefik
traefik-deploy.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: traefik namespace: traefik spec: replicas: 1 selector: matchLabels: app: traefik template: metadata: labels: app: traefik spec: serviceAccountName: traefik containers: - name: traefik image: docker.io/library/traefik:v3.5 imagePullPolicy: Never args: - "--api.insecure=true" # 开启 Traefik Dashboard(测试用) - "--providers.kubernetescrd" # 启用 CRD provider - "--providers.kubernetesingress" # 启用 Ingress provider - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" ports: - name: web containerPort: 80 - name: websecure containerPort: 443 - name: admin containerPort: 8080
4、Service 暴露
traefik-svc.yaml
apiVersion: v1 kind: Service metadata: name: traefik namespace: traefik spec: type: NodePort # 如果有 LoadBalancer 可以改成 LoadBalancer selector: app: traefik ports: - name: web port: 80 targetPort: 80 nodePort: 30080 - name: websecure port: 443 targetPort: 443 nodePort: 30443 - name: admin port: 8080 targetPort: 8080 nodePort: 30081
5、apply
kubectl apply -f traefik-rbac.yaml kubectl apply -f traefik-deploy.yaml kubectl apply -f traefik-svc.yaml
6、访问
http://<任意NodeIP>:30081/dashboard/
4、Traefik CRDs
1、Traefik CRDs(Custom Resource Definitions,自定义资源定义)
是 Kubernetes 中的一种扩展机制,由 Traefik Ingress Controller 引入,用于增强路由功能、支持更复杂的流量管理规则。
它们是 Traefik 在 Kubernetes 环境中实现高级功能的核心组件。
2、为什么需要 CRDs?
Kubernetes 原生的 Ingress
资源功能有限,比如:
- 不支持 TCP/UDP 路由
- 难以配置中间件(如重写、重定向、认证)
- 不支持多协议(HTTP、gRPC、WebSocket 等)
Traefik 通过 CRD 扩展 Kubernetes API,引入了更强大、灵活的自定义资源。
3、CRDs种类及其作用
CRDs名称 |
作用
|
IngressRoute |
替代原生 Ingress,支持更复杂的路由规则(如基于 Header、Path、Host 匹配)
|
Middleware |
定义中间件:URL 重写、重定向、压缩、认证、CORS 等
|
TLSStore |
定义 TLS 证书存储位置,集中管理 HTTPS 证书
|
TraefikService |
支持服务聚合(如负载均衡多个服务)、镜像流量等
|
IngressRouteTCP /IngressRouteUDP |
支持 TCP 和 UDP 协议的路由(如数据库、MQTT)
|
4、安装CRDs支持 IngressRoute
# 下载 wget https://raw.githubusercontent.com/traefik/traefik/v3.5/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml -O traefik-crds.yaml wget https://raw.githubusercontent.com/traefik/traefik/v3.5/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml -O traefik-crd-rbac.yaml # 部署 kubectl apply -f traefik-crds.yaml kubectl apply -f traefik-crd-rbac.yaml # 验证 # kubectl get crd | grep traefik ingressroutes.traefik.io 2025-08-20T06:29:24Z ingressroutetcps.traefik.io 2025-08-20T06:29:24Z ingressrouteudps.traefik.io 2025-08-20T06:29:24Z middlewares.traefik.io 2025-08-20T06:29:24Z middlewaretcps.traefik.io 2025-08-20T06:29:24Z serverstransports.traefik.io 2025-08-20T06:29:24Z serverstransporttcps.traefik.io 2025-08-20T06:29:24Z tlsoptions.traefik.io 2025-08-20T06:29:24Z tlsstores.traefik.io 2025-08-20T06:29:24Z traefikservices.traefik.io 2025-08-20T06:29:24Z
这样就证明 CRDs 安装成功,可以支持 IngressRoute
、TLSOption
、Middleware
等资源
二、Traefik Ingress使用场景
Service 解决“能访问”的问题,Traefik Ingress 解决“怎么优雅地访问”的问题。
如果只是内部测试或简单暴露端口,用 Service 就够了;要上线生产、用域名、做 HTTPS、限流、认证,那就该上 Traefik Ingress 了
Traefik Ingress 是 Kubernetes 的一种 Ingress Controller,它用于处理 L7(HTTP/HTTPS)流量,适合更复杂的流量管理需求。它的典型使用场景包括:
1. 基于域名或路径的高级路由(Layer 7 路由)
- 支持基于
Host
、Path
、Headers
、Query Params
、Method
等条件进行精细化路由。 - 支持正则匹配、SNI(用于 TLS 域名路由)。
- 支持多种路由类型:
- HTTP/HTTPS
- TCP/TLS(如数据库、MQ)
- UDP(如 DNS、VoIP)
traefik.http.routers.api.rule=Host(
api.example.com) && PathPrefix(
/v1)
2. TLS 终止与自动证书管理(HTTPS)
- 内置 ACME 客户端,支持 Let's Encrypt 自动签发和续期证书。
- 支持多种存储方式:
secret
、file
、consul
等保存证书。 - 支持 SNI(Server Name Indication),一个 IP 支持多个 HTTPS 域名。
- 可配置 TLS 版本、加密套件、HSTS 等安全策略。
3. 中间件功能(限流、认证、重写)
-
支持通过 Middleware 实现:
-
请求限流(RateLimit)
-
基本认证(BasicAuth)
-
路径重写(StripPrefix)
-
IP 白名单等
-
Traefik 的一大亮点是 可插拔的中间件机制,可在路由前后添加处理逻辑:
所有中间件可通过 CRD 定义,并在 Ingress 或 IngressRoute 中引用。
RateLimit |
限制每秒请求数(如 100req/s)
|
BasicAuth |
添加用户名密码认证
|
DigestAuth |
摘要认证(更安全)
|
ForwardAuth |
调用外部服务做身份验证(如 OAuth2 Proxy)
|
StripPrefix |
去除路径前缀(如
/api →/ ) |
ReplacePath |
重写路径
|
AddPrefix |
添加路径前缀
|
RedirectRegex /RedirectScheme |
重定向(HTTP→HTTPS,旧路径→新路径)
|
Headers |
修改响应头(CORS、X-Frame-Options 等)
|
IPWhiteList |
IP 白名单/黑名单
|
4. 服务发现与动态配置(零停机热更新)
- 实时监听 Kubernetes API:
Service
、Endpoints
、Pods
、Ingress
、IngressRoute
(Traefik CRD)
- 配置变更时自动重新加载,无需重启 Traefik。
- 支持多种后端:Kubernetes、Docker、Consul、etcd、ZooKeeper 等。
特别适合 DevOps 场景:CI/CD 发布新版本 → Traefik 自动感知并更新路由。
5. 多命名空间、多租户支持
- 单个 Traefik 实例可监听所有命名空间或指定命名空间。
- 支持跨命名空间路由(需权限配置)。
- 可为不同团队提供统一入口网关,实现集中式流量管理。
适用于大型集群中“统一网关”架构。
6. 高可用与负载均衡策略
- 内建负载均衡器,支持:
- 轮询(Round Robin)
- 加权轮询(Weighted Round Robin)
- 最少连接数(Least Connections)
- 支持健康检查(Health Check)自动剔除异常实例。
- 支持会话保持(Sticky Sessions)基于 Cookie。
7. TCP/UDP 支持(南北向非 HTTP 流量)
- 不同于 Nginx Ingress(主要支持 HTTP),Traefik 原生支持:
- TCP 路由(如 MySQL、PostgreSQL、Redis)
- TLS 直通(Passthrough)
- UDP 路由(如 DNS、STUN)
示例:将
db.example.com:3306
转发到内部 MySQL 集群。
8. 自定义 IngressRoute CRD(比标准 Ingress 更强大)
- Kubernetes 原生
Ingress
功能有限,Traefik 提供扩展 CRD:IngressRoute
:支持更复杂的路由规则Middleware
:定义中间件TLSStore
、ServerTransport
等
- 支持灰度发布、金丝雀发布(Canary)、流量镜像等高级功能。
9. 可观测性与运维支持
- 内置 Dashboard(可视化界面):
- 查看所有路由、服务、中间件状态
- 实时监控请求流量
- 多种指标输出:
- Prometheus(默认暴露
/metrics
) - Datadog、StatsD、InfluxDB 等
- Prometheus(默认暴露
- 访问日志(Access Logs):
- 支持结构化日志(JSON)
- 可输出到文件、stdout 或外部系统
10. 边缘安全防护
- 支持 WAF(Web Application Firewall)集成(通过插件或外部服务)
- 请求过滤、防爬虫、防 CC 攻击(结合限流)
- 支持 JWT 验证(通过中间件或 forwardAuth)
11. 灰度发布与金丝雀发布(Canary Release)
- 可通过
IngressRoute
配置按权重分发流量 - 结合 CI/CD 实现渐进式发布
entryPoints: - web routes: - match: Host(`app.example.com`) kind: Rule services: - name: app-v1 weight: 90 - name: app-v2 weight: 10
12. 入口网关高可用部署模式
- 支持部署为
DaemonSet
(每节点一个)或Deployment
(指定副本)。 - 可配合云厂商 LB 或 MetalLB 实现高可用入口。
- 支持
hostNetwork: true
或NodePort
暴露。
13. 建议使用 Traefik 的典型场景
- 微服务架构中需要统一网关
- 多个团队共享集群入口
- 需要自动 HTTPS 和 Let's Encrypt
- 需要灰度发布、限流、认证等高级功能
- 存在非 HTTP 服务(TCP/UDP)需要暴露
三、traefik + https//域名 + ghost
1、背景需求
使用traefik 反代 ghost,https + 域名
最终能实现效果,就是本地证书浏览器不信任
添加永久信任也不好使,暂留问题
curl -k https://blog.internal.com | more % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 18132 0 18132 0 0 86718 0 --:--:-- --:--:-- --:--:-- 86755 <!DOCTYPE html> <html lang="en"> <head> <title>我的博客记录</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="preload" as="style" href="/assets/built/screen.css?v=358e9a28ea"> <link rel="preload" as="script" href="/assets/built/source.js?v=358e9a28ea">
2、环境准备
1、nfs的准备2、https加密证书的准备,存入 secrets 中
3、注意traefik rbac 是否有crds的权限
apiVersion: v1 kind: ServiceAccount metadata: name: traefik namespace: traefik --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: traefik-cr rules: - apiGroups: - "traefik.io" resources: - middlewares - middlewaretcps - tlsoptions - tlsstores - ingressroutes - ingressroutetcps - ingressrouteudps - traefikservices - serverstransports - serverstransporttcps verbs: - get - list - watch - apiGroups: - "" resources: - services - endpoints - secrets - nodes - configmaps verbs: - get - list - watch - apiGroups: - "discovery.k8s.io" resources: - endpointslices verbs: - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: traefik-crb roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: traefik-cr subjects: - kind: ServiceAccount name: traefik namespace: traefik
4、traefik-deploy.yaml
刚开始使用treafik 自动生成加密证书,用pv存在本地
ACME(Automatic Certificate Management Environment)是一种协议,用于自动化地申请、验证、颁发和续期 TLS/SSL 证书
它允许 Traefik 自动为你的服务申请和续期 HTTPS 证书(由 Let's Encrypt 等 ACME 提供商签发),实现真正的“零配置 HTTPS”。
但是这个方案没有测通
使用的 hostNetwork: true, treafik 直接监听主机的端口
# traefik-pv.yaml apiVersion: v1 kind: PersistentVolume metadata: name: traefik-pv spec: capacity: storage: 1Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-path hostPath: path: /opt/traefik/acme nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - node1
pv 在node1上,所以需要配置容忍度
# cat traefik-deploy.yaml apiVersion: apps/v1 kind: Deployment metadata: name: traefik namespace: traefik spec: replicas: 1 selector: matchLabels: app: traefik template: metadata: labels: app: traefik spec: serviceAccountName: traefik hostNetwork: true containers: - name: traefik image: docker.io/library/traefik:v3.5 imagePullPolicy: Never args: - "--api.insecure=true" - "--providers.kubernetescrd" - "--providers.kubernetesingress" - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--entrypoints.web.http.redirections.entrypoint.to=websecure" - "--entrypoints.web.http.redirections.entrypoint.scheme=https" ports: - name: web containerPort: 80 - name: websecure containerPort: 443 - name: admin containerPort: 8080 volumeMounts: - name: acme-storage mountPath: /data volumes: - name: acme-storage persistentVolumeClaim: claimName: traefik-pvc # ✅ 添加:容忍 control-plane 节点的两种 effect tolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoExecute # 保留系统默认容忍(可选,但推荐) - key: node.kubernetes.io/not-ready operator: Exists effect: NoExecute tolerationSeconds: 300 - key: node.kubernetes.io/unreachable operator: Exists effect: NoExecute tolerationSeconds: 300 # ✅ 添加:强制调度到 node1(因为 PV 在那里) affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - node1
5、ghost-ingressroute.yaml
apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ghost-https namespace: ghost spec: entryPoints: - websecure routes: - match: Host(`blog.internal.com`) kind: Rule services: - name: ghost-svc port: 80 tls: secretName: blog-tls-secret
注意:ingressroute需要安装 crds
6、观测效果
能识别路由规则、有 TLS
四 、简单的负载均衡案例
1、先启动三个web服务,使用 service的ClusterIP 模式进行集群内暴露
kind: Deployment apiVersion: extensions/v1beta1 metadata: name: svc1 spec: replicas: 1 template: metadata: labels: app: svc1 spec: containers: - name: svc1 image: cnych/example-web-service env: - name: APP_SVC value: svc1 ports: - containerPort: 8080 protocol: TCP --- kind: Deployment apiVersion: extensions/v1beta1 metadata: name: svc2 spec: replicas: 1 template: metadata: labels: app: svc2 spec: containers: - name: svc2 image: cnych/example-web-service env: - name: APP_SVC value: svc2 ports: - containerPort: 8080 protocol: TCP --- kind: Deployment apiVersion: extensions/v1beta1 metadata: name: svc3 spec: replicas: 1 template: metadata: labels: app: svc3 spec: containers: - name: svc3 image: cnych/example-web-service env: - name: APP_SVC value: svc3 ports: - containerPort: 8080 protocol: TCP --- kind: Service apiVersion: v1 metadata: labels: app: svc1 name: svc1 spec: type: ClusterIP ports: - port: 8080 name: http selector: app: svc1 --- kind: Service apiVersion: v1 metadata: labels: app: svc2 name: svc2 spec: type: ClusterIP ports: - port: 8080 name: http selector: app: svc2 --- kind: Service apiVersion: v1 metadata: labels: app: svc3 name: svc3 spec: type: ClusterIP ports: - port: 8080 name: http selector: app: svc3
此处当apiversion报错可以使用convert转换,如下
将 Kubernetes 资源清单文件从旧版本的 API 转换为新版本的 API。
注意:从 Kubernetes 1.22 开始,kubectl convert
插件已被 移除,不再默认包含在 kubectl
中。你需要手动安装 kubectl-convert
插件(基于 kube-core
工具)。
kubectl convert apply -f we.yaml > we1.yaml
2、查看 svc
% kubectl get service !10043 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE go-web ClusterIP 10.100.174.21 <none> 80/TCP 389d nginx-service NodePort 10.98.169.188 <none> 81:30008/TCP 18d svc-nginx NodePort 10.108.42.76 <none> 8010:31415/TCP 27d svc1 ClusterIP 10.96.242.81 <none> 8080/TCP 111m svc2 ClusterIP 10.97.91.182 <none> 8080/TCP 111m svc3 ClusterIP 10.105.94.123 <none> 8080/TCP 111m
3、发布服务
% cat we2.yaml !10046 apiVersion: extensions/v1beta1 kind: Ingress metadata: name: example-web-app annotations: kubernetes.io/ingress.class: "traefik" spec: rules: - host: moxx.test.com http: paths: - path: /s1 backend: serviceName: svc1 servicePort: 8080 - path: /s2 backend: serviceName: svc2 servicePort: 8080 - path: / backend: serviceName: svc3 servicePort: 8080
注意:- host字段作为访问使用的域名需要提前做好dns解析
可以在本地或者dns上配置
本地配置:
在 /etc/hosts 加入ip和域名的对应关系(k8s节点和访问的客户端主机都需要配置)
dns上配置
如果在k8s上使用的是coredns,实际上就是通过configmap进行配置监听的,可以看到在kube-system命名空间下有一个名称为coredns的configmap
此处使用的也是读取本地的dns解析文件里的dns服务器
4、验证