kubernetes的timeout问题
kubernetes+alpine+php特别容易出现访问外网/解析外网地址的时候出现超时的问题.
原因
docker容器访问外网的时候,整个完整路径是这样的.
容器-->主机-->外网-->主机-->容器
容器到主机之间的流量要经过源地址转换(SNAT)才能顺利流通.
SNAT就像是一个搬运工,把砖(流量)从容器搬到主机
如果一个主机上面运行多个容器,并发访问外网(特别是PHP这种没有连接池的)时向系统申请可用端口(nf_nat_l4proto_unique_tuple),不可用时+1,然后再申请,再校验.这个过程一多,最终就会导致寻址超时.
说白了是个系统内核问题.
详细的解释见
记一次Docker/Kubernetes上无法解释的连接超时原因探寻之旅
解决方案
最优解
节点升级到 5.1的Linux内核.
iptables升级到1.6.2以上
用基于IPVS模式,尽量少做SNAT/DNAT,支持随机端口SNAT的网络插件启动kubernetes
或者用绕过SNAT的网络插件插件方案,比如阿里云的terway.但这个插件跟阿里云绑定得比较深入,需要每台机器额外购买一个弹性网卡.
次优解
用ds部署name sever,所有节点的DNS解析走节点上的name server,通过最小程度的SNAT+dns cache缓解此类问题.
伪解决方案(不能解决根本问题)
默认的pod的/etc/resolv.conf
一般长这样
sh-4.2# cat /etc/resolv.conf nameserver <kube-dns-vip> search <namespace>.svc.cluster.local svc.cluster.local cluster.local localdomain options ndots:5
这个配置的意思是,默认nameserver指向kube-dns/core-dns,所有查询中,如果.的个数少于5个,则会根据search中配置的列表依次搜索,如果没有返回,则最后再直接查询域名本
身。ndots就是n个.(dots)的意思
举个例子
sh-4.2# host -v baidu.com Trying "baidu.com.<namespace>.svc.cluster.local" Trying "baidu.com.svc.cluster.local" Trying "baidu.com.cluster.local" Trying "baidu.com.localdomain" Trying "baidu.com" ......
重开socket
lifecycle: postStart: exec: command: - /bin/sh - -c - "/bin/echo 'options single-request-reopen' >> /etc/resolv.conf"
设置重开socket是规避容器并发A,AAAA查询
2级域名直接走上层解析
参考kubernetes 使用基于 alpine 镜像无法正常解析外网DNS 做的
直接运行 sed -i 's/options ndots:5/#options ndots:5/g' /etc/resolv.conf 会报错
alpine的echo命令会吞换行符,而resolv.conf格式不对DNS解析会报错
dnsConfig: options: - name: ndots value: "2" - name: single-request-reopen
去掉了options ndots:5
,变会默认值1,这样的话,容器内部直接访问还是没问题的,走search列表,<svc>.<namespace>.svc.cluster.local
,还是能够访问。
而解析Google.com
,实际上是解析Google.com.
,.的数量超过1个,这时不走search列表,直接用上层DNS
综上所述,去掉ndots/ndots设为1 降低了频繁DNS查询的可能性。对于外网IP的解析有“奇效”。
但如果该主机运行其他容器(这不废话吗,一个节点不跑多个容器那还用啥kubernetes),其他容器也会并发地请求,SNAT的问题还是会出现,所以说修改/etc/resolv.conf
文件并不能解决根本问题
歪门邪道1
lifecycle: postStart: exec: command: - /bin/sh - -c - "head -n 2 /etc/resolv.conf > /etc/temp.conf;cat /etc/temp.conf > /etc/resolv.conf;rm -rf /etc/temp.conf"
歪门邪道2
initContainers: - name: alpine image: alpine command: - /bin/sh - -c - "head -n 2 /etc/resolv.conf > /etc/temp.conf;cat /etc/temp.conf > /etc/resolv.conf;rm -rf /etc/temp.conf"
衍生的问题
DNAT
容器访问clusterIP(因为是虚拟IP所以需要DNAT)也有可能出现这类超时的问题
注意Virtual domain的问题
non-headservice的域名格式是<svc>.<namespace>.svc.cluster.local
如果我们容器直接访问<svc>.<namespace>.svc.cluster.local
,因为默认DNS设置的问题,解析的次数反而更多。正确的方式是访问<svc>
例子:假设test下面有个s的svc
host -v s # 解析1次 host -v s.test.svc.cluster.local # 解析4次
所以,访问同namespace其他svc,直接用svc名去访问即可,没必要装逼使用<svc>.<namespace>.svc.cluster.local
这种格式。
其他知识
dns记录类型
- A记录:地址记录,用来指定域名的IPv4地址(如:8.8.8.8),如果需要将域名指向一个IP地址,就需要添加A记录。
- CNAME: 如果需要将域名指向另一个域名,再由另一个域名提供ip地址,就需要添加CNAME记录。
- TXT:在这里可以填写任何东西,长度限制255。绝大多数的TXT记录是用来做SPF记录(反垃圾邮件)。
- NS:域名服务器记录,如果需要把子域名交给其他DNS服务商解析,就需要添加NS记录。
- AAAA:用来指定主机名(或域名)对应的IPv6地址(例如:ff06:0:0:0:0:0:0:c3)记录。
- MX:如果需要设置邮箱,让邮箱能收到邮件,就需要添加MX记录。
- 显性URL:从一个地址301重定向到另一个地址的时候,就需要添加显性URL记录(注:DNSPod目前只支持301重定向)。
- 隐性URL:类似于显性URL,区别在于隐性URL不会改变地址栏中的域名。
- SRV:记录了哪台计算机提供了哪个服务。格式为:服务的名字、点、协议的类型,例如:_xmpp-server._tcp。
用到的命令
安装方法:
yum install -y bind-utils sudo apt-get install -y dnsutils apk add bind-tools
dig
dig +trace +ndots=5 +search $host
host
host -v $host
参考链接:

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
K8S从懵圈到熟练 – 集群伸缩原理
阿里云K8S集群的一个重要特性,是集群的节点可以动态的增加或减少。有了这个特性,集群才能在计算资源不足的情况下扩容新的节点,同时也可以在资源利用率降低的时候,释放节点以节省费用。 这篇文章,我们讨论阿里云K8S集群扩容与缩容的实现原理。理解实现原理,在遇到问题的时候,我们就可以高效地排查并定位原因。我们的讨论基于当前的1.12.6版本。 节点增加原理 阿里云K8S集群可以给集群增加节点的方式有,添加已有节点,集群扩容,和自动伸缩。其中,添加已有节点又可分为手动添加已有节点和自动添加已有节点。节点的增加涉及到的组件有,节点准备,弹性伸缩(ESS),管控,Cluster Autoscaler以及调度器。 手动添加已有节点 节点准备,其实就是把一个普通的ECS实例,安装配置成为一个K8S集群节点的过程。这个过程仅靠一条命令就可以完成。这条命令使用
- 下一篇
k8s中将Jenkins安装到master节点上的yaml
Node 将 pod 指定到特定的 node上有几种方式,使用label是个很好的方法,在执行前需要给每个node打个标签命令如下 $ kubectl label node master nodename=master 这句命令的意思是给master节点上打上 nodename=master 的标签,如此可以为其他节点也打上各自的标签 yaml 配置 --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: traefik-ingress-controller rules: - apiGroups: - "" resources: - services - endpoints - secrets verbs: - get - list - watch - apiGroups: - extensions resources: - ingresses verbs: - get - list - watch --- kind: ClusterRoleBinding apiVersio...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- 设置Eclipse缩进为4个空格,增强代码规范
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2全家桶,快速入门学习开发网站教程
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8编译安装MySQL8.0.19
- Docker安装Oracle12C,快速搭建Oracle学习环境