背景信息
獨占ENI模式可為Pod提供最佳網絡性能,提供高網絡吞吐量和無限接近主機的網絡延遲,適用于對網絡性能有嚴格需求的場景,如視頻流、科學計算等。該模式下,Cubecni插件將彈性網卡(ENI)投射到Pod給Pod獨占使用,支持為有狀態集(StatefulSet)提供固定IP能力,以及Pod或Namespace粒度的子網和安全組配置。
使用限制
Cubecni支持版本為v1.1.3,可檢查kube-system下守護進程cubecni的cubecni-daemon鏡像版本是否不低于v1.1.3
獨占ENI的Pod不支持NetworkPolicy,可配置安全組實現訪問控制
使用獨占ENI的Pod,其部署密度受到云主機ENI數限制,詳見彈性網卡使用限制
固定ENI(IP)只適用于有狀態集
該特性目前處于內測階段,僅對以下資源池開放:華東1,華北2,長沙42,杭州7,上海15,烏魯木齊7,武漢41,蕪湖4,西安7,西南1,西南2,上海36,呼和浩特3
使用方法
步驟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.daliqc.cn > v1 > ElasticNetworkInterfaceConfiguration,單擊新增;
創建EniCfg的示例如下:
apiVersion: network.ccse.daliqc.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.daliqc.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.daliqc.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.daliqc.cn/v1.cubecni.eni.config的值為該Pod使用的EniCfg資源,若沒該注解,則說明該Pod創建時無匹配的EniCfg;
apiVersion: v1 kind: Pod metadata: annotations: ccse.daliqc.cn/eni-instance-id: port-qkqksxxxxx network.ccse.daliqc.cn/v1.cubecni.eni.binding: e94e1cad-753d-4da6-a3b2-xxxx network.ccse.daliqc.cn/v1.cubecni.eni.config: binding-eni network.ccse.daliqc.cn/v1.cubecni.eni.status.ipv4: 192.168.x.x network.ccse.daliqc.cn/v1.cubecni.exclusiveEni: "true" labels: app: demo cubecni.exclusiveEni: "true"Cubecni將創建自定義資源Eni,用于描述Pod使用的ENI及配置信息。Pod注解network.ccse.daliqc.cn/v1.cubecni.eni.binding的值,記錄了該Pod使用的自定義資源Eni。可通過以下方式查詢。
# kubectl get eni e94e1cad-753d-4da6-a3b2-54eb10a3 -oyaml
apiVersion: network.ccse.daliqc.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.daliqc.cn/eni.