Cilium 网络 Runbook:安装、查看、调试
Cilium 是本集群的 CNI。没有 CNI,节点会 NotReady,Pod 即使创建出来也不能跨节点通信,Service/DNS 基本不可用。
1. Cilium 解决什么问题
K8s 只定义“Pod 要有 IP、Service 要能转发”,但不实现网络。CNI 插件负责实现:
- 给 Pod 分配 IP。
- 让不同节点的 Pod 互通。
- 实现 NetworkPolicy。
- 配合 kube-proxy 或 eBPF 实现 Service 转发。
- 提供流量可观测,本集群用 Hubble。
为什么选 Cilium:
- eBPF dataplane,Service/Policy 查表效率高。
- Hubble 能看 Pod 间流量、DNS、HTTP verdict。
- 生态成熟,适合从学习走向生产。
2. 安装
前提:
- kubeadm 集群已经 init/join 完成。
- 5 个节点能
kubectl get nodes看到。 - Pod CIDR 是
10.244.0.0/16。
安装 Cilium CLI:
CILIUM_CLI_VERSION=v0.16.24
curl -L --fail --remote-name-all \
https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-amd64.tar.gz
tar xzvf cilium-linux-amd64.tar.gz
mv cilium /usr/local/bin/cilium
安装 Cilium:
helm repo add cilium https://helm.cilium.io
helm repo update
helm install cilium cilium/cilium \
--namespace kube-system \
--version 1.16.5 \
--set ipam.operator.clusterPoolIPv4PodCIDRList='{10.244.0.0/16}' \
--set routingMode=tunnel \
--set tunnelProtocol=vxlan \
--set k8sServiceHost=k8s-api \
--set k8sServicePort=16443 \
--set hubble.enabled=true \
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true
为什么 routingMode=tunnel + vxlan:当前 5 台机器在小厂 IDC,同子网裸 Pod IP 可能被 source-IP filtering 丢掉。VXLAN 外层包源 IP 是节点 IP,更稳。
3. 安装后验收
cilium status --wait
kubectl get pods -n kube-system -l k8s-app=cilium -o wide
kubectl get pods -n kube-system | grep hubble
kubectl get nodes
期望:
DaemonSet cilium Desired: 5, Ready: 5/5。cilium-operatorRunning。hubble-relay、hubble-uiRunning。- 5 个节点从
NotReady恢复到Ready。
4. 测 Pod 到 Pod 网络
kubectl create ns net-test
kubectl run -n net-test a --image=busybox:1.36 --restart=Never \
--command -- sleep 3600
kubectl run -n net-test b --image=busybox:1.36 --restart=Never \
--command -- sleep 3600
kubectl wait -n net-test --for=condition=Ready pod/a pod/b --timeout=120s
kubectl get pod -n net-test -o wide
B_IP=$(kubectl get pod -n net-test b -o jsonpath='{.status.podIP}')
kubectl exec -n net-test a -- ping -c 3 $B_IP
为什么这么测:Service 和 DNS 可能掩盖底层问题。先测 Pod IP 直连,确认 CNI dataplane 工作。
5. 测 Service 和 DNS
kubectl create deploy -n net-test echo --image=hashicorp/http-echo -- -text=ok
kubectl expose deploy -n net-test echo --port=5678 --target-port=5678
kubectl run -n net-test curl --image=curlimages/curl:8.10.1 --restart=Never \
--command -- sleep 3600
kubectl wait -n net-test --for=condition=Ready pod/curl --timeout=120s
kubectl exec -n net-test curl -- curl -sS http://echo:5678
kubectl exec -n net-test curl -- nslookup kubernetes.default.svc
如果 Pod IP 通,但 Service 不通,查:
kubectl get svc,endpoints -n net-test
cilium service list
cilium bpf lb list | head
如果 DNS 不通,查:
kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide
kubectl logs -n kube-system deploy/coredns --tail=100
kubectl get pods -n kube-system -l k8s-app=node-local-dns -o wide
6. Hubble 查看流量
cilium hubble enable --ui
cilium status --wait=false
hubble status
hubble observe --last 20
hubble observe --namespace net-test --last 20
hubble observe --verdict DROPPED --last 50
为什么用 Hubble:kubectl logs 只能看应用日志,tcpdump 只能看包。Hubble 能直接告诉你“哪个 Pod 到哪个 Pod,被哪个策略放行/拒绝”。
7. 常见故障
7.1 节点 NotReady,日志有 NetworkPluginNotReady
kubectl get pods -n kube-system -l k8s-app=cilium -o wide
kubectl logs -n kube-system -l k8s-app=cilium --tail=100
cilium status --wait=false
常见原因:
- Cilium Pod 没调度到所有节点。
- kubeconfig 里的
k8s-api解析失败。 - 节点内核太老或缺 eBPF 支持。
- 上一个 CNI 残留了路由/iptables。
7.2 跨节点 Pod 不通
先确认两个 Pod 是否在不同节点:
kubectl get pod -A -o wide | grep <pod-name>
查 Cilium endpoint:
cilium endpoint list
kubectl exec -n kube-system ds/cilium -- cilium endpoint list
查丢包:
hubble observe --verdict DROPPED --last 100
如果之前装过 Calico,清残留:
ip route | grep bird || true
ip route flush proto bird
rm -f /etc/cni/net.d/*calico* /etc/cni/net.d/calico-kubeconfig
systemctl restart kubelet
7.3 Service 不通
kubectl get svc,endpoints -A | grep <service>
kubectl describe svc -n <ns> <service>
cilium service list | grep <service-ip>
常见原因:
- Service selector 选不到 Pod,Endpoints 为空。
- Pod readiness 没过,不进 Endpoints。
- Cilium agent 状态异常。
8. 回滚和重装
谨慎执行。卸载 CNI 会让节点重新 NotReady:
helm uninstall cilium -n kube-system
for node in 154.201.73.31 154.201.73.81 45.205.31.214 45.205.31.180 45.205.31.10; do
ssh root@$node '
rm -f /etc/cni/net.d/*cilium*
ip link delete cilium_host 2>/dev/null || true
ip link delete cilium_net 2>/dev/null || true
ip link delete cilium_vxlan 2>/dev/null || true
systemctl restart kubelet
'
done
重装后先跑:
cilium status --wait
kubectl get nodes