背景信息
独占ENI模式可为Pod提供最佳网络性能,提供高网络吞吐量和无限接近主机的网络延迟,适用于对网络性能有严格需求的场景,如视频流、科学计算等。该模式下,Cubecni插件将弹性网卡(ENI)投射到Pod给Pod独占使用,支持为有状态集(StatefulSet)提供固定IP能力,以及Pod或Namespace粒度的子网和安全组配置。
使用限制
Cubecni版本需为v1.1.3及以上
独占ENI的Pod不支持NetworkPolicy
目前仅支持华东1资源池
使用独占ENI的Pod,其部署密度受到云主机ENI数限制,详见弹性网卡使用限制
固定ENI(IP)只适用于有状态集
该特性目前处于内测阶段
使用方法
步骤1和步骤2可选,用于声明带特定标签的Pod或特定Namespace下的Pod的独占ENI使用哪些子网和安全组,从而实现Namespace或Pod粒度的子网和安全组配置;
步骤3演示如何创建使用独占ENI的Pod,步骤4演示如何创建使用固定ENI(IP)的有状态集。
可选步骤1:创建自定义资源EniCfg(可实现Namespace或Pod粒度子网和安全组配置)
通过创建EniCfg,可通过selector方式为某些Pod或某些Namespace下的Pod在新建时指定使用的子网和安全组。若无EniCfg,Pod将使用默认的子网和安全组。创建方式如下:
登录容器服务管理控制台,在集群列表页面单击目标集群名称;
在左侧导航栏,选择工作负载 > 自定义资源;
在自定义资源页面,选择资源对象浏览器,API组选择network.ccse.ctyun.cn > v1 > ElasticNetworkInterfaceConfiguration,单击新增;
创建EniCfg的示例如下:
apiVersion: network.ccse.ctyun.cn/v1 kind: ElasticNetworkInterfaceConfiguration metadata: name: elasticnetworkinterfaceconfiguration-sample spec: type: binding idleTimeout: 600 cascadingDelete: false priority: selector: podSelector: matchLabels: foo: bar namespaceSelector: matchLabels: foo: bar subnets: ## ENI使用的子网列表 - subnet-1 - subnet-2 securityGroups: ## ENI使用的安全组列表 - sg-1 - sg-2
参数说明如下:
参数 说明 type 取值范围:
- binding:独占ENI策略,Pod删除后,ENI被释放
- fixed:固定ENI(IP)策略,Pod删除后,ENI会保留一段时间,仅用于有状态集(StatefulSet)
idleTimeout 空闲超时时间。当Pod删除后,对应ENI资源的保留时间,默认10h,当type为fixed时生效
cascadingDelete 是否级联删除。当Pod删除后,若对应有状态集已删除,是否级联删除对应ENI,默认为false,当type为fixed时生效
priority 优先级。若有多个EniCfg匹配同个Pod,值越小的EniCfg优先使用
selector 取值范围:
- podSelector:Pod选择器。用来匹配Pod的标签,匹配的Pod在创建时将使用该EniCfg,和namespaceSelector是“与”关系
- namespaceSelector:Namespace选择器。用来匹配Namespace的标签,匹配的Namespace下,Pod创建时将使用该EniCfg,和podSelector是“与”关系subnets 子网ID列表。用于配置Pod使用的子网,多个子网间是“或”的关系,此时Cubecni将选择一个符合条件的子网
securityGroups 安全组ID列表。可配置多个Pod ENI使用的安全组,最终生效的安全组数量小于等于5个
点击创建EniCfg资源后,Cubecni会同步网络配置信息,当该自定义资源status为Ready后,才能对新建的Pod生效。
[root@test# kubectl get enicfg NAME TYPE PRIORITY SELECTOR PHASE AGE elasticnetworkinterfaceconfiguration-sample fixed 100 {"namespaceSelector":{"matchLabels":{"foo":"bar"}},"podSelector":{"matchLabels":{"foo":"bar"}}} Ready 3m31s
可选步骤2:为命名空间添加匹配的标签
创建EniCfg自定义资源后,可为指定命名空间增加匹配的标签,以确保与EniCfg的selector.namespaceSelector匹配。如下所示,为test命名空间添加与示例EniCfg匹配的标签foo=bar。
kubectl label namespaces test foo=bar
预期输出如下:
# kubectl get ns test --show-labels
NAME STATUS AGE LABELS
test Active 11s foo=bar,kubernetes.io/metadata.name=test
步骤3:创建使用独占ENI的Pod
Pod创建时,Cubecni将根据Pod的标签以及所在命名空间的标签,查找匹配的EniCfg资源。如果没EniCfg资源匹配,将使用默认的安全组和子网。如果有EniCfg匹配,Cubecni将按照该资源定义的配置来申请ENI。
除了EniCfg外,可通过Pod注解方式声明独占ENI使用的子网和安全组,Pod注解优先级高于EniCfg,注解定义如下:
键 | 值 |
---|---|
cubecni.eni.securityGroups | 值为安全组ID列表,表示在已有安全组的基础上,额外增加的安全组,最终生效的安全组数量<=5 |
cubecni.eni.additionalSecurityGroups | 值为安全组ID列表,如sg-xxx,sg-aaa |
cubecni.eni.subnets | 值为子网ID列表 |
通过打标方式,声明Pod使用独占ENI,此时,Cubecni会创建类型为Eni的自定义资源来描述Pod所占用的ENI。如下所示:
创建名为demo的Pod,打标cubecni.exclusiveEni="true"声明该Pod使用独占ENI
cat << EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: name: demo spec: replicas: 1 selector: matchLabels: app: demo template: metadata: labels: app: demo cubecni.exclusiveEni: "true" ### podTemplate打标,声明使用独占ENI spec: containers: - image: registry-crs-huadong1.ctyun.cn/library/nginx:latext name: server EOF
查询Pod状态,以及使用的Eni资源
[root@test]# kubectl get po -l app=demo -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES demo-768fcfc9b8-ld5xx 1/1 Running 0 44s 192.168.32.87 ccseagent-jgzr9kcqyu <none> <none> [root@test]# [root@test]# kubectl get eni NAME MODE BOUNDPOD PODNAMESPACE IPV4 SUBNETID PHASE AGE cc2e0d32-5b2e-4640-8bb0-d695004a binding demo-768fcfc9b8-ld5xx default 192.168.32.87 subnet-e5vae31kox Bound 51s
步骤4:创建使用固定ENI(IP)的有状态集
Cubecni可为有状态集提供固定ENI(IP)能力,当这类Pod重建后,依旧能使用重建前使用的ENI(IP)。如下所示:
创建名为demo的有状态集,打标cubecni.fixedEni="true"声明使用固定ENI(IP)
cat << EOF | kubectl apply -f - apiVersion: v1 kind: Service metadata: labels: app: fixed-demo app-group: fixed-demo name: fixed-demo spec: ports: - name: http port: 80 protocol: TCP targetPort: 80 selector: app-group: fixed-demo sessionAffinity: None type: ClusterIP --- apiVersion: apps/v1 kind: StatefulSet metadata: name: fixed-demo spec: replicas: 1 serviceName: fixed-demo selector: matchLabels: app: fixed-demo template: metadata: annotations: labels: app: fixed-demo cubecni.fixedEni: "true" ### podTemplate打标,声明使用固定ENI(IP) spec: containers: - image: registry-crs-huadong1.ctyun.cn/library/nginx:latext name: server EOF
查询Pod状态,以及使用的Eni资源
# kubectl get sts NAME READY AGE fixed-demo 1/1 68s [root@test]# kubectl get po -l app=fixed-demo -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES fixed-demo-0 1/1 Running 0 70s 192.168.32.90 default-50ecd <none> <none> [root@test]# kubectl get eni NAME MODE BOUNDPOD PODNAMESPACE IPV4 SUBNETID PHASE AGE c9bafd11-edc8-4e83-bfaa-71dcd13c fixed fixed-demo-0 default 192.168.32.90 subnet-e5vae31kox Bound 65s
常见问题
如何判断Pod是否使用EniCfg的网络配置?
Pod创建后,Pod注解network.ccse.ctyun.cn/v1.cubecni.eni.config的值为该Pod使用的EniCfg资源,若没该注解,则说明该Pod创建时无匹配的EniCfg;
apiVersion: v1 kind: Pod metadata: annotations: ccse.ctyun.cn/eni-instance-id: port-qkqksxxxxx network.ccse.ctyun.cn/v1.cubecni.eni.binding: e94e1cad-753d-4da6-a3b2-xxxx network.ccse.ctyun.cn/v1.cubecni.eni.config: binding-eni network.ccse.ctyun.cn/v1.cubecni.eni.status.ipv4: 192.168.x.x network.ccse.ctyun.cn/v1.cubecni.exclusiveEni: "true" labels: app: demo cubecni.exclusiveEni: "true"
Cubecni将创建自定义资源Eni,用于描述Pod使用的ENI及配置信息。Pod注解network.ccse.ctyun.cn/v1.cubecni.eni.binding的值,记录了该Pod使用的自定义资源Eni。可通过以下方式查询。
# kubectl get eni e94e1cad-753d-4da6-a3b2-54eb10a3 -oyaml
apiVersion: network.ccse.ctyun.cn/v1
kind: ElasticNetworkInterface
metadata:
name: e94e1cad-753d-4da6-a3b2-xxxx
spec:
idleTimeout: 36000
mode: binding
nodeName: ccseagent-jgzxxxxx
podName: demo-768fcfc9b8-xxxx
podNamespace: default
resID: 64c2a49d-2b01-496b-xx-xxxxx
securityGroupIDs:
- sg-342bxxxxx
subnetID: subnet-e5vaxxxxx
status:
eniInfo:
instanceID: affe3664-xxxx-d1e7-607c-ed186dxxxxx
instanceType: "3"
mac: fa:16:3e:5f:xx:xx
mainIPv4: 192.168.x.x
name: ccse-cni-xxxx-a2bf-4b6b-xxxx
networkInterfaceID: port-qkqksxxxx
securityGroupIDs:
- sg-342bxxxx
subnetID: subnet-e5vaexxxx
subnetIPv4CIDR: 192.168.x.x/19
subnetIPv4Gateway: 192.168.x.x
subnetIPv6Gateway: fe80::f816:3eff:xxxx:xxxx
vpcID: vpc-mpawzxxxxx
message: resource prepare success
nodeName: ccseagent-jgzrxxxxx
phase: Bound
podLastSeen: "2025-xx-xxT08:46:24Z"
Pod创建后为什么没有使用EniCfg中的网络配置?
请确保EniCfg资源状态为Ready;
请确保Pod标签和EniCfg中的podSelector标签匹配,且(或)Pod所在命名空间的标签与EniCfg中的namespaceSelector标签匹配;
请检查EniCfg的spec.type值是否正确,值binding表示该EniCfg只作用于新建的使用独占ENI的Pod,值fixed表示该EniCfg仅作用于新建的使用固定ENI的有状态集。
声明使用独占ENI或固定IP的Pod卡在pending状态为什么没创建出来?
可查看工作负载或Pod的事件,通常是ENI配额不够导致Pod无法调度:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling <invalid> default-scheduler 0/5 nodes are available: 5 Insufficient network.ccse.ctyun.cn/eni.