当kubernetes运行在云主机上时,你可能遇到哪些问题?

在推动K8S落地到生产环境的半年时间内,我遇到了数不清的问题,真是一言难尽。

虽然618大促顺利扛过,但背后其实”带病上阵”,如果你的K8S也运行在虚拟机中,那么下面2个问题也许对你也有启发。

SDN流表同步问题

因为K8S滚动发布期间会瞬时创建大量的新POD,每个POD都通过CNI分配一个IP地址。

POD运行在虚拟机上,虚拟机运行在物理宿主机上,形成了”套娃”关系。

问题表现:

就是新POD创建后,首次访问其他IP会出现超时的问题。

SDN简单原理

云厂商的CNI插件实现,一般是请求SDN网络申请VPC内的同网段IP地址。

当新POD首次连接1台数据库时,流量经过底层虚拟化网络(SDN)的规则匹配,是可以顺利转发到数据库的。

但是当数据库回包给POD时,因为数据库侧的SDN组件此前没有见过POD的IP,因此不知道如何进行流量转发,这时候相关的SDN组件只能请求中央SDN数据库来拉取转发规则,规则可能是这样的:

POD IP的MAC地址是XXX,又或者POD IP需要经过网关IP YYY的转发。

只有拉取到规则之后,回包才能正确的交换/路由回到POD所在的虚拟机进而流入POD,在SDN中把这样的转发规则叫做一条flow。

超时问题

当我们deployment滚动发布时,一定会同时创建出很多新POD,它们同时分配到新IP地址,并且并发的访问同1台数据库。

此时,数据库侧SDN发现这些POD IP都没有本地的flow规则,因此就需要去SDN中心数据库进行拉取,导致SDN中心数据库超负荷响应变慢,规则同步延迟增加,导致回包的延迟剧增,应用访问数据库超时。

解决方案

不同的云厂商会有不同的解决思路。

目前了解到一种做法是对于K8S向SDN申请分配的这些IP地址,主动推送flow到VPC内的所有SDN组件,避免被动拉取造成中心单点瓶颈。

但是这并不完美,因为推送也是有延迟的,因此当POD启动后立即访问数据库时,如果规则还没有推到数据库侧的SDN组件,那么回包还是会触发拉取逻辑。

因此,我们能做的就是CNI插件分配到IP后暂等一下,给推送规则一点处理时间,算作trade off。

POD的CPU利用率不均匀

问题表现:

同一个Deployment的POD在不同虚拟机上的CPU使用率不同,严重的可能差异一倍。

这就是导致大部分POD的CPU都没有问题,然而个别的POD的CPU却打满了,让我们非常难受。

越临近大促该情况越明显,实际是因为云厂商虚拟机超卖严重导致,这个问题可以这样理解:

我们认为购买的是16核的云主机,然而因为云厂商超卖严重,16核对应的物理核心只有8核,因此运行在该主机上的POD的CPU使用率就是其他机器的一倍。

根据运维的经验,可以通过购买更多的云主机来占住底层资源,并且通过日常提高CPU使用率来避免云厂商超卖,这些都是缓解措施。

针对这种POD,我目前在发布系统提供了剔除POD的功能,相当于kubectl delete掉POD让其重建到其他node,以便应对这种难以克服的问题。

有条件的话还是建议物理机搭建K8S,并且确保使用相同的机型,避免这种CPU使用率不均匀的问题,否则会严重影响使用。

如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~