1.k8s中的网络通信类型
K8s中的网络是非常重要的,整个k8s集群的通信调度都是通过网络插件实现的。
网络通信主要有以下几种:
1).容器间的通信: 同一个pod内的多个容器间的通信。
2).pod通信: 从一个pod的ip到另一个pod的ip。
3).pod与service通信: pod的ip到cluster ip。
4).外部通信: service与集群外部客户端的通信。
2.k8s中的网络插件和各自特点
1).常用的网络插件:calico、flannel
(1).calico 既能够提供ip,又能够配置网络策略
提供ip: 给pod提供ip地址
配置网络策略:指定某一个pod允许哪一个网段的ip访问,限制哪个网段能访问,哪个不能.
(2).flannel: 也能够提供ip,但不能配置网络策略。
2).网络插件哪个性能好?
calico和flannel的性能差不多,因为flannel支持很多种后端模式,默认是vxlan叠加的网络模式,还有一个Director routing(直接路由模式)、host-gw(以宿主机充当网关)模式,
calico的优势在于能配置网络策略。如果论性能,flannel的直接路由模式和calico性能差不多。
3.pod网络连接超时的几种情况和排查思路
1).pod网络连接超时的几种情况:
(1).pod和pod连接超时
(2).pod和虚拟主机上的服务器连接超时
(3).pod和云主机或外网连接超时
2).排查思路:
(1).pod和pod连接超时:
查看calico或flannel是否是running状态,查看日志提取重要信息。(网络层面)
(2).pod和虚拟主机上的服务器连接超时:
检查pod网络,测试pod是否可以ping通同网段其他pod的ip。(pod层面)
(3).pod和外网连接超时:
检查物理网络,测试ping www.baidu.com或其他pod的ip,可以抓包测试有无异常,通过抓包修改内核参数(物理机层面)
当pod内部ping不通外网,如:www.baidu.com
解题思路: centos系统中
查看/etc/sys/net/bridge/bridge-nf-call-iptables的值是不是1,若不是则修改成1.(开启桥接模式)
当pod中连接集群之外的数据库超时:
解题思路:
(1).检查pod配置数据库地址是否正确
(2).检查网络状态,进入到容器对数据库ip地址telnet测试端口
(3).检查数据库是不是拒绝pod网段ip访问,是否已经开放了访问权限
(4).检查是否出现慢查询和数据库连接数问题
4.访问pod的ip:端口或者service时候显示超时的故障排查
处理思路和故障现象:
用tcpdump在相应宿主机上抓包,可以显示发送了大量重复的SYN数据包,但是没有收到ack.
诊断: 检查ipv4是否开启. #vim /etc/sysctl.conf 添加或修改: net.ipv4.ip_forward=1,sysctl -p生效
5.pod的生命周期阶段状态划分
(1).pending: 挂起状态,表示pod已经开始创建,内部的容器正在创建,包括拉取镜像、调度到node节点、可能需要一段时间。
(2).Running: 运行状态,pod成功创建并且正常调度到node节点,里面的容器已经被创建了。
(3).Teminated: 终止状态。
6.Pod的状态是running,但是容器已经退出的几种情况
1).pod是running,容器成功exit.
2).pod是running, 容器OOM退出(内存泄露的退出),容器自启拉取,pod持续保持running.
7.coredns或者kube-dns经常重启和报错的故障
1).故障现象:
在k8s中部署服务,服务之间无法通过dns解析,coredns一直处于CrashLoopBackOff状态,查看日志,报错如下: Loop (127.0.0.1:44222 -> :53) detected for zone。
2).解决思路:
coredns主要和相关node节点的宿主机上dns文件resolv.conf打交道,会读取宿主机的/etc/resolv.conf中的nameserver内容,查询resolv.conf文件,如果里面存在本地回环,如:127.0.0.1或127.0.0.53,那么就容易造成死循环。
3).解决步骤:
(1).修改相关node节点宿主机的resolv.conf文件,将nameserver临时改成114.114.114.114;
(2).之后,编辑coredns相关的deployment的yaml文件,将副本数改为0,停止已经启动的coredns 的pod。
(3).再编辑coredns相关的deployment的yaml文件,将副本数改为2或原来的数量,这样会触发coredns重新读取系统配置,此时服务的状态为running
上述一般能解决该问题。
总结:先将宿主机的dns文件/etc/resolv.conf的dns修改,然后重建coredns的pod,新建的pod就会重新读取宿主机上的/etc/resolv.conf文件。
8.k8s中calico或flannel网络插件的pod会挂载相应node节点宿主机本地dns文件案例
网络插件pod和coredns的pod里会挂载宿主机的dns文件,应用pod不会。
#cat /etc/resolv.conf #查看宿主机本地的dns文件
#Generated by NetworkManager
nameserver 192.168.5.200
#kubectl get pod -n kube-system -o wide |grep calico #查看calico网络的pod(也可flannel)
calico-kube-controllers-84445dd79f-7wjlk 1/1 Running 3 182d 100.80.33.27 dev-core-master-6-51
calico-node-6rx6m 1/1 Running 10 132d 192.168.6.76 dev-core-node-6-76
calico-node-84hbx 1/1 Running 6 286d 192.168.6.51 dev-core-master-6-51
calico-node-8mcv7 1/1 Running 7 286d 192.168.6.52 dev-core-master-6-52
…
#kubectl exec -it calico-node-84hbx bash -n kube-system – cat /etc/resolv.conf #查看网络插件pod的dns文件
nameserver 192.168.5.200
#kubectl get pod -n dev00-th-ffm -o wide |grep wms-boss
wms-boss-api-5b547957fc-hpdcv 1/1 Running 0 27h 100.105.200.204 dev-ard-node-7-93
wms-boss-ui-b85d49595-7h27c 1/1 Running 0 27h 100.105.200.226 dev-ard-node-7-93
#kubectl exec -it wms-boss-api-5b547957fc-hpdcv -n dev00-th-ffm – cat /etc/resolv.conf |grep nameserver #普通pod
nameserver 10.96.0.10
#kubectl exec -it wms-boss-ui-b85d49595-7h27c -n dev00-th-ffm – cat /etc/resolv.conf |grep nameserver
nameserver 10.96.0.10
coredns的pod也会挂载本地的/etc/resolv.conf文件,看看这个文件里的nameserver是不是114.114.114.114
9.pod之间,跨主机通信中断的故障
k8s中pod有调度到node1节点,有调度到node2节点,pod之间跨主机通信中断的错误.
1).故障现象:
在k8s集群部署pod后,pod之间无法跨节点访问。登录到一个node节点的pod,ping另一个node节点的pod,报错:无路由,No route to host。
2).排查思路:
查看网络插件如calico或flannel插件的pod日志,如果发下pod网段和物理机网段重合,则需要修改pod网段的ip地址,不能让pod网段的ip和宿主机网段的ip网段重合。
3).若pod网段和物理机网段重合,导致的网络故障,解决步骤如下:
(1).# kubectl get ippool default-ipv4-ippool -o yaml > default-ipv4-ippool.yaml #导出yaml
(上面default-ipv4-ippool是集群中默认的名字)
(2).# vim default-ipv4-ippool.yaml #修改pod的网段为新的和宿主机不同的网段
………
spec:
blockSize: 26
cidr: 100.64.0.0/10
ipipMode: Always
(3).# kubectl delete -f default-ipv4-ippool.yaml #删除现有ip pool
(4).# kubectl apply -f default-ipv4-ippool.yaml #创建新的ip pool
(5)然后依次删除calico或flannel网络pod
10.k8s集群内部域名解析困难故障
1). k8s的pod容器内部无法解析集群外的域名
安装coredns后,容器内部无法解析集群外的域名。
解决思路:
查看coredns是否正常运行
查看coredns日志
查看coredns会挂载本地的/etc/resolv.conf文件,看看这个文件里的nameserver是不是114.114.114.114
2).公司的k8s的基础服务mysql或redis是基于域名访问的,但是应用pod访问基础服务的域名时报错dns超时相关的故障
解决思路:
(1).出现k8s内部域名解析问题,最多的就是查看pod内部resolv.conf文件是否有问题,需要先登录pod查看resolv.conf有没有问题。
(2).如果pod的内部resov.conf文件没有问题, 尝试ping 基础服务的全域名(如:redis.svc.cluster.local),可能是跨命名空间等,需要用全域名,如果全域名能ping通,在yaml文件里配置域名为全域名地址。