华为云CCE上Istio服务网格的流量劫持排查:一次Sidecar注入失败的完整复盘
最近在华为云CCE集群上落地Istio服务网格,做微服务的灰度发布和链路追踪。集群是CCE Turbo版(Kubernetes 1.28),Istio用的是1.19。部署完控制面后,给order-service命名空间开启了自动注入,结果Pod起来了,但istio-proxy容器一直CrashLoopBackOff,业务Pod也连不上注册中心。折腾了大半天才定位到根因,记录一下排查过程。
一、 现象:Sidecar注入后启动失败
bash
kubectl get pods -n order-service
# NAME READY STATUS RESTARTS
# order-service-7d8f9c6b5-xxxxx 1/2 CrashLoopBackOff 5
istio-proxy容器日志里反复报:
text
error: failed to start proxy: failed to read iptables rules: exit status 1
业务容器日志则显示无法解析nacos的域名。
二、 排查路径
1. 看注入的Init容器
Istio的流量劫持依赖istio-init容器执行iptables规则。查看Init容器日志:
bash
kubectl logs order-service-7d8f9c6b5-xxxxx -c istio-init -n order-service
报错:iptables: Permission denied。
2. 定位:CCE Turbo的安全组与特权模式
CCE Turbo版集群的节点默认开启了更严格的安全加固(seccomp/AppArmor),且节点的安全组策略限制了容器网络命名空间内的iptables操作。Istio 1.19默认的istio-init需要NET_ADMIN和NET_RAW能力,但CCE Turbo的默认PodSecurityPolicy(或Kyverno策略)限制了这些能力。
3. 验证假设
手动创建一个带NET_ADMIN的测试Pod,执行iptables -L,果然被拒绝。说明问题不在Istio本身,而在集群的安全策略。
三、 解决方案
方案一:为命名空间配置更宽松的Pod安全上下文(推荐)
在order-service命名空间上打标签,允许Istio所需的特权能力:
yaml
apiVersion: v1
kind: Namespace
metadata:
name: order-service
labels:
pod-security.kubernetes.io/enforce: privileged
同时在Istio的values.yaml中确认istio-init的securityContext包含所需能力:
yaml
global:
proxy:
privileged: false
# istio-init 需要的能力
sidecarInjectorWebhook:
injectedAnnotations: {}
实际上更简洁的做法是使用Istio官方提供的istioctl重新生成注入模板,显式保留NET_ADMIN、NET_RAW。
方案二:改用Istio的CNI插件模式(更彻底)
CNI模式不需要每个Pod的istio-init容器,而是由节点上的CNI插件统一处理流量重定向,对安全策略更友好。在CCE上安装Istio时指定:
bash
istioctl install --set components.cni.enabled=true --set components.cni.namespace=kube-system
我们最终选择了方案二,因为运维成本更低,且避免了每个Pod启动时执行iptables的开销。
四、 验证与总结
改造后,order-service的Pod正常2/2 Running,Envoy sidecar成功接管流量,Jaeger里能看到完整的调用链路。灰度发布用Istio的VirtualService按Header切流也跑通了。
几点经验:
CCE Turbo版集群安全加固较严,部署Istio前先确认命名空间的Pod Security级别,别直接套用默认的privileged标签。
istio-init的iptables劫持对节点内核和安全策略敏感,CNI模式是更稳的选择。
排查Sidecar问题,先看istio-init日志,再看istio-proxy日志,最后才怀疑业务配置,顺序别乱。
服务网格在华为云CCE上的落地,技术本身不是最大的坎,集群安全策略的适配才是需要提前规划的地方。希望这篇复盘能帮到正在踩同样坑的兄弟。
- 点赞
- 收藏
- 关注作者
评论(0)