记我们K8s集群中flannel遇到的两个问题
Contents
自建的K8s集群的坑不少, 尤其是到了Node数量越来越多之后, 问题也逐渐显露了出来, 博客主要介绍我们使用flannel
之后遇到的两个问题以及解决方案, 问题其实不严重, 只是涉及到了底层的结构, 改动时候要小心.
问题1 flannel的OOM问题
官方给出的配置
下面这张图是官方的配置, 可以看到, 默认的资源设置仅给定了50M内存
1 | kubectl -n kube-system describe ds kube-flannel-ds-amd64 |
我们遇到的问题
当我们的机器数量超过100个以后, flannel会以OOM的形式一直挂掉..
1 | Feb 9 04:52:44 kernel: [37630249.323630] Memory cgroup out of memory: Kill process 33838 (flanneld) score 1653 or sacrifice child |
通过Prometheus
采集到的数据也可以看到, 容器的内存使用情况很不乐观:
也没什么好的解决方案, 只能调整资源限制了.
问题2 flannel指定网卡问题
问题背景
因为我们使用的机器比较混杂, 机器的网卡也各不相同, 在开始搭建集群时就遇到了下面的问题.
1 | > 我们虚拟机中的网卡, 仅有`10`开头的内网地址 |
这样带来的问题就是flannel通信问题, 如果多个网卡, 且启动时未指定, flannel会找一个缺省的网卡, 对于虚拟机来讲没有关系, 但是对于物理机, flannel会找到eth0这个外网网卡, flannel使用错误的网卡发送数据, 抓包的数据可以看出 flannel使用了公网的网卡发送内网数据, 会被交换机丢弃, 具体图片就不贴了, IP属于公司机密.
具体的修改方法是确保flannel使用了正确的网卡, 需要在启动时指定参数--iface
与--iface-regex
:
我们的虚拟机数量少, 物理机数量多. 除了eth1
, 还有bond1
这种网卡名, 因此针对虚拟机, 统一将其eth0
改名变成eth1
,
而后指定了-iface-regex=eth1|bond1
这样的配置, 对于后续增加物理机更友好.
问题到这里似乎就结束了, 但是随着flannel经常发生OOM重启, 暴露了我们的设置问题.
我们发现flannel OOM后无法正常重启
1 | NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES |
为什么一开始没出现, 但是重启又会发生呢, 问题出在了正则表达式上. K8s在机器上启动容器时, 会创建虚拟的网卡. 这些网卡的名字类似veth17f90f70@if3
, 这样网卡名称的也会被正则表达式匹配到, 导致flannel无法启动, 临时的解决方案就是把机器上的容器移走,
vethxxx
网卡会自动删除, flannel也就自动恢复了.
当然根本的解决方案是修改正则配置: - -iface-regex="^(bond1|eth1)$"
使flannel更加精准的匹配网卡名称.
flannel 配置更新与验证
更新准备
因为不太了解flannel是否处理流量, 更新flannel时有点害怕, 直到看到了这里的架构.
flannel的功能主要是负责机器上路由表的修改, 也就是说, 只要不增删机器, flannel挂掉也没关系, 因为路由表不需要修改.
更新
我们有100多台节点, 整个集群更新过程大概持续了1个多小时, 更新过程中服务完全正常.
验证可用性
内存使用情况:
为了验证flannel是否可用, 我们将一台node删除, 观察到其他机器上的路由表也同步进行了修改.
总结
- 问题出现不可怕, 重要的是加好监控及时报警, 我们之前一直对kube-system的监控没有做到很好, flannel一直启动不成功的问题是我检查时发现的,
- 使用别人提供的yaml文件前, 要注意下资源设置的, 类似Prometheus也有这种问题的, 它对内存的要求很高
- 预算充足就不要自建集群了, 有不少运维问题的, 万一出现一个解决不了的就很麻烦, 类似上次那篇文章: 记一次Kubernetes机器内核问题排查
希望我们的经验能帮助到使用K8s的各位读者.