k8s问题总结
/ / 点击总结遇到的问题及解决方案
设计类问题
集群Master高可用
创建集群时,使用多个Master就不提了,这是基础。
- 一般做法是使用Keepalived陪VIP,结合health_check来做高可用,但这种做法存在一个问题:所有的rest请求都落到一个Master上,当客户端请求量比较大的时候,会导致apiserver hang死。
-
2. 使用DNS动态解析:平安证券分享的方案(公众号上看的,公布细节有限,原话是:当Master挂掉,DNS解析可在十分钟内指向新的MasterIP),猜测他们的做法使用脚本去发现apiserver的运行状况,发现挂掉,就切换解析,这种做法在Master挂掉时,会存在无法访问apiserver服务的空窗期(十分钟左右,DNS解析生效时间),无法提供服务,而且所有请求也都落到一个Master上;另一种利用DNS的做法是DNS批量解析到所有Master上,当脚本检测到Master挂掉,然后解除到该Master的解析,虽然比前者好用一些,但在DNS删除解析生效期间,也会有一部分请求落到挂掉的Master上。
-
3. 使用Nginx+Keepalived方案:首先所有Master上都使用docker启动一个NGINX,并配置自动重启和检查apiserver健康的策略,然后安装好keepalived并配置VIP和设置NGINX的监控检查规则。客户端向集群发送rest请求时使用的是VIP+NGINX端口,所有请求都落到VIP Master的NGINX上,然后由NGINX转发到所有Master的apiserver上。- NGINX配置apiserver健康检查,可以保证其转发的请求都能转发到正常运行的apiserver上,keepalived配置NGINX的健康检查可以保证,每次客户端请求时都能请求到NGINX,通过这么设置,实现了NGINX的高可用和apiserver的高可用,且所有到apiserver的请求不仅仅落到某一台机器上。
不同集群Pod间网络互通
正常情况下,不同集群的Pod之间是无法相互访问的
想要不同集群Pod之间网络互通,必要条件是,两者的网段不能够冲突,如果冲突,无法确定Pod要访问的地址到底是另一个集群的还是当前集群的。
- 使用网络插件。通过对Pod请求出来的数据进行重新封包(目标PodIP所在集群作为新包的目的IP),把数据包发送到目标Pod所在集群,然后网络插件再解包,把解包后的原始数据包发送到指定Pod,实现Pod网络互通的目地。
- 使用网关+路由的方式。在集群中弄几台机器用作网关,所有到该集群Pod的请求路由到这些机器,这些机器再利用kube-proxy将请求转到Pod内部,实现网络互通,但这种实现方式中,一个Pod请求到外部和外部请求进来的路径不一致。外部请求进来:proxyNode->Pod;请求到外部:Pod->Pod所在Node->外部。这种方式存在问题:对于Pod来说,每次请求的来源IP都是ProxyNode,当应用根据来源IP来做一些策略时可能存在问题。
踩坑系列
apiserver请求过多,直接hang死
使用
集群Master高可用方案里的第3点(参照设计类问题中的集群Master高可用部分)。
k8s 1.12以下版本kubelet使用configmap后无法删除pod
原因:kubelet目录使用了软连接,umount时报错。解决:1.升级1.12后修复bug 2. /etc/systemd/system/kubelet.service.d/10-kubeadm.conf中启动命令加上参数 –root-dir=/app/…kubelet 直接将kubelet目录改成实际目录
k8s postStart执行程序导致容器无法ready
使用postStart执行程序时如果执行的是一个常驻程序,会导致容器一直处于 containerCreating状态
k8s apiserver 调不通 service类型的webhook // TODO
k8s coredns主机多个servername时,随机解析(主机上配了容灾dns服务器)
coredns configmap配置串行解析
1 | forward . /etc/resolv.conf { |
k8s集群内数据包无法通过weave发送到指定pod(内核3.10,weave 2.4.0)
原因(同时存在):
- 在低于3.14版本的内核中,bridge设备的mac地址发生变化的时候,local fdb未更新。内核修复记录
- weave 2.4.0中,网桥执行initPrep时给网桥设置了mac地址,后边其他地方又修改了。weave修复记录
解决办法(解决1个即可):
- 升级内核大于3.14(解决内核bug)
- 升级weave版本到2.5.0以后(去掉了initPrep中给网桥初始化mac地址的代码)
内核参数 tcp_timestamps 开启导致的问题
高版本内核中移除了同一dst的timestamp缓存tcp timestamp的offsets随机生成,集群内部访问到外部时,经过主机会做NAT,端口复用的时候就会出现timestamp 比对端期望的小,导致对端把数据包丢弃,从而无法建立连接。
cp: remove per-destination timestamp cache
Commit 8a5bd45f6616 (tcp: randomize tcp timestamp offsets for each connection)
randomizes TCP timestamps per connection.解决办法:
- 关闭内核中 net.ipv4.tcp_timestamps
- 关闭服务端内核配置: net.ipv4.tcp_tw_recycle (tcp_tw_resue?)