一、操作场景
·让某些节点上的 Pod 只使用指定子网的 IP,实现节点维度的网段隔离。
·让某个业务的 Pod 固定使用某几个子网的 IP,便于在防火墙或安全策略中按网段放通。
这篇说说如何通过节点和 Pod 维度的指定子网能力实现上述需求,包含两种用法:
| 用法 | 适用集群 | 生效范围 | 配置位置 |
| 节点指定子网 | 非固定 Pod IP 模式 | 该节点上新增的弹性网卡 | 节点注解或标签 |
| Pod 指定子网 | 固定 Pod IP 模式 | 该 Pod 申请的 IP | Pod 注解 |
注意:说明:
注意:两种用法均同时支持共享网卡和独立网卡。
二、前提条件
·集群网络模式为 VPC-CNI。
·待指定的子网已添加到集群中。未添加到集群的子网无法被使用,指定后节点将无法分配弹性网卡。添加方法请参见这篇的 添加子网到集群。
·待指定的子网与节点处于同一可用区。子网是可用区级资源,跨可用区的子网会被忽略;若某节点指定的子网全部位于其他可用区,该节点将无法分配 IP。
·eniipamd 组件版本满足要求,各能力的版本要求如下表:
| 能力 | eniipamd 版本要求 |
| 通过节点注解指定子网(非固定 Pod IP 模式) | 3.4.2 及以上 |
| 通过节点注解指定子网(固定 Pod IP 模式) | 3.5.2 及以上 |
| 通过节点标签指定子网 | 3.5.7 及以上 |
| 通过 Pod 注解指定子网(固定 Pod IP 模式) | 3.4.3 及以上 |
三、如何确定集群网络类型
1. 登录 容器服务控制台,选择左侧导航中的集群。
2. 在集群页面,选择目标集群名称,进入集群详情页,查看集群基础信息下的节点和网络信息。
3. 查看容器网络插件是否为 VPC-CNI 相关模式,以及是否固定 Pod IP 的取值。该取值决定了应使用节点指定子网还是 Pod 指定子网。
四、如何确定 eniipamd 组件版本
1. 登录 容器服务控制台,选择左侧导航中的集群。
2. 在集群页面,选择目标集群名称,进入集群详情页。
3. 选择左侧导航栏中的组件管理,在组件页面查看 eniipamd 组件版本。
五、添加子网到集群
指定的子网必须先添加到集群中。可通过控制台或云 API 添加。
控制台操作步骤如下:
1. 登录 容器服务控制台,选择左侧导航中的集群。
2. 在集群页面,选择目标集群名称,进入集群详情页。
3. 在节点和网络信息中找到容器网络的子网配置,添加目标子网。
六、节点指定子网
适用于非固定 Pod IP 模式的集群。设置后,该节点上新增的弹性网卡都从指定子网创建。
注意:指定子网只影响新增的弹性网卡。节点上的存量弹性网卡不受影响,即使存量网卡位于非指定子网,其上仍可继续分配 IP。若需要让节点上所有网卡都落到指定子网,请参见这篇的 使节点所有网卡都使用指定子网。
七、通过节点注解指定子网
执行以下命令,多个子网以英文逗号分隔:
kubectl annotate node <nodeName> tke.cloud.tencent.com/nominated-eni-subnets="subnet-xxxxxxx1,subnet-xxxxxxx2" –overwrite
注意:逗号后不能有空格,否则子网 ID 校验会失败。
八、通过节点标签指定子网
eniipamd 3.5.7 及以上版本支持通过节点标签指定子网。多个子网通过多个标签指定,可同时生效:
kubectl label node <nodeName> tke.cloud.tencent.com/nominated-eni.subnet-xxxxxxx1=truekubectl label node <nodeName> tke.cloud.tencent.com/nominated-eni.subnet-xxxxxxx2=true
注意:说明:
注意:若注解和标签同时存在,以注解为准,同时会在节点上产生一条告警事件提示冲突。
九、使节点所有网卡都使用指定子网
指定子网只对新增网卡生效。若需要让节点上的所有共享网卡都使用指定子网,需要解绑存量网卡后重新绑定。
注意:警告:
注意:解绑网卡会中断该节点上所有 Pod 的网络,直到 Pod 重建完成。请在业务低峰期操作,或先将节点上的业务迁移到其他节点。
1. 指定子网。该操作只影响新增网卡,对存量网卡无副作用。
kubectl annotate node <nodeName> tke.cloud.tencent.com/nominated-eni-subnets="subnet-xxxxxxx1,subnet-xxxxxxx2" –overwrite
2. 解绑节点上的存量网卡。注解取值必须是 yes,填写 true 不会生效。
kubectl annotate node <nodeName> tke.cloud.tencent.com/disable-node-eni="yes" –overwrite
3. 确认存量网卡已全部解绑。以下命令输出为空表示已解绑完成。
kubectl get nec <nodeName> -o jsonpath='{.status.eniInfos[*].eniID}'
4. 重新绑定网卡。此时新建的网卡会使用指定子网。
kubectl annotate node <nodeName> tke.cloud.tencent.com/disable-node-eni="no" –overwrite
5. 重建节点上的所有 Pod,使其从新网卡获取 IP。先查询节点上的 Pod:
kubectl get pod -owide -A –field-selector spec.nodeName=<nodeName>
十、取消节点指定子网
将注解的值置为空,即可回退到默认分配策略:
kubectl annotate node <nodeName> tke.cloud.tencent.com/nominated-eni-subnets="" –overwrite
十一、节点初始化时指定子网
新增节点时,若希望节点从初始化阶段就使用指定子网,可在节点池中预先配置。
为避免节点在拿到指定子网配置之前就分配了网卡,需要同时添加以下标签:
tke.cloud.tencent.com/need-nominated-eni-subnets=true
该标签可以保证节点在没有拿到指定子网注解前不会分配弹性网卡。
注意:警告:
注意:该标签生效后,若节点始终拿不到指定子网注解,节点将一直不分配弹性网卡,其上的 Pod 会长期处于 Pending 状态,且没有超时兜底机制。请确认节点池已正确配置注解下发后再使用。需要解除时,执行 kubectl label node <nodeName> tke.cloud.tencent.com/need-nominated-eni-subnets- 删除该标签。
十二、原生节点池
1. 添加节点时,设置节点标签 tke.cloud.tencent.com/need-nominated-eni-subnets=true。
2. 通过节点注解指定子网 tke.cloud.tencent.com/nominated-eni-subnets=subnet-xxxxxxx1,subnet-xxxxxxx2。
新增节点池时的配置路径为创建节点池 > 高级设置。
十三、普通节点池
1. 通过节点注解指定子网 tke.cloud.tencent.com/nominated-eni-subnets=subnet-xxxxxxx1,subnet-xxxxxxx2。
2. 添加节点时,设置节点标签 tke.cloud.tencent.com/need-nominated-eni-subnets=true。
注意:普通节点池的注解和标签都是异步添加的。为保证节点初始化时就带有指定子网的注解,强烈建议通过 kubelet 的自定义参数 node-labels 来添加上述标签。
新增节点池时的配置路径为创建节点池 > 高级设置。
存量节点池的注解可通过节点池编辑页面修改。kubelet 自定义参数当前不支持修改,如有需要请 联系我们。
十四、通过标签指定(普通/原生节点池)
eniipamd 3.5.7 及以上版本支持通过节点标签指定子网,多个子网通过多个标签指定:
tke.cloud.tencent.com/nominated-eni.subnet-xxxxxxx1=truetke.cloud.tencent.com/nominated-eni.subnet-xxxxxxx2=true
新增节点池时的配置路径为创建节点池 > 高级设置。
存量节点池的配置路径为节点池页面 > 编辑节点池。
十五、限制子网仅供指定使用
默认情况下,集群中的所有子网都参与自动分配。若希望某些子网只能通过指定的方式使用、不参与自动分配,可以修改 eniipamd 的全局配置。
注意:说明:
注意:该配置的含义是:“该子网退出自动选择流程,但仍可被指定子网的注解或标签显式使用”而不是禁用该子网。配置后,未指定该子网的节点不会从中分配 IP,而显式指定了该子网的节点仍然可以正常使用。
操作步骤如下:
1. 登录 容器服务控制台,选择左侧导航中的集群。
2. 在集群页面,选择目标集群名称,进入集群详情页。
3. 选择左侧导航栏中的组件管理,在组件页面选择 eniipamd 组件右侧的修改全局配置。
4. 找到 ipam.onlyNominatedEniSubnets 配置,将目标子网 ID 添加进去。
5. 单击左下角确认修改,等待组件更新完成。
十六、Pod 指定子网
适用于固定 Pod IP 模式的集群。通过 Pod 注解指定该 Pod 申请 IP 时使用的子网。
十七、使用方式
在 Pod 的注解中添加 tke.cloud.tencent.com/nominated-eni-subnets,多个子网以英文逗号分隔。以 StatefulSet 为例:
apiVersion: apps/v1kind: StatefulSetmetadata: name: busybox namespace: defaultspec: replicas: 3 serviceName: busybox selector: matchLabels: k8s-app: busybox template: metadata: annotations: # 必填:指定子网,多个子网以英文逗号分隔,逗号后不能有空格 tke.cloud.tencent.com/nominated-eni-subnets: "subnet-xxxxxxx1,subnet-xxxxxxx2" labels: k8s-app: busybox spec: containers: – name: busybox image: busybox command: ["sleep", "infinity"]