TKE集群节点max-pod是如何配置的

2022-08-15 18:03:53 浏览数 (2)

使用tke集群部署服务的时候,经常会遇到一种情况,就是pod一种pending无法成功调度到节点上,查看事件提示报错

代码语言:javascript复制
0/9 nodes are available: 1 node(s) didn't match Pod's node affinity, 8 Too many pods.

从日志看,是1个节点没满足节点亲和性,还有8个节点pod太多,这个pod太多是什么原因呢?

其实tke集群的每个节点我们都会设置一下最大可容纳的pod数量,一般都是在kubelet的启动配置/etc/kubernetes/kubelet文件中通过MAX_PODS来进行定义的,一般会同步到节点的yaml的status.allocatable.pods字段,当节点的pod数量达到max_pods的值时候,这个时候再往节点调度pod就会失败,提示Too many pods。

那么节点的最大运行pod数量到底是如何定义的呢?下面我们来说说tke不同网络模式下节点新加入tke集群的max_pods是如何进行设置的。

1. GlobalRouter模式节点最大pod数设置

GlobalRouter 网络模式是容器服务 TKE 基于底层私有网络 VPC 的全局路由能力,实现了容器网络和 VPC 互访的路由策略,GlobalRouter模式集群创建的时候就会对节点的pod数量上限进行设置,因为需要根据网络配置给节点分配容器cidr。

因此GlobalRouter的kubelet配置的max_pods就是单个节点的容器cidr ip数量,然后再减去3个,这里为什么要减去3个呢? 因为有三个地址不能分配分别是:网络号、广播地址和网关地址,因此 Node 最大的 Pod 数目 = cidr - 3。

比如你创建集群单节点设置的最大pod数量是32,那么实际上节点最多可以容纳29个pod,当第30个pod想继续运行到节点就会报错node Too many pods。

很多人这里就有个疑问了,如果我节点资源还充足,我想继续往上面调度pod,是不是可以修改节点的kubelet参数就行了呢?其实理论上这样是可行的,这样节点确实可以调度更多的pod,但是这样会存在一些问题。

如果你将值改太大,会导致后续有pod分配不到ip,因为一个节点可用的pod ip是固定的cidr - 3,但是pod的调度只会去看节点的max-pods是不是满了,并不会判断容器网段ip是不是不足,因此可能节点的容器网段ip用完了,pod还是会往节点调度,导致pod无法分配ip。

还需要注意的是max-pod是包含节点hostnetwork模式pod,hostnetwork模式pod不会占用容器网段ip,但是会算在max-pod的数量里面,那么这里就有另外一个问题了,节点虽然有cird - 3 和容器ip可以给pod使用,但是实际是调度不了那么多GlobalRouter模式pod到节点的,因为每个节点会有一些hostnetwork模式的pod,会占用一些pod数量,因此实际可分配给GlobalRouter模式pod的数量就会比cidr - 3少。这里其实可以适当的给kubelet的pod数量增加一些,用来容纳hostnetwork模式pod,这里每个节点的容器网段ip就能充分利用了。

2. vpc-cni模式节点最大pod数设置

上面说了GlobalRouter模式的max-pod是如何设置的,下面我们来说说vpc-cni模式下是如何设置的,GlobalRouter因为会给每个节点分配容器网段,max-pod是根据容器网段cidr来设置,但是vpc-cni模式下容器网段就是vpc子网,pod ip是从子网获取,那每个节点的max-pods是如何设置呢?

vpc-cni这里的模式比较复杂,vpc-cni模式下会有个最大的eni ip数量限制,这个是根据机型配置来的,并且也支持在创建集群的时候设置单节点的max-pod,默认是设置的64,。vpc-cni模式这里定义节点的max-pods会根据对比机型的eni ip数量限制和创建集群设置的pod上限值大小,取2者中的较大的设置为节点的max-pods。

那么节点的eni数量限制怎么来的呢?vpc-cni是利用弹性网卡的能力,因此这里的限制也是根据弹性网卡限制来的,具体可以参考文档 https://cloud.tencent.com/document/product/576/18527

其实在tke控制台选择节点也是有提示的

那么这些数量是如何来的呢?这里简要说下,每种机型都有2个限制,一个是弹性网卡数量限制,还有就是弹性网卡内网ip数量限制。 这里定义下弹性网卡限制为eni_num,弹性网卡内网ip数量为eni_ip_num

因为弹性网卡数量配额会包含主网卡,这里给容器使用的弹性网卡数量需要在eni_num-1 弹性网卡内网ip包含网卡的主ip,主ip是无法给容器使用的,因此给容器使用的ip为eni_ip_num-1 那么最终某种机型可以用的eni ip是(eni_num-1) * (eni_ip_num-1)

这里拿标准型 S5的1核机型为例

最终计算的eni数量为(2 - 1)*(6 - 1)=5,也就是说1C的S5机型加入tke集群,机型的eni数量限制是5个。 如果是标准型 S5的8核机型,那么eni数量是(6 - 1)*(20 - 1)=95,也就是说8C的S5机型加入tke集群,机型的eni数量限制是95个。

如果创建集群默认设置的node节点pod上限是64,这里在加入集群时候会计算出机型的eni数量去和64比较,取较大的作为节点max-pods。

也就是说1C的S5机型加入tke集群,节点的max-pod值设置的是61,这里后端设计遵循了GlobalRouter逻辑还是会减去3个ip,因此是61。

8C的S5机型加入tke集群,节点的max-pod值设置的是95。

当然vpc-cni也是可以手动设置节点的max-pods,修改节点/etc/kubernetes/kubelet文件中MAX_PODS配置,但是这里改大会存在一个问题,就是节点的eni ip最大数量是有限制的,如果你将非hostnetwork模式pod调度到节点,会出现分配不到eni-ip的情况,只有hostnetwork模式pod才能正常调度到节点。

0 人点赞