主题
Traefik(RKE2 内置)HTTP/HTTPS 配置、原理与高并发生产落地手册
- 日期:2026-08-05
- 环境:RKE2 v1.35.6 内置 Traefik(Rancher hardened-traefik v3.7.4,DaemonSet,hostPort 80/443),集群 uat1(192.168.122.31)
- 内容:HTTP/HTTPS 分别如何配置 → 实现原理 → 最佳实践 → 高并发生产落地
1. 认识现状:RKE2 内置 Traefik 长什么样
bash
kubectl -n kube-system get ds rke2-traefik -o jsonpath='{.spec.template.spec.containers[0].args}'本集群实际启动参数(精简):
text
--entryPoints.web.address=:8000/tcp # HTTP 容器 8000 ↔ hostPort 80
--entryPoints.websecure.address=:8443/tcp # HTTPS 容器 8443 ↔ hostPort 443
--entryPoints.traefik.address=:8080/tcp # 管理/ping 入口(不对外)
--entryPoints.metrics.address=:9100/tcp # Prometheus 指标入口
--api.dashboard=true --ping=true --metrics.prometheus=true
--providers.kubernetescrd # 监听 IngressRoute 等 CRD
--providers.kubernetescrd.ingressClass=traefik # 只认 ingress.class=traefik 注解!
--providers.kubernetesingress # 兼容标准 Ingress
--entryPoints.websecure.http.tls=true # websecure 入口强制 TLS要点:
- DaemonSet + hostPort:每个节点 80/443 由本机 Traefik Pod 直接占用,节点 IP 即入口;
- 两种路由资源都能用:标准
Ingress和 Traefik CRDIngressRoute(功能更强,推荐); - CRD 路由必须带注解
kubernetes.io/ingress.class: traefik,否则被忽略(典型踩坑点)。
2. HTTP / HTTPS 分别配置
2.1 纯 HTTP(80)
yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: web-http
namespace: default
annotations:
kubernetes.io/ingress.class: traefik
spec:
entryPoints:
- web # 只挂 80
routes:
- match: Host(`app.ai-ear.cn`)
kind: Rule
services:
- name: web
port: 802.2 HTTPS(443)——证书 Secret + IngressRoute TLS
bash
# ① 准备证书(DigiCert/自签/cert-manager 签发均可)
kubectl -n default create secret tls app-tls --cert=app.crt --key=app.keyyaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: web-https
namespace: default
annotations:
kubernetes.io/ingress.class: traefik
spec:
entryPoints:
- websecure # 只挂 443
tls:
secretName: app-tls # ② 引用证书;多个域名可配多条 route + 多个 secret,按 SNI 自动选证书
routes:
- match: Host(`app.ai-ear.cn`)
kind: Rule
services:
- name: web
port: 80后端 Pod 仍是明文 HTTP(集群内 TLS 终止于 Traefik),这是最常见模式;端到端加密见 5.4。
2.3 HTTP 自动跳转 HTTPS(生产必配)
方式一(推荐):入口级重定向,改 HelmChartConfig 追加参数,所有挂在 web 入口的域名统一跳转:
yaml
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: rke2-traefik
namespace: kube-system
spec:
valuesContent: |-
additionalArguments:
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true" # 301 永久跳转方式二:路由级,用 redirectScheme middleware 针对单个域名跳转:
yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: redirect-https
namespace: default
spec:
redirectScheme:
scheme: https
permanent: true
---
# 在 HTTP IngressRoute 的 route 上引用:
# middlewares:
# - name: redirect-https2.4 收紧 TLS 安全策略(TLSOption)
yaml
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata:
name: default # 固定名 default 即该命名空间的默认 TLS 策略
namespace: default # TLSOption 按命名空间生效,需与引用它的路由同 ns
spec:
minVersion: VersionTLS12 # 禁掉 TLS1.0/1.1;纯内网可上 VersionTLS13
sniStrict: true # SNI 不匹配任何路由证书时直接拒绝
cipherSuites: # 仅 minVersion=TLS1.2 时有效;TLS1.3 套件不可配
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA2562.5 HSTS 与安全响应头
yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: security-headers
namespace: default
spec:
headers:
stsSeconds: 63072000 # HSTS 2 年
stsIncludeSubdomains: true
stsPreload: true
customResponseHeaders:
X-Content-Type-Options: nosniff
X-Frame-Options: DENY3. 实现原理
3.1 静态配置 vs 动态配置
| 内容 | 来源 | 修改方式 | |
|---|---|---|---|
| 静态配置 | entryPoints、providers、api、metrics、log | 启动参数(Helm chart 渲染进 DaemonSet args) | 改 HelmChartConfig/kube-system/rke2-traefik → RKE2 自动重装 chart |
| 动态配置 | Router(路由匹配)、Middleware(加工)、Service(负载均衡)、TLSOption | K8s CRD(IngressRoute/Middleware/...) | kubectl apply,热加载零重启 |
RKE2 用 HelmChart rke2-traefik 管 chart,HelmChartConfig 是官方唯一正确的自定义入口——不要直接改 DaemonSet/HelmChart,会被 RKE2 调谐覆盖。
3.2 一条请求的生命周期
text
Client ──TLS(SNI 选证书)──▶ Node:443(hostPort)──▶ Traefik 容器:8443(websecure entryPoint)
│ │
│ ┌────────────────────────────────────┘
│ ▼
│ Router 匹配:Host(`app.ai-ear.cn`) && PathPrefix(`/api`)
│ (多条命中时按 rule 长度算优先级,长的优先)
│ │
│ ▼
│ Middleware 链:redirectScheme → headers → rateLimit → ...
│ │
│ ▼
│ Service(加权负载均衡,默认轮询)
│ 后端列表来自 EndpointSlice——直接负载到 Pod IP,不经过 kube-proxy/ClusterIP
│ │
└──────────────┴──▶ 后端 Pod:80关键点:
- TLS 终止:证书在 Traefik 侧按 SNI 选择并解密;
tls.secretName只对引用它的路由生效,多证书共存互不影响; - 直连 Pod:kubernetesCRD provider 监听 EndpointSlice,Traefik 直接 RR 到 Pod,少一跳 NAT,且能感知就绪探针——未 Ready 的 Pod 自动摘流;
- ingressClass 过滤:
--providers.kubernetescrd.ingressClass=traefik意味着 IngressRoute/Middleware 的生效范围受kubernetes.io/ingress.class注解控制,多 ingress 控制器共存时互不干扰; - 热加载:CRD 变更秒级生效,不重载进程、不断现有连接。
3.3 为什么 404 不代表故障
Traefik 收到请求但没有任何 Router 命中时返回内置 404 page not found(集群里没有任何 Ingress/IngressRoute 时访问 80/443 就是这个)——说明监听、协议栈都正常,只是没路由。判断层次:ping 8080 通 = 进程活;404 page not found = 无路由;业务 404(带应用特征) = 路由通、后端问题。
4. 最佳实践清单
- 统一用 IngressRoute(CRD),放弃标准 Ingress:tls 选项、middleware、灰度权重(Weighted Round Robin)只有 CRD 能完整表达;
- 所有 CRD 带
kubernetes.io/ingress.class: traefik注解; - 生产强制 HTTPS:入口级 301 跳转 +
minVersion: VersionTLS12+ HSTS; - 证书自动化:上 cert-manager(
kubernetesingressprovider 已开,cert-manager.io/cluster-issuer注解的标准 Ingress 可直接签);手工证书注意 2.2 的 secret 与路由同 namespace; - dashboard 不裸奔:必须 IngressRoute 显式暴露 + basicAuth/forwardAuth,用完即删(参考《uat1 集群 Traefik dashboard 访问》);
- 不要把管理入口(8080/9100)暴露到 web/websecure;metrics 走独立入口只给 Prometheus 抓;
- 变更后验证:
kubectl -n kube-system port-forward <pod> 8080:8080看/api/http/routers确认路由状态enabled。
5. 高并发生产落地
5.1 入口拓扑:两种形态
| 形态 | 适用 | 要点 |
|---|---|---|
| DaemonSet + hostPort(RKE2 默认,本集群现状) | 节点固定、有外部 L4 LB/VIP | 前面挂 F5/HAProxy/keepalived VIP,负载到所有节点 80/443;天然每节点一个实例,无单点 |
| Deployment + Service LB | 云上(ELB/NLB) | 副本数 3+,跨 AZ 反亲和 |
裸金属/内网集群推荐前者:外部 LB 健康检查打 Traefik 的 ping 入口(本集群 --ping=true 在 8080,GET /ping 返回 200),LB 只把流量发给健康节点。
若 LB 是 L4(TCP)且需要真实客户端 IP:LB 侧开 PROXY protocol,Traefik 侧配置信任 LB 网段:
--entrypoints.web.proxyProtocol.trustedIPs=<LB网段>、--entrypoints.websecure.proxyProtocol.trustedIPs=<LB网段>,否则拿到的是 LB 的 IP,影响 rateLimit/日志/审计。
5.2 实例与资源
yaml
# HelmChartConfig valuesContent 片段
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: "2" # 给上限但别卡死:Traefik 是纯网络 IO,突发吃 CPU
memory: 1Gi- 单实例 hardened-traefik 在 2C 下约可扛 2~5 万 RPS(短连接 HTTPS 取下限,长连接/HTTP 取上限),容量规划按 50% 水位留余量;
- Traefik 自动按 GOMAXPROCS 用满分配 CPU,不要给 100m 这种小 requests 让调度器把它挤到忙节点。
5.3 连接与超时调优(高并发核心)
yaml
# HelmChartConfig valuesContent 片段
additionalArguments:
# ── 到后端的连接池(对性能影响最大)──
- "--serversTransport.maxIdleConnsPerHost=500" # 默认 200,后端少时不够,会产生大量 TIME_WAIT
- "--serversTransport.idleConnTimeout=90s"
- "--serversTransport.forwardingTimeouts.dialTimeout=10s"
- "--serversTransport.forwardingTimeouts.responseHeaderTimeout=30s"
- "--serversTransport.forwardingTimeouts.idleConnTimeout=90s"
# ── 面向客户端侧 ──
- "--entrypoints.web.transport.respondingTimeouts.readTimeout=0" # 0=不限;有 SSE/WebSocket/长轮询必须为 0
- "--entrypoints.web.transport.respondingTimeouts.writeTimeout=0"
- "--entrypoints.web.transport.respondingTimeouts.idleTimeout=180s" # 无 SSE 的纯短 API 可收紧到 30s
# ── 优雅退出(滚动更新/节点维护不断流)──
- "--entrypoints.web.transport.lifeCycle.requestAcceptGraceTimeout=10s"
- "--entrypoints.web.transport.lifeCycle.graceTimeOut=60s"配套的节点内核调优(hostPort 模式下调的是节点内核):
bash
# /etc/sysctl.d/99-traefik.conf(所有入口节点)
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.core.netdev_max_backlog = 65535
net.netfilter.nf_conntrack_max = 2097152 # conntrack 打满是高并发常见瓶颈
net.ipv4.ip_local_port_range = 10240 65535 # 到后端 Pod 的源端口池
net.ipv4.tcp_tw_reuse = 1
fs.file-max = 2097152
# 应用:sysctl --system;并确认 Traefik Pod ulimit nofile ≥ 65535(containerd 默认已较高)5.4 端到端加密(可选高安全场景)
默认 Traefik→Pod 是明文。要求全链路加密时,用 ServersTransport 指定后端走 HTTPS + 信任内部 CA:
yaml
apiVersion: traefik.io/v1alpha1
kind: ServersTransport
metadata:
name: mtls-backend
namespace: default
spec:
serverName: app.default.svc
rootCAsSecrets:
- internal-ca
# insecureSkipVerify: true # 应急才用,生产禁止
---
# IngressRoute service 引用:
# services:
# - name: web
# port: 443
# scheme: https
# serversTransport: mtls-backend代价:后端证书管理 + 后端加解密 CPU,内网高并发下一般不做。
5.5 韧性中间件(生产三件套)
本版本(v3.7.4)Middleware CRD 支持:rateLimit / inFlightReq / circuitBreaker / retry / buffering / compress / chain 等。
yaml
# ① 限流:保护后端不被突发打垮
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata: {name: api-ratelimit, namespace: default}
spec:
rateLimit:
average: 200 # 每秒平均 200 请求(按 sourceCriterion 维度,默认按客户端 IP)
burst: 400
period: 1s
---
# ② 并发闸:超过直接 503,比排队拖死强
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata: {name: api-inflight, namespace: default}
spec:
inFlightReq:
amount: 500
sourceCriterion:
requestHost: true
---
# ③ 熔断:后端 5xx 比例超阈值时快速失败
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata: {name: api-breaker, namespace: default}
spec:
circuitBreaker:
expression: ResponseCodeRatio(500, 600, 0, 600) > 0.30
checkPeriod: 5s
fallbackDuration: 15s
recoveryDuration: 30s
---
# ④ 重试:只对幂等 GET 开
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata: {name: api-retry, namespace: default}
spec:
retry:
attempts: 3
initialInterval: 100ms用 chain middleware 组合后挂到路由:
yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata: {name: api-chain, namespace: default}
spec:
chain:
middlewares:
- {name: api-ratelimit}
- {name: api-inflight}
- {name: api-breaker}
- {name: api-retry}
compress(gzip)对文本收益大,但高并发下吃 CPU——只给大响应文本接口开,别全局开。
5.6 灰度发布
IngressRoute 原生支持同一 match 下多 service 加权,做金丝雀:
yaml
routes:
- match: Host(`app.ai-ear.cn`)
kind: Rule
services:
- name: web-v1
port: 80
weight: 90
- name: web-v2
port: 80
weight: 10 # 10% 流量进新版本5.7 可观测性(高并发的眼睛)
- 指标:独立入口 9100 已开,Prometheus 抓
http://<pod-ip>:9100/metrics,核心面板:traefik_entrypoint_requests_total/..._request_duration_seconds(入口 RPS、延迟)traefik_service_requests_total{code=~"5.."}(按后端看 5xx)traefik_entrypoint_open_connections(在途连接,配合内核参数看水位)
- 访问日志:高并发下关闭或采样,全量 JSON 访问日志会成为磁盘/CPU 瓶颈;排障时临时开:
--accesslog=true --accesslog.format=json --accesslog.filters.statuscodes=400-599(只记错误) - 告警:5xx 比例、P99 延迟、open_connections 接近上限、Pod CPU 超限。
5.8 滚动更新不断流
- 上节
lifeCycle.graceTimeOut=60s:收到 SIGTERM 后停止接新连接,等存量请求完成; - 外部 LB 健康检查(8080/ping)配合:Traefik 退出期 ping 先失败,LB 提前摘流;
- 维护单节点时先
kubectl cordon/drain或直接在 LB 上摘节点,再重启 Pod。
5.9 落地配置汇总(HelmChartConfig 完整示例)
yaml
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: rke2-traefik
namespace: kube-system
spec:
valuesContent: |-
additionalArguments:
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
- "--serversTransport.maxIdleConnsPerHost=500"
- "--serversTransport.forwardingTimeouts.dialTimeout=10s"
- "--serversTransport.forwardingTimeouts.responseHeaderTimeout=30s"
- "--entrypoints.web.transport.respondingTimeouts.idleTimeout=180s"
- "--entrypoints.websecure.transport.respondingTimeouts.idleTimeout=180s"
- "--entrypoints.web.transport.lifeCycle.graceTimeOut=60s"
- "--entrypoints.websecure.transport.lifeCycle.graceTimeOut=60s"
resources:
requests: {cpu: 500m, memory: 512Mi}
limits: {cpu: "2", memory: 1Gi}注意:Rancher 纳管集群里该 HelmChartConfig 由 Rancher 创建(含
global.cattle.clusterId),在其valuesContent上合并追加即可,勿整段覆盖;改完 RKE2 的 helm-controller 会自动重渲染并滚动重建 Traefik Pod,用kubectl -n kube-system rollout status ds/rke2-traefik观察。
6. 验证与排障速查
bash
# 路由是否生效
kubectl -n kube-system port-forward <traefik-pod> 18080:8080
curl -s localhost:18080/api/http/routers | jq '.[] | {name, rule, status, service}'
# HTTPS 跳转/证书
curl -sI http://app.ai-ear.cn/ --resolve app.ai-ear.cn:80:192.168.122.31 # 301 → https
echo | openssl s_client -connect 192.168.122.31:443 -servername app.ai-ear.cn 2>/dev/null | openssl x509 -noout -subject -dates
# 压测(观察 5.7 指标)
# 关键水位:open_connections、5xx、P99、Pod CPU、节点 conntrack 用量
conntrack -C7. 总结
- HTTP/HTTPS 分离 = 路由分别挂
web/websecure入口,HTTPS 加tls.secretName,跳转用入口级 redirection 或redirectSchememiddleware; - 原理一句话:静态配置定入口,CRD 动态定路由,Traefik 按 SNI 终止 TLS、按 EndpointSlice 直连 Pod 做负载,热加载不断流;
- 高并发三板斧:连接池与超时调优 + 节点内核参数 + 限流/熔断/重试韧性中间件,辅以独立 metrics 入口做容量观测;
- RKE2 里一切定制走
HelmChartConfig,别手改 DaemonSet。