RUNBOOK — Traefik 入口代理¶
服务:Traefik Proxy v3.7.13(Helm chart
traefik-41.6.0,releasetraefik,命名空间server) 角色:集群内唯一的 HTTP/HTTPS/TCP 入口代理,所有外部流量经它进入 部署档案见 SOP.md;命名空间总览见 ns_migration/RUNBOOK.md 最近更新:2026-09-19
目录¶
1. 服务概览¶
Traefik 以单副本 Deployment 运行在 k8s-master-01,直接占用该节点的宿主机端口对外提供服务。
| 项 | 值 |
|---|---|
| 工作负载 | deploy/traefik,1 副本,nodeSelector: kubernetes.io/hostname=k8s-master-01 |
| 入口节点 | k8s-master-01(192.168.31.10) |
| 资源 | requests 100m / 128Mi,limits 1 核 / 512Mi |
| Service | server/traefik(ClusterIP,供内部引用;对外不依赖它) |
| 路由来源 | kubernetescrd + kubernetesingress 两个 provider,均开启 allowEmptyServices |
| IngressClass | traefik (default) |
端口映射(宿主机端口由 CNI portmap 以 iptables DNAT 实现,因此 ss 不显示监听属正常):
| entrypoint | 容器端口 | 宿主机端口 | 用途 |
|---|---|---|---|
web |
8000 | 80 | HTTP |
websecure |
8443 | 443 | HTTPS(http.tls=true) |
ldap |
1389 | 389 | OpenLDAP 明文(TCP) |
ldaps |
1636 | 636 | OpenLDAP TLS(TCP) |
mariadb |
3306 | 3306 | MariaDB(TCP) |
metrics |
9100 | — | Prometheus 指标 |
traefik |
8080 | — | Dashboard / API(经 443 反代访问) |
业务影响:Traefik 不可用 = 全部外部入口中断(Web、GitLab 除外——GitLab 走 Envoy Gateway,但 LDAP/MariaDB 的 TCP 入口会中断)。
2. 接入与凭据¶
| 入口 | 地址 | 凭据 |
|---|---|---|
| Dashboard | https://traefik.rainchen.top/dashboard/ |
BasicAuth,用户 admin |
| Traefik API | 集群内 http://traefik.server.svc:8080/api/rawdata |
无认证(仅集群内可达) |
取用凭据(勿写入任何文档):
cat traefik_deploy/secrets/dashboard-basic-auth.txt # 权限 600,内含明文口令
取用证书位置:
ls -l traefik_deploy/certs/ # ca.crt / ca.key / tls.crt / tls.key(私钥权限 600)
客户端若要避免浏览器告警,需导入内部 CA:traefik_deploy/certs/ca.crt。
3. 日常速查表¶
# 1) 服务是否在跑、在哪个节点
kubectl -n server get pods -l app.kubernetes.io/name=traefik -o wide # 预期 1/1 Running,NODE=k8s-master-01
# 2) 入口是否活着(404=正常,表示已接管且无匹配路由)
curl -s -o /dev/null -w '%{http_code}\n' http://192.168.31.10/ # 预期 404
# 3) 各域名连通性
for h in traefik.rainchen.top ldapadmin.rainchen.top; do
printf '%-24s ' "$h"
curl -sk -o /dev/null -w '%{http_code}\n' --resolve "$h:443:192.168.31.10" "https://$h/"
done
# 预期:traefik 401(需认证)、ldapadmin 200/302
# 4) TCP 入口连通性(389/636/3306)
for p in 389 636 3306; do
timeout 5 bash -c "cat < /dev/null > /dev/tcp/192.168.31.10/$p" 2>/dev/null \
&& echo "$p 可连接" || echo "$p 不可连接"
done
# 5) 当前加载了多少路由(热加载,改路由无需重启)
kubectl -n server exec deploy/traefik -- traefik version
curl -s http://192.168.31.10:8080/api/rawdata 2>/dev/null | head -c 200 # 集群内执行
# 6) 日志(近 100 行,看有无 ERROR)
kubectl -n server logs deploy/traefik --tail=100 | grep -iE 'error|panic' || echo "无错误"
# 7) 证书有效期
echo | timeout 10 openssl s_client -connect 192.168.31.10:443 -servername traefik.rainchen.top 2>/dev/null \
| openssl x509 -noout -subject -enddate
4. 日常操作¶
# 查看所有路由资源(全集群)
kubectl get ingressroute,ingressroutetcp,middleware -A
# 查看某个路由的详情(例:phpldapadmin)
kubectl -n server get ingressroute phpldapadmin-web -o yaml
# 【高危】重启 Traefik —— 单副本 + hostPort,重启期间全部入口中断约 5–15 秒
kubectl -n server rollout restart deploy/traefik
kubectl -n server rollout status deploy/traefik --timeout=120s # 预期 successfully rolled out
# 删掉某个路由(热加载,不影响入口本身)
kubectl -n server delete ingressroute <名称>
# 进容器排查(容器内无常见网络工具,用于看配置与进程)
kubectl -n server exec -it deploy/traefik -- sh
5. 配置管理¶
唯一的配置文件是 traefik_deploy/values.yaml(约 90 行,含大量注释说明"为什么这样设")。
| 想改什么 | 改哪里 | 生效方式 |
|---|---|---|
| 新增一个 HTTP 端口 | values.yaml 的 ports: 下加一段 |
helm upgrade → Pod 重建 |
| 新增一个 TCP 端口 | 同上,但不要写 http: 段 |
同上 |
| 升级 Traefik 版本 | image.tag(chart 的 appVersion 才是权威) |
同上 |
| 换调度节点 | nodeSelector + tolerations |
同上 |
| 加日志级别 | logs.general.level |
同上 |
| 改路由规则 | IngressRoute CRD(不在 values 里) |
kubectl apply,热加载,无需重启 |
标准变更流程(详细版见 SOP.md 第 5 章):
BASE="/home/rain/Documents/k8s_ins/traefik_deploy"
# 1) 改 values.yaml
# 2) 本地渲染并与现网比对(预期只出现你打算改的部分)
helm template traefik "$BASE/chart/traefik-41.6.0.tgz" -n server -f "$BASE/values.yaml" > /tmp/after.yaml
helm get manifest traefik -n server > /tmp/before.yaml
diff /tmp/before.yaml /tmp/after.yaml
# 3) 应用
helm upgrade traefik "$BASE/chart/traefik-41.6.0.tgz" -n server -f "$BASE/values.yaml" \
--skip-crds --wait --timeout 4m
# 4) 验证(见第 3 章速查表第 1、2 条)
易错点(本环境实测):
updateStrategy必须保持maxUnavailable: 1 / maxSurge: 0。若改回默认的maxUnavailable: 0,新 Pod 会因抢不到宿主机 80/443 而永久 Pending,升级必然超时。service.spec.type必须是ClusterIP;集群无 LoadBalancer 实现,改成LoadBalancer会一直 Pending。- 升级大版本时需手工同步 CRD(
--skip-crds意味着 CRD 不由 Helm 管理)。 - 连接用
--connect-timeout,排查时不要用会挂起的裸curl。
6. 备份与恢复¶
| 备份物 | 位置 | 说明 |
|---|---|---|
| 配置 | traefik_deploy/values.yaml |
唯一的常改文件,纳入版本管理 |
| 证书与私钥 | traefik_deploy/certs/ |
CA 与服务端证书(有效期至 2036-09-13) |
| Dashboard 口令 | traefik_deploy/secrets/dashboard-basic-auth.txt |
权限 600 |
| chart | traefik_deploy/chart/traefik-41.6.0.tgz(另有解包目录) |
离线可复用 |
| 渲染快照 | traefik_deploy/docs/rendered-manifests.yaml |
用于比对历史渲染结果 |
| 变更前备份 | traefik_deploy/backup/ |
台账见 backup/README.md |
恢复步骤:
# 场景:误改 values 导致部署异常,回退到上一个 revision
helm history traefik -n server # 找到目标 revision 号
helm rollback traefik <revision> -n server
kubectl -n server rollout status deploy/traefik --timeout=120s
# 场景:整个 release 丢失,从备份重建
kubectl create namespace server --dry-run=client -o yaml | kubectl apply -f -
for f in traefik_deploy/chart/traefik/crds/traefik.io_*.yaml; do kubectl apply -f "$f"; done
kubectl -n server create secret tls traefik-selfsigned-tls \
--cert=traefik_deploy/certs/tls.crt --key=traefik_deploy/certs/tls.key \
--dry-run=client -o yaml | kubectl apply -f -
helm upgrade --install traefik traefik_deploy/chart/traefik-41.6.0.tgz \
-n server -f traefik_deploy/values.yaml --skip-crds --wait --timeout 5m
恢复后验证:第 3 章速查表第 1、2、7 条全部符合预期。
7. 监控与告警¶
- 指标端点:Traefik 已暴露
metricsentrypoint(容器端口 9100),values 中metrics.prometheus.entryPoint: metrics。 - 当前状态:未接入监控栈。
monitoring命名空间没有针对 Traefik 的 ServiceMonitor,因此在 Prometheus 里查不到 Traefik 指标、也没有相关告警。这是已知缺口(补 ServiceMonitor 属变更,需走变更流程)。 - 替代观测手段(值班兜底):
# 入口可用性(最直接的"是否活着"判断)
curl -s -o /dev/null -w '%{http_code}\n' http://192.168.31.10/ # 期望 404;连接失败即入口中断
# 容器资源使用
kubectl -n server top pod -l app.kubernetes.io/name=traefik
# 错误日志
kubectl -n server logs deploy/traefik --since=30m | grep -iE 'error|panic'
- 需要重点盯的:入口连通性(任何非预期状态都要立即处理)、Pod 重启次数(
kubectl -n server get pods -l app.kubernetes.io/name=traefik,RESTARTS 增长说明反复崩溃)。
8. 故障处置¶
场景 1:所有域名同时不通(入口整体中断)¶
症状:所有 HTTP/HTTPS 域名无法访问;curl http://192.168.31.10/ 连接失败(非 404)。
诊断
# 1) Pod 是否在运行
kubectl -n server get pods -l app.kubernetes.io/name=traefik -o wide # 预期 1/1 Running,NODE=k8s-master-01
# 2) 若不在 Running,看原因
kubectl -n server describe pod -l app.kubernetes.io/name=traefik | grep -A6 Events
# 3) 节点是否健康
kubectl get node k8s-master-01 # 预期 Ready
处置:
- Pod
Pending且事件含didn't have free ports→ 同节点已有其他 Pod 占用 80/443,检查是否有 Traefik 的旧 Pod 未释放或误改副本数;确认replicas为 1。 - Pod
CrashLoopBackOff→ 看kubectl -n server logs deploy/traefik --previous --tail=50,多为 values 改错(如端口冲突、证书 Secret 缺失)。 - 节点
NotReady→ 转节点故障流程;此时入口无法自动切换(单副本 + 固定节点),需人工干预。
验证:curl -s -o /dev/null -w '%{http_code}\n' http://192.168.31.10/ 返回 404。
场景 2:某个域名返回 404(其余正常)¶
症状:单个域名 404,其他域名正常。说明 Traefik 活着,但该域名的路由缺失或匹配失败。
诊断
# 1) 路由资源是否存在
kubectl get ingressroute,ingressroutetcp -A | grep <域名关键字>
# 2) 路由的 Host 规则是否与访问域名完全一致(大小写、拼写)
kubectl -n server get ingressroute <名称> -o jsonpath='{.spec.routes[*].match}{"\n"}'
# 3) 后端服务是否存在且端点非空
kubectl -n server get endpoints <后端服务名> # 预期有 IP:端口
处置:路由缺失 → 重新 kubectl apply 对应 IngressRoute(清单在各交付目录,如 ldap-deploy/manifests/);其中若含跨命名空间引用且报错,需确认 allowCrossNamespace 配置。
验证:重跑 curl --resolve <域名>:443:192.168.31.10 https://<域名>/ 返回非 404。
场景 3:域名返回 502/503(后端不可达)¶
症状:入口可达但报 502/503。
诊断
kubectl -n server get pods | grep <后端组件> # 后端 Pod 是否 Ready
kubectl -n server get endpoints <后端服务> # 端点是否为空
kubectl -n server logs deploy/traefik --tail=50 | grep -i '502\|503\|no available' # Traefik 侧线索
处置:后端未就绪 → 转该服务的 RUNBOOK(GitLab → gitlab-deploy-v2/RUNBOOK.md;LDAP → ldap-deploy/RUNBOOK.md);端点为空但 Pod Ready → 检查 Service 的 selector 与 Pod 标签是否匹配。
验证:域名返回 200/302/401(非 5xx)。
场景 4:TCP 入口不通(389 / 636 / 3306)¶
症状:LDAP 客户端报 Can't contact LDAP server;MariaDB 客户端连不上 3306。
诊断
# 1) 宿主端口是否被 Traefik 接管(从能访问 .10 的机器执行)
for p in 389 636 3306; do timeout 5 bash -c "cat < /dev/null > /dev/tcp/192.168.31.10/$p" 2>/dev/null \
&& echo "$p 通" || echo "$p 不通"; done
# 2) TCP 路由是否存在
kubectl -n server get ingressroutetcp
# 3) 后端 LDAP / MariaDB 是否就绪
kubectl -n server get pods | grep -E 'openldap|mariadb'
kubectl -n server get endpoints openldap mariadb
处置:端口不通 → 看 Traefik Pod 是否运行、entrypoint 是否在启动参数里(kubectl -n server get deploy traefik -o jsonpath='{.spec.template.spec.containers[0].args}' | tr ',' '\n' | grep entryPoints);路由缺失 → 重新 apply IngressRouteTCP;后端未就绪 → 转对应服务 RUNBOOK。
验证:端口连通性检查全部返回"通",并在客户端实际发起一次连接(LDAP 用 ldapwhoami、MariaDB 用 mysql -h ... -u ... -p)。
场景 5:升级时长时间卡住后报超时¶
症状:helm upgrade --wait 超时,报 context deadline exceeded;新 Pod 一直 Pending。
诊断
kubectl -n server get pods -l app.kubernetes.io/name=traefik # 新旧 Pod 是否并存
kubectl -n server get events --sort-by=.lastTimestamp | grep -i 'free ports\|FailedScheduling' | tail -5
kubectl -n server get deploy traefik -o jsonpath='{.spec.strategy}{"\n"}'
处置:若事件为 didn't have free ports for the requested pod ports,说明滚动策略被改成了"先起新再停旧"。应确认 values.yaml 中仍为:
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # 先停旧,再起新
maxSurge: 0
若 release 卡在 pending-upgrade(中断命令导致),清理方式:
helm history traefik -n server # 找到 pending 的 revision 号(设为 N)
kubectl -n server delete secret sh.helm.release.v1.traefik.vN
helm list -n server -a # 确认状态后重新执行 upgrade
验证:helm history traefik -n server 最新 revision 为 deployed,Pod 1/1 Running。
9. 安全与权限¶
- 认证:Dashboard 由
server/middleware/dashboard-auth(BasicAuth)保护;未认证访问返回 401。 - TLS:内部 CA 自签,默认证书为
server/secret/traefik-selfsigned-tls(CN=traefik.rainchen.top,含 SAN,有效期至 2036-09-13)。轮换步骤:
# 1) 重新签发(或替换证书文件)后更新 Secret
kubectl -n server create secret tls traefik-selfsigned-tls \
--cert=traefik_deploy/certs/tls.crt --key=traefik_deploy/certs/tls.key \
--dry-run=client -o yaml | kubectl apply -f -
# 2) 让 Traefik 重新加载证书
kubectl -n server rollout restart deploy/traefik # 【高危】会短暂中断入口
# 3) 验证
echo | openssl s_client -connect 192.168.31.10:443 -servername traefik.rainchen.top 2>/dev/null | openssl x509 -noout -enddate
- RBAC:Traefik 使用 chart 创建的 ServiceAccount,需要集群级只读权限(读取
IngressRoute/Ingress/Endpoints/Secret等)以发现路由。 - 安全项(已在 values 中启用,勿关闭):
safeNaming: true(路由名带命名空间前缀,防跨命名空间重名)、aliasHeadersStrategy: delete(丢弃别名头,防伪造)、strictTLSOptions: true。 - 跨命名空间引用:默认禁止;确需开启时在 values 中设
providers.kubernetesCRD.allowCrossNamespace: true(属变更,需评估影响面)。
10. 容量与性能¶
| 项 | 当前值 |
|---|---|
| requests / limits | 100m / 128Mi → 1 核 / 512Mi |
| 实测使用 | 约 15% 节点 CPU 水位下运行平稳(单副本负责全部入口流量) |
| 路由规模 | HTTP 路由 5 条(gitlab、phpldapadmin、traefik-dashboard、grafana、prometheus)+ TCP 路由 3 条(openldap×2、mariadb) |
扩容触发条件:CPU 持续 > 60% 或内存接近 512Mi 上限时,先提 resources.limits,再考虑横向方案(当前单副本绑定单节点,横向需改 DaemonSet + hostNetwork,属架构变更)。
已知瓶颈:单副本 + 固定节点,节点宕机即入口中断,无自动切换。
11. 附录¶
术语表¶
| 术语 | 含义 |
|---|---|
| entrypoint | 监听端口定义,本文档第 1 章表格列出全部 |
| provider | 路由来源(本环境同时启用 CRD 与 Ingress 两种) |
| Middleware | 请求处理链(本环境用于 Dashboard BasicAuth) |
| hostPort | Pod 直接占用宿主机端口,由 CNI portmap 实现 |
相关文档¶
| 文档 | 位置 |
|---|---|
| 部署变更档案(含排障与回滚) | traefik_deploy/SOP.md |
| Helm 使用手册(改端口/升版本/改 ns) | traefik_deploy/docs/Helm使用手册-Traefik.md |
| 命名空间总览与跨服务排障 | ns_migration/RUNBOOK.md |
| 变更前备份台账 | traefik_deploy/backup/README.md |
修订记录¶
| 日期 | 修改人 | 变更内容 |
|---|---|---|
| 2026-09-19 | 运维 | 首版:Traefik v3.7.13(server 命名空间,含 ldap/ldaps/mariadb TCP 入口) |
来源:
/home/rain/Documents/k8s_ins/traefik_deploy/RUNBOOK.md| 最后更新:2026-09-19 16:51(由build/sync.py同步,请勿在站点侧修改)