一份由表及里、层层深入的真实网络故障排查实录
本报告将一个真实的 K3s 网络故障排查过程转化为交互式学习体验。一个看似无害的网络策略,在 Calico 的 eBPF 模式下引发了 Vault 集群的连锁性启动失败。您可以按时间线探索每个诊断阶段,揭示从误导性日志到架构性根源的完整过程。
TLS handshake timeout误入歧途:追查 TLS
转折点:定位网络策略
揭示“隐形”流量
制定精确策略
故障初期的所有迹象都指向了 TLS 问题。Pod 日志中充斥着以下错误,这是典型的加密握手失败信号:
> http: TLS handshake error from 127.0.0.1:55066: EOF
> net/http: TLS handshake timeout
基于此,我们进行了大量针对性的 TLS 排查,包括:
1. 验证证书与私钥是否匹配:
# 检查证书公钥的哈希
openssl x509 -noout -modulus -in tls.crt | openssl md5
# 检查私钥中公钥的哈希
openssl rsa -noout -modulus -in tls.key | openssl md5
排查结果: 两个哈希值完全一致,证明密钥对是匹配的。
2. 验证证书链的有效性:
# 使用根证书(ca.crt)验证包含中间证书的服务器证书(tls.crt)
openssl verify -CAfile ca.crt tls.crt
排查结果: 命令失败,返回 error 20 ... unable to get local issuer certificate。这曾让我们以为是 CA 证书链不完整的问题。
阶段结论:方向错误
尽管所有排查都围绕 TLS 进行,但问题依旧。事后证明,这些日志是底层网络连接被切断后,应用层表现出的“症状”,而非“病因”。
在排查陷入僵局时,一个决定性的操作彻底改变了我们的方向:
# 删除应用于 vault 命名空间的所有网络策略
kubectl delete networkpolicy --all -n vault
决定性发现:集群立即恢复正常!
这一现象无可辩驳地证明了,问题的根源 100% 在于网络策略。我们的排查方向因此从应用层配置,彻底转向了网络层隔离策略的分析。
为什么一个看似允许内部通信的策略会导致失败?深入分析后,我们发现它阻塞了两个应用启动和维持健康所必需的、但容易被忽略的“隐形”流量路径。
Kubernetes 的健康检查探针是由运行在 节点(Node) 上的 kubelet 进程发起的,其源 IP 是节点的 IP。而网络策略的入口(Ingress)规则仅配置了 podSelector,它只允许来自其他 Pod 的流量,从而拒绝了来自节点的探针请求。
K3s 为了轻量化,其 API Server 是一个直接运行在 Master 节点 上的进程,而非 Pod。Vault Pod 在启动时,需要连接 API Server 进行服务发现。策略的出口(Egress)规则没有允许流量到 Master 节点的 IP,导致此关键步骤失败,Raft 集群无法建立。
基于对 K3s 架构和“隐形”流量的正确理解,我们制定了最终的、精确的网络策略,为所有必要的通信路径“开窗”。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: vault-final-policy
namespace: vault
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: vault
policyTypes:
- Ingress
- Egress
ingress:
# 规则 A: 允许来自其他 Vault Pod 的内部通信
- from:
- podSelector:
matchLabels:
app.kubernetes.io/name: vault
# 规则 B: 允许来自节点 (Kubelet) 的健康检查
- from:
- ipBlock:
cidr: 10.10.0.0/16 # !! 重要:替换为您节点的 IP 地址范围
egress:
# 规则 A: 允许到其他 Vault Pod 的内部通信
- to:
- podSelector:
matchLabels:
app.kubernetes.io/name: vault
# 规则 B: 允许 DNS 查询
- to:
- podSelector:
matchLabels:
k8s-app: kube-dns
# 规则 C: 允许与 K3s API Server (Master 节点) 通信
- to:
- ipBlock:
cidr: 192.168.1.100/32 # !! 关键:替换为您的 K3s Master 节点的 IP
ports:
- protocol: TCP
port: 6443
结果:问题彻底解决
应用此精确策略后,Vault Pod 能够顺利完成服务发现和 Raft 集群建立,健康检查正常通过,集群稳定运行。