自己使用一台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
