按理說到這一步Calico網絡插件應該可以正常工作了喊废,但我這里有一個節(jié)點的容器一直 Error 和 CrashLoopBackOff绅这,查看一下 Pod 狀態(tài) 和 Pod 日志:
從上面日志報出的問題可以看出是訪問 :
https://10.0.0.1:443/api/v1/namespaces/kube-system/pods/kube-flannel-ds-kw2bh 的時候超時了糯累,然后我就切換到報錯這個k8s-node01~02主機上算利,試著手動訪問一下:
$ curl --connect-timeout 10 https://10.0.0.1:443/api/v1/namespaces/kube-system/pods/kube-flannel-ds-kw2bh
curl: (28) Connection timed out after 10002 milliseconds
可以看到的確是超時的。泳姐。所以現(xiàn)在要找一下超時的原因了效拭。
試著 ping 一下 10.0.0.1:
$ ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.138 ms
^C
--- 10.0.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.138/0.138/0.138/0.000 ms
也是 OK 的,證明 ping
的 ICMP
數(shù)據(jù)包是可以正常來回的胖秒,但 curl HTTP
數(shù)據(jù)包就不知道了缎患,但至少確定了不是 10.0.0.1 這個目標地址的問題。
現(xiàn)在只能抓一下包了阎肝,打開一個窗口挤渔,執(zhí)行 tcpdump -i eth0 host 10.0.0.1 -n
進行監(jiān)聽,然后在另一個窗口執(zhí)行 curl https://10.0.0.1:443/api/v1/namespaces/kube-system/pods/kube-flannel-ds-kw2bh风题,此時 tcpdump
抓取到的報文如下:
$ tcpdump -i eth0 host 10.0.0.1 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
18:04:36.404311 IP 10.0.0.1.45998 > 192.168.0.181.sun-sr-https: Flags [S], seq 479485038, win 65495, options [mss 65495,sackOK,TS val 3269988560 ecr 0,nop,wscale 7], length 0
18:04:37.440153 IP 10.0.0.1.45998 > 192.168.0.181.sun-sr-https: Flags [S], seq 479485038, win 65495, options [mss 65495,sackOK,TS val 3269989596 ecr 0,nop,wscale 7], length 0
...
現(xiàn)在就來分析一下這個報文了:
- 首先判导,我是通過 curl 訪問 10.0.0.1;
- 由于 10.0.0.1 這個地址是對 kube-apiserver 地址的代理沛硅,所以報文會被轉發(fā)到 kube-apiserver眼刃,即 192.168.0.181;
- 而在上面抓取到的報文可以看出摇肌,報文轉到 192.168.0.181 時源地址為 10.0.0.1擂红,這就說明 192.168.0.181 回報文時也是直接會給 10.0.0.1 了;
- 而顯然围小,回給 10.0.0.1 是不可取的昵骤,因為現(xiàn)在每個 Kubernetes Node 上都有一個 kube-apiserver 的代理地址树碱,并且 kube-apiserver 所在主機并沒有正確到到達 10.0.0.1 的路由;
- 而現(xiàn)在有一個 Kubernetes Node 是正常的涉茧,說明當前網絡就把 10.0.0.1 這個地址綁定到了這個 Kubernetes Node赴恨,所以也就只有一個 Kubernetes Node 能夠正常訪問疹娶;
- 所以這個報文對于 k8s-node01~02 來說是處于一個只能出不能進的狀態(tài)伴栓,那就當然超時了;
知道問題所在之處后雨饺,就有解決辦法了钳垮。只要將從 Kubernetes Node
出去的報文的源地址改為 Kubernetes Node
本身的地址,而不是 10.0.0.1
就行了额港,這樣響應報文就能正確從 kube-apiserver
所在主機響應到 Kubernetes Node
主機了饺窿。
在所有 Kubernetes Node
機器上,添加如下 SNAT
的 iptables
規(guī)則即可:
$ iptables -t nat -A POSTROUTING -s 10.0.0.1/32 -j MASQUERADE
然后移斩,將其添加到 /etc/rc.local (避免以后重啟開機后不在自運行)
$ chmod +x /etc/rc.d/rc.local && echo 'iptables -t nat -A POSTROUTING -s 10.0.0.1/32 -j MASQUERADE' >> /etc/rc.d/rc.local
戶外題:如果安裝 Flannel 插件肚医,pod狀態(tài)出現(xiàn)了Error掉,該如何處理呢向瓷?
答:Flannel 運行時指定使用的網卡肠套,如 --iface=eth0
,修改 Flannel 部署的 YAML 文件在 Flannel 容器部分運行參數(shù)列表加上就行猖任,如下:
containers:
- name: kube-flannel
image: registry.cn-shenzhen.aliyuncs.com/zze/flannel:v0.13.0
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --iface=eth0
- --kube-subnet-mg
在網上查找是有這個解決方案你稚,不過這個方案對二進制部署k8s的起不到什么效果。如果還是不行朱躺,需要手動添加 SNAT
的 iptables
的規(guī)則刁赖。