《Kubernetes网络权威指南》读书笔记 | 前方高能:Kubernetes网络故障定位指南

Posted COCOgsta

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Kubernetes网络权威指南》读书笔记 | 前方高能:Kubernetes网络故障定位指南相关的知识,希望对你有一定的参考价值。

书籍来源:《Kubernetes网络权威指南:基础、原理与实践》

一边学习一边整理读书笔记,并与大家分享,侵权即删,谢谢支持!

附上汇总贴:《Kubernetes网络权威指南》读书笔记 | 汇总_COCOgsta的博客-CSDN博客


本节重点介绍Kubernetes网络故障定位的实战经验。

3.9.1 IP转发和桥接

  1. IP转发

IP转发是一种内核态设置,有时,该项设置可能会被安全团队运行的定期安全扫描重置,或者没有配置为重启后生效。在这种情况下,就会出现网络访问失败的情况。

  1. 桥接

Kubernetes通过bridge-netfilter配置使iptables规则应用在Linux网桥上。该配置对Linux内核进行宿主机和容器之间数据包的地址转换是必需的。否则,Pod进行外部服务网络请求时会出现目标主机不可达或者连接拒绝等错误(host unreachable或connection refused)。

3.9.3 hairpin

hairpin的含义用一句话表述就是“自己访问自己”。例如,Pod有时无法通过Service IP访问自己,这就有可能是hairpin的配置问题了。Kubelet的启动参数提供了一个--hairpin-mode的标志,支持的值有hairpin-veth和promiscuous-bridge。

3.9.4 查看Pod IP地址

查看Kubernetes Pod IP有两个办法,分别是从外面看和进到里面看。从外面看又分为Kubernetes API和docker命令。进到里面看就是进到容器内使用ip或ifconfig等命令查看。

  1. 从外面看Pod IP地址之Kubernetes API

Kubernetes是知道集群中所有Pod的IP信息的,也提供相应的查询接口,因此kubectl get pod或者kubectl describe pod就能显示Pod的详细信息。

如果运行在容器内的进程希望获取该容器的IP,环境变量是一个不错的选择,尤其是Kubernetes提供了相关的downward API。当在Pod的配置文件书写如下env字段时:

容器启动后MY_POD_IP这个环境变量的值来自Pod的status.podIP,容器内的应用只要读取该环境变量即可获取Pod的真实IP地址。

  1. 从外面看Pod IP地址之docker命令

一般情况下我们可以通过以下命令查询容器的IP地址:

然而对于Pod中的容器,这一招并不管用,你会发现输出是一个空字符串。究其原因,既不是Kubernetes的Bug也不是用户配置错误,而是Kubernetes使用的CNI与Docker奉行的CNM标准割裂导致的。

  1. 进到容器里面看Pod IP地址

进到容器的docker命令有docker exec或docker attach,进到容器后再执行ip addr或ifconfig这类常规命令。

3.9.5 故障排查工具

下面是一些我们在排查上述问题时使用的非常有用的工具。

  1. tcpdump

tcpdump是一个用来捕获网络流量的“利器”,不论是传统主机网络还是容器网络架构,它可以帮助我们定位一些常见的网络问题,下面是一个使用tcpdump进行流量捕获的简单例子。

  1. 容器镜像内置常用网络工具

在一个镜像中内置一些网络工具包,对我们的排查工作会非常有帮助,比如在下面的简单服务中,我们添加一些常用的网络工具包:iproute2 net-tools ethtool,Dockerfile如下所示:

另外,就算只用busybox镜像,其实也有很多“讲究”,nslookup在调试Kube-dns的域名功能时非常有用。busybox 1.28版自带nslookup。

3.9.6 为什么不推荐使用SNAT

  1. 问题描述

当一个容器尝试访问一个外部服务时,运行容器的主机将网络包中的容器IP用它本身的IP替换,即Masquerade(SNAT的一种)。当响应返回到主机的时候,它进行一个逆转换(把网络包中的主机IP替换成容器IP)。对于容器,这个操作完全是透明的,它不知道发生了这样的一个转换。

这么做会带来一个问题,就是当并发访问NodePort时会导致丢包。除了NodePort,flannel的--ip-masq=true选项也会引起丢包。

SNAT导致Linux内核丢包的原因在于其conntrack的实现。SNAT代码在POSTROUTING链上被调用两次。这意味着在SNAT端口分配和插入conntrack表之间有一个时延,如果有冲突的话可能最终导致插入失败及丢包。

  1. 解决方法

需要在masquerade规则中设置flag NF_NAT_RANGE_PROTO_RANDOM_FULLY。通过使用打了补丁的flannel和Kube-proxy,能够显著降低conntrack表的插入错误,使整个集群中的丢包错误的数目从每几秒一次下降到每几个小时一次。

以上是关于《Kubernetes网络权威指南》读书笔记 | 前方高能:Kubernetes网络故障定位指南的主要内容,如果未能解决你的问题,请参考以下文章

《Kubernetes网络权威指南》读书笔记 | iptables

《Kubernetes网络权威指南》读书笔记 | 打通CNI与Kubernetes:Kubernetes网络驱动

《Kubernetes网络权威指南》读书笔记 | Kubernetes网络策略:为你的应用保驾护航

《Kubernetes网络权威指南》读书笔记 | 最常用的Docker网络技巧

《Kubernetes网络权威指南》读书笔记 | Linux隧道网络的代表:VXLAN

《Kubernetes网络权威指南》读书笔记 | 主角登场:Linux容器