kube-proxy的iptables模式访问原理疑问及异常排查
关于kube-proxy iptables模式访问原理与异常规则的问题
一、核心疑问:iptables模式下的访问路径
我想确认kube-proxy采用iptables模式时的访问原理:到底是client --> iptables --> pod还是client --> iptables --> kube-proxy --> pod?查阅资料得知是前者,但在Kubernetes v1.25.1集群中实际查看发现不符合预期。
二、集群环境与异常iptables规则
我的集群环境:
- Kubernetes版本:v1.25.1
- kube-proxy的
--mode字段为空 - iptables版本:v1.4.21
执行iptables命令获取的规则如下:
┌──[root@vms100.liruilongs.github.io]-[~] └─$iptables -S -t nat | grep -e "-A KUBE-SVC-TCOU7JCQXEZGVUNU" -A KUBE-SVC-TCOU7JCQXEZGVUNU ! -s 10.244.0.0/16 -d 10.96.0.10/32 -p udp -m comment --comment "kube-system/kube-dns:dns cluster IP" -m udp --dport 53 -j KUBE-MARK-MASQ -A KUBE-SVC-TCOU7JCQXEZGVUNU -m comment --comment "kube-system/kube-dns:dns -> 10.244.239.184:53" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-QZKT3GTHGHPWIPHL -A KUBE-SVC-TCOU7JCQXEZGVUNU -m comment --comment "kube-system/kube-dns:dns -> 10.244.239.185:53" -j KUBE-SEP-JN7UQ4Z24ZZERE5A ┌──[root@vms100.liruilongs.github.io]-[~] └─$ ┌──[root@vms100.liruilongs.github.io]-[~] └─$iptables -S -t nat | grep -e "-A KUBE-SEP-JN7UQ4Z24ZZERE5A" -A KUBE-SEP-JN7UQ4Z24ZZERE5A -s 10.244.239.185/32 -m comment --comment "kube-system/kube-dns:dns" -j KUBE-MARK-MASQ -A KUBE-SEP-JN7UQ4Z24ZZERE5A -p udp -m comment --comment "kube-system/kube-dns:dns" -m udp -j DNAT --to-destination :0 --persistent --to-destination :0 --persistent --to-destination ┌──[root@vms100.liruilongs.github.io]-[~] └─$iptables -S -t nat | grep -e "-A KUBE-SEP-QZKT3GTHGHPWIPHL" -A KUBE-SEP-QZKT3GTHGHPWIPHL -s 10.244.239.184/32 -m comment --comment "kube-system/kube-dns:dns" -j KUBE-MARK-MASQ -A KUBE-SEP-QZKT3GTHGHPWIPHL -p udp -m comment --comment "kube-system/kube-dns:dns" -m udp -j DNAT --to-destination :0 --persistent --to-destination :0 --persistent --to-destination ┌──[root@vms100.liruilongs.github.io]-[~] └─$
可以看到,endpoint对应的链DNAT到:0,这更类似userspace模式的表现;同时iptables的随机负载均衡规则也不符合预期。
正常的iptables模式规则应该类似:
-A KUBE-SEP-2KC5TQ77EILRJT77 -p tcp -m comment --comment "default/test-goweb:80-8090" -m tcp -j DNAT --to-destination 10.244.240.51:8090
而当前实际规则是:
-A KUBE-SEP-QZKT3GTHGHPWIPHL -p udp -m comment --comment "kube-system/kube-dns:dns" -m udp -j DNAT --to-destination :0 --persistent --to-destination :0 --persistent --to-destination
三、问题原因分析与解答
iptables模式的正常访问路径
没错,iptables模式下的访问路径确实是client --> iptables --> pod。因为iptables会直接通过DNAT规则将请求转发到Pod的IP和端口,整个过程不需要kube-proxy进程介入,kube-proxy仅负责维护iptables规则。异常现象的根本原因
你遇到的问题确实是因为旧版iptables导致kube-proxy自动切换到了userspace模式:- Kubernetes v1.25默认kube-proxy模式为iptables,但该模式要求iptables版本支持特定特性(比如
--random-fully、正确处理--persistent参数等),而你的iptables v1.4.21版本过旧,不满足这些要求。 - 当kube-proxy检测到iptables版本不达标时,会自动降级到userspace模式运行。此时iptables规则仅负责将请求转发到kube-proxy监听的端口(即规则中的
:0,实际由kube-proxy进程处理端口映射和转发),然后再由kube-proxy将请求转发到Pod,路径就变成了client --> iptables --> kube-proxy --> pod,这就是你看到异常规则的原因。
- Kubernetes v1.25默认kube-proxy模式为iptables,但该模式要求iptables版本支持特定特性(比如
验证方式
- 查看kube-proxy Pod的日志,会发现类似"falling back to userspace proxy"的降级提示;
- 执行
kubectl describe pod <kube-proxy-pod-name> -n kube-system,查看容器启动参数,确认实际运行模式为userspace。
解决办法
升级节点上的iptables版本到Kubernetes v1.25要求的最低版本(建议升级到1.6.1及以上),之后重启kube-proxy Pod,它会自动切换到iptables模式,并生成正确的DNAT规则(直接指向Pod的IP:Port)。
内容的提问来源于stack exchange,提问作者liruilong
相关产品推荐
相关产品推荐

