k8s hosPort 网络模式不生效
本文主要介绍了在 k8s 中,采用 flannel 部署网络后,当 pod 中容器的网络模式为 hostPort
时,其结果并未生效的问题,并就该问题进行了分析解决。
介绍
首先,hostPort 是直接将容器的端口与所调度的 k8s 工作节点的端口路由,这样用户就可以通过对应工作节点的 ip 加端口来访问应用了。如:
apiVersion: v1
kind: Pod
metadata:
name: whoami
spec:
containers:
- name: whami
image: whoami
ports:
- containerPort: 8080
hostPort: 8080
问题定位
当我们将 hostPort
网络模式的应用通过 kubectl
命令放入到 k8s 中后,若在工作节点上采用对应端口( 如 8080 ) 访问时发现应用服务未跑起来,这时我们可以先看一下自己的 CNI 网络插件 portmap( 见 官网 ) 是否正常,通过 journalctl -fu kubelet
命令返回的日志可以进行查看,如果 CNI 网络插件未安装,我们看下自己当时的的 flannel.yaml 文件中是否设置了 portMappings capability 属性的值为 true,如下:
{
"name": "k8s-pod-network",
"cniVersion": "0.3.0",
"plugins": [
{
"type": "calico",
"log_level": "info",
"datastore_type": "kubernetes",
"nodename": "127.0.0.1",
"ipam": {
"type": "host-local",
"subnet": "usePodCidr"
},
"policy": {
"type": "k8s"
},
"kubernetes": {
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
}
},
{
"type": "portmap",
"capabilities": {"portMappings": true}
}
]
}
如果本来是 true,在 apply flannel.yaml 文件后还是没有 CNI 插件,则可以根据上述日志中的路径从其他 k8s 节点上复制一份。
当网络插件正常后,若还是无法访问应用,则可以在应用被调度的工作节点上执行如下命令,查看 iptables 中的 nat 表中生成的 CNI-HOSTPORT-DNAT
:
# iptables -nvL CNI-HOSTPORT-DNAT -t nat
Chain CNI-HOSTPORT-DNAT (2 references)
pkts bytes target prot opt in out source destination
4 240 CNI-DN-550b4bf3691bef6919331 tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* dnat name: "podman" id: "aea317babc7f3ec7607b242227b39c90a43b50a7dd0f0b8fbccc82620370831d" */ multiport dports 8080
假如当前 k8s 中只部署了一个 hostPort 模式的应用,则通过以上命令只会看到一个类似 CNI-DN-550b4bf3691bef6919331
的数据,若是有多个,则就说明有问题,应用未能正确访问的原因就是生成的 CNI 网络被占用了(笔者这里就是因为出现了两个,所以导致自己的应用无法正常访问)。这时就需要清理 iptables
,采用如下命令对 iptables
进行清理:
root@user:/# iptables -t nat -F
root@user:/# iptables -t nat -X
root@user:/# iptables -t nat -nvL
现在再重新部署应用并在对应的工作节点上查看 iptables 的 nat 表是否正常,若只有一条,再尝试访问应用。若还是不能正常访问,则查看 iptables 对应表中的 CNI-DN-550b4bf3691bef6919331
数据的规则是否完整,可以执行以下命令:
[root@user ~]# iptables -n -t nat -L CNI-DN-550b4bf3691bef6919331
Chain CNI-DN-66a2679082f9abc22ecf1 (1 references)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8086 to:10.244.3.254:8080
此时可以再尝试如下命令,将对应的工作节点(如 ip
为 10.23.34.56
)再绑定一遍:
[root@user ~]# iptables -t nat -R CNI-DN-550b4bf3691bef6919331 1 -p tcp -d 10.23.34.56 --dport 8080 -j DNAT --to-destination 10.244.3.254:8086
注意上面的工作节点 ip
及 8080
端口替换为自己实际的 ip 和端口。
参考
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论