cilium / cilium-cli / hubble —— eBPF CNI 排错
一句话定义
cilium 是基于 eBPF 的现代 K8s CNI(容器网络),用 eBPF 程序替代 iptables 实现 service / network policy / load balance,性能和可观测性都比传统 CNI(Flannel / Calico iptables 模式)强很多。它有两组 CLI:cilium(cilium-cli)——管装机、健康检查、连接测试;hubble——看实时流量。
典型场景
- 装 cilium:
cilium install - 看 CNI 健康:
cilium status - 跑连通性测试:
cilium connectivity test - 实时看 pod 间流量:
hubble observe -f - 排查 NetworkPolicy 拦截:
hubble observe --verdict DROPPED
训练营 Day1+ 重度使用 cilium。这篇聚焦 CLI 排错入口。
装
cilium-cli (主管理 CLI)
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
curl -L --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-amd64.tar.gz
tar xzf cilium-linux-amd64.tar.gz -C /usr/local/bin
hubble CLI(流量观测)
HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/master/stable.txt)
curl -L --remote-name-all https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-amd64.tar.gz
tar xzf hubble-linux-amd64.tar.gz -C /usr/local/bin
装 cilium 到集群
cilium install
# 自动检测集群 / kube-proxy / IPv4-v6 / pod CIDR
# 装 cilium DaemonSet、operator、Hubble(可选)
cilium install --version 1.15.0 \
--set kubeProxyReplacement=true \ # 替代 kube-proxy(IPVS / iptables 不用)
--set ipam.mode=kubernetes \ # 用 K8s 默认 IPAM
--set hubble.enabled=true \ # 启用 Hubble
--set hubble.relay.enabled=true \
--set hubble.ui.enabled=true # 启用 Hubble UI
或者用 helm:
helm install cilium cilium/cilium \
-n kube-system \
--version 1.15.0 \
-f cilium-values.yaml
cilium status —— 最常用一条
$ cilium status
/¯¯\
/¯¯\__/¯¯\ Cilium: OK
\__/¯¯\__/ Operator: OK
/¯¯\__/¯¯\ Envoy DaemonSet: disabled (using embedded mode)
\__/¯¯\__/ Hubble Relay: OK
\__/ ClusterMesh: disabled
Deployment cilium-operator Desired: 1, Ready: 1/1
DaemonSet cilium Desired: 5, Ready: 5/5
DaemonSet hubble-relay Desired: 1, Ready: 1/1
Containers: cilium Running: 5
cilium-operator Running: 1
Cluster Pods: 50/50 managed by Cilium
Helm chart version: 1.15.0
最关键:
- Cilium / Operator —— OK / Error
- DaemonSet ready —— 5/5 = 5 个节点都有 cilium agent 跑
- Cluster Pods managed —— pod 数量被 cilium 管
任何 NotReady → 看具体的 pod 日志。
cilium status --wait # 等所有就绪
kubectl -n kube-system logs ds/cilium # 看 agent 日志
cilium connectivity test —— 端到端连通性测试
cilium connectivity test
# 自动创建测试 pod、跑几十个测试用例(pod 间、service、跨节点、ingress、egress、DNS ...)
# 输出每个 case 通过 / 失败
输出:
[=] Test [no-policies]
.....................
[=] Test [allow-all]
....
[=] Test [client-egress-knp]
....
📋 Test Report
✅ 50 tests successful
❌ 0 tests failed
任何 ❌ —— 详细看日志。
--test '<name>' 只跑某项:
cilium connectivity test --test "client-egress-knp"
装完 cilium 必跑
cilium connectivity test——验证基础网络通。Day1 的标准动作。
hubble —— 实时流量观测(Cilium 的杀手锏)
Hubble 是 cilium 的"网络可视化"组件——所有 pod 间流量、L7 解析都能看。
Port-forward
cilium hubble port-forward & # hubble relay 默认 4245
# 或
kubectl port-forward -n kube-system svc/hubble-relay 4245:80
实时看流量
hubble observe -f # follow,类似 tail -f
hubble observe -f --pod my-app/my-pod # 只看某 pod
hubble observe -f --namespace my-ns # 按 ns
hubble observe --since 5m # 过去 5 分钟
hubble observe --last 100 # 最近 100 条
输出(每行一个流量事件):
Apr 27 14:30:00.123 default/nginx-abc:80 -> default/curl-xyz:8080 http-request FORWARDED GET /index.html HTTP/1.1
Apr 27 14:30:00.234 default/curl-xyz:43210 -> google.com:443 http-request FORWARDED CONNECT
Apr 27 14:30:00.345 default/curl-xyz:43211 -> kube-system/kube-dns:53 dns-query FORWARDED google.com.
看 DROPPED 流量(NetworkPolicy 排错杀手锏)
hubble observe --verdict DROPPED # 只看被拦截的
# default/bad-actor:43210 -> default/my-app:80 Policy denied DROPPED
NetworkPolicy 配错导致 pod 不通 → hubble observe --verdict DROPPED 立刻看到。
L7(HTTP / gRPC / DNS)流量
cilium 装了 L7 visibility 后 hubble 显示协议层:
hubble observe --protocol http
hubble observe --protocol dns
hubble observe --protocol grpc
... -> my-app:80 http-request FORWARDED GET /api/users
... http-response FORWARDED 200 6ms
cilium monitor —— 节点级 datapath 追踪
# 在节点上的 cilium agent pod 里跑
kubectl exec -n kube-system cilium-xxx -- cilium monitor
# 或简化
cilium monitor # cilium-cli 帮你 exec
cilium monitor --type drop # 只看丢包
cilium monitor --to-namespace default # 流向 default ns
输出比 hubble 更底层——直接是 eBPF datapath 事件。
xx drop (Policy denied) flow 0x... to endpoint 1234, identity 5678->9012: 10.0.0.5:43210 -> 10.0.0.10:80 tcp SYN
看 endpoint / identity
cilium 用 identity(label hash)替代 IP 做策略。
# 列所有 endpoint
kubectl exec -n kube-system cilium-xxx -- cilium endpoint list
# ENDPOINT POLICY (ingress) POLICY (egress) IDENTITY IPv4
# 1234 Disabled Disabled 5678 10.0.0.5
# ...
# 看单个
kubectl exec -n kube-system cilium-xxx -- cilium endpoint get 1234
# identity 列表
kubectl exec -n kube-system cilium-xxx -- cilium identity list | head
NetworkPolicy 调试
# 看 cilium 实际生效的 policy
kubectl exec -n kube-system cilium-xxx -- cilium policy get
# 用 hubble 看具体哪个 policy 拦了
hubble observe --verdict DROPPED --pod my-app/my-pod
# Policy denied (L3) by ingress-policy-xxx
注意 cilium 支持 CiliumNetworkPolicy(CRD,比标准 K8s NetworkPolicy 强大):
kubectl get cnp -A
kubectl get ccnp -A # ClusterwideCNP
kubeProxyReplacement(替代 kube-proxy)
cilium 可以完全替代 kube-proxy——iptables 全部不用,eBPF 实现 service:
# 装时启用
cilium install --set kubeProxyReplacement=true
# 装完后可以删 kube-proxy
kubectl delete ds -n kube-system kube-proxy
kubectl delete cm -n kube-system kube-proxy
性能更好、可观测性更强。生产推荐。
验证:
cilium status | grep -i proxy
# KubeProxyReplacement: True
实战场景
1. Day1 装 cilium + 验证
cilium install --version 1.15.0 \
--set kubeProxyReplacement=true \
--set hubble.enabled=true \
--set hubble.relay.enabled=true
cilium status --wait
# 全套连通性测试
cilium connectivity test
2. 排查 "pod 连不通另一个 pod"
# 用 hubble 看
cilium hubble port-forward &
hubble observe --verdict DROPPED -f --pod my-app/source-pod
# 让源 pod 发请求
kubectl exec my-app/source-pod -- curl http://my-app.svc
# hubble 立刻看到 DROPPED 事件 + 原因
# Policy denied (L3)
接着看 policy:
kubectl get cnp -A
kubectl describe cnp <name> -n my-app
3. 升级 cilium
cilium upgrade --version 1.15.1
或 helm:
helm upgrade cilium cilium/cilium -n kube-system --version 1.15.1 -f values.yaml
升完跑 connectivity test 验证。
4. Hubble UI(图形化)
kubectl port-forward -n kube-system svc/hubble-ui 12000:80
# 浏览器打开 http://localhost:12000
实时看 pod / service 间通信关系,比命令行 hubble 更直观。
常见踩坑
坑 1:装 cilium 之前没装 / 不卸 kube-proxy
cilium install --set kubeProxyReplacement=true
# 警告 / 工作但 kube-proxy 也跑着 → iptables 还在生效
kubeProxyReplacement=true 之后手动删 kube-proxy:
kubectl delete ds -n kube-system kube-proxy
kubectl delete cm -n kube-system kube-proxy
并清 iptables(见 iptables.md 坑 4)。
坑 2:cilium connectivity test 一些 case 失败
❌ 2 tests failed
详细看:
kubectl get pods -n cilium-test
kubectl logs <test-pod> -n cilium-test
常见原因:
- 集群没足够节点(某些 case 要 2 节点)
- NodePort 范围 / firewall 挡
- ipsec / wireguard 加密配置不全
坑 3:hubble 端口转发不工作
hubble status
# Healthcheck: unhealthy
可能 hubble-relay pod 没起。
kubectl get pods -n kube-system | grep hubble
kubectl logs -n kube-system deploy/hubble-relay
坑 4:装 cilium 之后 pod 起不来
kubectl get pods -A | grep -v Running
# 各种 CrashLoopBackOff
通常是 cilium agent 没在某个节点 ready,pod 调度上去就起不来(没网络)。
cilium status
kubectl get pods -n kube-system -l k8s-app=cilium -o wide
# 看哪个节点的 cilium 没 Ready
修:cilium pod 自己的日志、节点的 kernel version(cilium 要 ≥ 4.19)。
坑 5:内核版本太老
uname -r
# 4.15.x ← 不支持 cilium 完整功能
cilium 全功能(kubeProxyReplacement、L7 visibility)需要 kernel ≥ 5.4。Ubuntu 22 默认 5.15 OK;CentOS 7 的 3.10 ❌。
排查不通 / 失败时先 uname -r 看内核。
坑 6:网络策略写错把自己锁住
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: deny-all
spec:
endpointSelector: {} # 匹配所有 endpoint
ingress:
- fromEndpoints: [] # 不允许任何来源
集群所有 pod 间通信全断。先 hubble 看 DROPPED,再回滚 policy。
养成习惯:写 policy 用 allow 而不是 deny-all,逐步细化。
坑 7:hubble observe 没看到流量
hubble observe -f
# 一片空白
可能:
- hubble 没启用(
cilium status看Hubble: disabled)→ 重装时加--set hubble.enabled=true - relay 没起
- 流量被 sampling 跳过
坑 8:用 cilium 之后 service DNS 不通
cilium 替代 kube-proxy 后,service 流量被 eBPF 处理。CoreDNS 看着没问题但 pod 解析失败 → 通常是 cilium 的 socketLB 配置:
cilium config view | grep socket-lb
某些应用(特别是 host network 模式)和 socketLB 不兼容。修:禁某个 ns 的 socketLB,或者把应用从 hostNetwork 拿出来。