Files
im_server/docs/problems/IM-R11-Traefik入口故障运维排查手册-20261004.md
T

227 lines
8.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# IM R11 Traefik 入口故障运维排查手册
## 1. 目标与已知事实
需要定位 2026-10-04 北京时间 `10:39:30–10:42:30`,即 UTC `02:39:30–02:42:30` 的入口整体中断。
已知现象:
- `api.118im.com/metrics` 先后出现超时、HTTP 521 和 HTTP 503。
- 三个源 IP 的 443 在约 10:40:16 同时 `connection refused`。
- 2000 个 WebSocket 几乎同时断开,A/B 两台压测机均受影响。
- Tinode cluster 采样仍为 2/2 live peers。
- 故障后三个源 IP 返回同一张 `TRAEFIK DEFAULT CERT`,证书 `notBefore` 为 `2026-10-04 10:41:32 +08:00`,与入口恢复窗口重合。
- 运维已确认 `216.236.31.189:6443` 按安全策略不对公网开放,只允许集群网络访问;外部调试机 TCP 超时属于预期行为。
排查过程中不要先重启 Traefik、节点或 k3s,也不要清理容器和日志。先完成只读取证。
## 2. 运维进入方式
优先在控制面节点直接执行 `kubectl`。如果控制面节点没有配置 kubeconfig,k3s 通常可使用:
```bash
sudo k3s kubectl get nodes -o wide
```
普通 Kubernetes 可使用:
```bash
kubectl get nodes -o wide
kubectl cluster-info
```
不建议把 6443 直接向公网完全开放。长期方案应采用 VPN/堡垒机或仅允许固定运维出口 IP。短期也可以让运维直接在控制面节点采集下面的结果。
## 3. 第一优先级:确认 Traefik 是否重启
先找到 Traefik 所在 namespace、工作负载和 Pod:
```bash
kubectl get deploy,ds,sts,pod -A -o wide | grep -i traefik
kubectl get pods -A -l app.kubernetes.io/name=traefik -o wide
kubectl get pods -A -l app=traefik -o wide
```
对每个 Traefik Pod 执行:
```bash
kubectl -n kube-system get pod TRAEFIK_POD -o jsonpath='{.metadata.name}{"\nstarted="}{.status.startTime}{"\nrestarts="}{.status.containerStatuses[*].restartCount}{"\nlastReason="}{.status.containerStatuses[*].lastState.terminated.reason}{"\nlastExit="}{.status.containerStatuses[*].lastState.terminated.exitCode}{"\nlastFinished="}{.status.containerStatuses[*].lastState.terminated.finishedAt}{"\n"}'
kubectl -n kube-system describe pod TRAEFIK_POD
kubectl -n kube-system logs TRAEFIK_POD --all-containers --timestamps --since-time=2026-10-04T02:39:30Z
kubectl -n kube-system logs TRAEFIK_POD --all-containers --previous --timestamps --since-time=2026-10-04T02:39:30Z
```
重点检查:
- `OOMKilled`、exit code 137、liveness/readiness failure。
- `Killing`、`Evicted`、`NodeNotReady`、`Preempted`。
- `Configuration loaded`、provider reconnect、TLS store/default certificate 重建。
- 10:41:32 附近是否有容器启动日志。
如果 Traefik 不在 `kube-system`,将命令中的 namespace 替换为实际值。
## 4. 第二优先级:查滚动发布和配置变更
```bash
kubectl -n kube-system get deploy,ds,rs -l app.kubernetes.io/name=traefik -o wide
kubectl -n kube-system rollout history deploy/traefik
kubectl -n kube-system get deploy traefik -o yaml
kubectl -n kube-system get cm,secret | grep -i traefik
```
若由 Helm 管理:
```bash
helm list -A | grep -i traefik
helm history traefik -n kube-system
helm get values traefik -n kube-system -a
```
若由 ArgoCD 管理:
```bash
kubectl get applications.argoproj.io -A
kubectl get applications.argoproj.io -A -o yaml | grep -n -i -C 5 traefik
kubectl get pods -n argocd -o wide
kubectl logs -n argocd -l app.kubernetes.io/name=argocd-application-controller --all-containers --timestamps --since-time=2026-10-04T02:39:30Z
```
同时检查 CI/CD 平台在北京时间 10:39–10:42 是否执行过 Traefik、Ingress、Service、证书或节点部署。需要记录操作者、commit、同步 revision 和开始/结束时间。
## 5. 第三优先级:节点是否重启或资源耗尽
```bash
kubectl get nodes -o wide
kubectl describe nodes
kubectl get events -A --sort-by=.metadata.creationTimestamp
kubectl get events -A --field-selector type=Warning --sort-by=.metadata.creationTimestamp
```
在承载 Traefik 的节点执行:
```bash
uptime -s
last -x | head -30
sudo journalctl --list-boots
sudo journalctl --since '2026-10-04 10:39:30' --until '2026-10-04 10:42:30' -u k3s -u k3s-agent -u kubelet -u containerd --no-pager
sudo journalctl -k --since '2026-10-04 10:39:30' --until '2026-10-04 10:42:30' --no-pager
sudo dmesg -T | grep -Ei 'oom|killed process|memory cgroup|conntrack|nf_conntrack|link.*down|reset|I/O error'
```
重点判断:
- 节点是否在 10:41 左右重启。
- 内核是否 OOM kill Traefik、containerd 或 k3s。
- 磁盘是否满、只读或发生 I/O error。
- 网卡是否 link down、驱动 reset。
- kubelet 是否因 liveness probe 杀掉 Traefik。
## 6. 第四优先级:Service 与 Endpoint 是否短暂清空
```bash
kubectl get svc,endpoints,endpointslices -A | grep -Ei 'traefik|im-server'
kubectl -n kube-system describe svc traefik
kubectl -n kube-system get endpoints traefik -o yaml
kubectl -n kube-system get endpointslices -l kubernetes.io/service-name=traefik -o yaml
kubectl -n im-server-system get pod,svc,endpoints,endpointslices -o wide
kubectl -n im-server-system describe svc im-server
kubectl -n im-server-system get endpoints im-server -o yaml
kubectl -n im-server-system get endpointslices -l kubernetes.io/service-name=im-server -o yaml
```
检查 10:40–10:41 是否发生:
- Traefik Service 没有可用 endpoint。
- `im-server` 三个 Pod 同时 NotReady,导致上游 503。
- selector、port、targetPort 或 Ingress backend 被 ArgoCD/Helm 临时改写。
- StatefulSet 滚动时 readiness 配置错误,所有 endpoint 被同时摘除。
## 7. 第五优先级:连接数和 conntrack
在入口节点执行:
```bash
sudo ss -lntp | grep -E ':443|:6443'
sudo ss -s
sudo sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max
sudo conntrack -S 2>/dev/null || true
sudo nstat -az | grep -Ei 'ListenDrops|ListenOverflows|RetransSegs|InErrors|OutDiscards'
sudo ip -s link
```
如果有节点监控,导出 10:35–10:45 的:
- CPU usage、load、CPU throttling。
- 内存、OOM、working set。
- conntrack 使用率。
- TCP listen overflow、reset、retransmit。
- 网卡吞吐、drop、error。
- Traefik active connection、open connection、5xx、upstream duration。
conntrack 达到 `nf_conntrack_max` 通常更偏向 timeout/drop;本轮观察到短时间 `connection refused`,因此还应优先确认 443 监听进程是否消失或入口规则是否被重建。
## 8. im-server 同期状态
```bash
kubectl -n im-server-system get pods -o wide
kubectl -n im-server-system get sts im-server -o yaml
kubectl -n im-server-system describe sts im-server
for pod in $(kubectl -n im-server-system get pods -l app=im-server -o name); do
kubectl -n im-server-system logs "$pod" --all-containers --timestamps --since-time=2026-10-04T02:39:30Z > "${pod##*/}.log"
kubectl -n im-server-system logs "$pod" --all-containers --previous --timestamps --since-time=2026-10-04T02:39:30Z > "${pod##*/}.previous.log" 2>&1 || true
done
```
如果 `app=im-server` 标签不匹配,先执行 `kubectl -n im-server-system get pods --show-labels`,再替换 selector。
需要确认三个 im-server Pod 的:
- `startTime` 和 `restartCount`。
- readiness/liveness failure。
- 10:40 左右是否仍持续处理 Kafka、cluster RPC 和 WS。
- 是否有 `too many open files`、OOM、accept error、DNS error、MySQL/Kafka timeout。
## 9. Kubernetes API 访问方式
从当前调试机访问三个源 IP 的 443 均正常。运维已确认 `216.236.31.189:6443` 只允许集群网络访问,因此外部连接超时符合既定安全策略,也与 VPN/TUN 无关。
运维应检查控制面节点:
```bash
sudo ss -lntp | grep 6443
sudo nft list ruleset | grep -n -C 3 6443
sudo iptables -S | grep 6443
sudo iptables -t nat -S | grep 6443
```
后续排查采用以下方式之一:
1. 让排查命令直接在控制面节点运行并回传结果包。
2. 如确需远程调试,为固定运维出口 IP 临时增加 6443 allowlist,完成后撤销。
3. 通过堡垒机/VPN 进入控制面网络。
不要为了调试把 6443 对 `0.0.0.0/0` 永久开放。
## 10. 运维需要回传的结果
至少回传以下内容:
1. Traefik Pod YAML、describe、当前日志和 previous 日志。
2. Traefik Deployment/DaemonSet、ReplicaSet 和 rollout history。
3. 10:39:30–10:42:30 的 k3s/kubelet/containerd/kernel journal。
4. 全集群 Warning Event、节点 describe。
5. Traefik 和 im-server 的 Service、EndpointSlice、Ingress YAML。
6. ArgoCD/Helm/CI 在故障窗口的发布历史。
7. 入口节点 CPU、内存、conntrack、TCP overflow/retransmit 和网卡 drop。
拿到这些材料后,按照以下优先级定责:
1. Traefik 容器或节点在 10:41:32 重启。
2. ArgoCD/Helm/CI 触发 Traefik 滚动或配置重建。
3. Traefik/im-server endpoint 短暂清空。
4. OOM、liveness、conntrack、监听队列或节点网络故障。
5. 其他上游负载均衡或云网络事件。