自己使用一台master两台worker搭建了一个k8s集群。把服务部署上去后,发现服务无法访问到部署在集群外部的数据库。
在宿主机上直接ping是能够ping通的,但是pod中不行。
pod能ping通各node ip,但无法ping通集群外部的网络ip。这个问题很奇怪。
#通过busybox验证
kubectl run busybox -it --image=busybox --rm
ping 192.168.x.x
这个问题花了不少时间搜索,有人遇到过类似问题,虽然没有提供完整的的解决方法,但提供了问题的定位方法。
参考:1) http://dockone.io/question/1350 2) https://blog.csdn.net/kozazyh/article/details/80595782
问题的原因在于部署集群时使用的网络插件flannel配置不正确,导致node的iptables设置错误。
查看iptables规则方法如下:
iptables -t nat -S
#关键的配置
-A POSTROUTING -s 10.20.0.0/16 -d 10.20.0.0/16 -j RETURN
-A POSTROUTING -s 10.20.0.0/16 ! -d 224.0.0.0/4 -j MASQUERADE --random-fully
-A POSTROUTING ! -s 10.20.0.0/16 -d 10.20.0.0/24 -j RETURN
-A POSTROUTING ! -s 10.20.0.0/16 -d 10.20.0.0/16 -j MASQUERADE --random-fully
这里的10.20.0.0应该是pod cidr网段,你需要查看该网段与你实际使用的网段是否一致。不一致就会导致目前的问题。
该网段在使用Kubeadm部署k8s时,通过--pod-network-cidr参数指定
#https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#initializing-your-control-plane-node
sudo kubeadm init
--image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers
--control-plane-endpoint=cluster-endpoint
--pod-network-cidr=10.20.0.0/16
--cri-socket=/run/containerd/containerd.sock
--apiserver-advertise-address=192.168.197.13
-v=5
如果你忘记了当时设置的cidr网段是什么,也可通过命令查询:kubectl describe node
在安装网络插件flannel时,在官方教程提供的配置中,其实也指定了网段为10.244.0.0/16
,如果这两个网段不一致,那么就会出现此问题。
#kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
---
kind: ConfigMap
...
data:
...
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
解决方法也很简单,重新设置flannel的网段配置,然后重启集群即可。
参考:https://stackoverflow.com/questions/55877256/kubernetes-pod-cant-reach-external-ip-address
#读取configmap
kubectl get configmap -n kube-system -o yaml kube-flannel-cfg > flannel.yaml
#修改flannel net-conf.json网段配置,设置为与pod cidr一致
vi flannel.yaml
net-conf.json: |
{
"Network": "10.244.0.0/16", #修改此行
"Backend": {
"Type": "vxlan"
}
}
#应用配置
kubectl apply -f flannel.yaml