# 使用容器网络配置为命名空间/工作负载绑定子网及安全组
#### 操作场景
CCE Autopilot集群支持以命名空间或工作负载粒度设置容器所在的容器子网及安全组，该功能通过名为NetworkAttachmentDefinition的[CRD](https://kubernetes.io/zh/docs/concepts/extend-kubernetes/api-extension/custom-resources/)资源实现。如您想为指定的命名空间或工作负载配置指定的容器子网和安全组，可创建自定义容器网络配置（NetworkAttachmentDefinition），并将该容器网络配置与相应的命名空间或工作负载关联，进而实现业务的子网划分或业务安全隔离的诉求。
图1自定义容器网络配置示意图   
![](https://support.huaweicloud.com/usermanual-cce-autopilot/zh-cn_image_0000002053791601.png "点击放大")
目前容器网络配置（NetworkAttachmentDefinition）支持关联的资源类型对比如下：
 表1关联资源类型对比 
| 维度                    | 容器网络配置（NetworkAttachmentDefinition）关联的资源类型                                                                                  ||
| 维度                    | 命名空间                                          | 工作负载                                           |
|:---|:---|:---|
| 容器网络划分维度说明           | 为命名空间关联容器网络配置，该命名空间下创建的所有工作负载使用相同的子网配置和安全组配置。 | 为工作负载关联容器网络配置，指定了相同容器网络配置的工作负载使用相同的子网配置和安全组配置。 |
| 支持的CCE Autopilot集群版本 | v1.27.8-r0, v1.28.6-r0及以上版本。                  | v1.27.8-r0, v1.28.6-r0及以上版本。                   |
| 约束限制                 | 同一个命名空间最多只能被关联到一个容器网络配置。                        | 只能指定未关联命名空间的自定义容器网络配置。                        |
   
![](https://support.huaweicloud.com/usermanual-cce-autopilot/public_sys-resources/note_3.0-zh-cn.png)
- Pod使用的容器网络配置优先级如下：Pod直接关联的容器网络配置 \> Pod的命名空间关联的容器网络配置 \> 集群默认容器网络配置（default-network）。
- 集群中存在默认容器网络配置default-network，对所有未配置自定义容器网络配置的Pod生效，"概览"页面的网络信息中的"默认容器子网"即为default-network中的容器子网。default-network不支持删除。
- 当集群中只有一个容器网络配置，该容器网络配置即为默认容器网络配置；当集群中有多个容器网络配置时，带有名为"yangtse.io/default-network: true"annotation的容器网络配置即为默认容器网络配置。当集群中不存在默认容器网络配置时，未关联任何容器网络配置的Pod创建后会由于无法分配到网卡而启动失败。
 
#### 约束与限制
- 如需删除创建的自定义容器网络配置(NetworkAttachmentDefinition)，请先删除对应的命名空间下使用该配置创建的Pod（带有名为"cni.yangtse.io/network-status"的annotation），详情请参见[删除网络配置]。
- 为容器网络配置添加一个子网，就会调用两次VPC的/v2.0/subnets查询接口，一次是webhook组件检查子网的可用性，一次是控制面组件获取必要的子网信息进行持久化。请勿一次性添加超过20个子网，以免触发VPC该接口的查询流控。
 
#### 创建命名空间类型的容器网络配置
创建命名空间类型的容器网络配置后，关联命名空间下创建的所有工作负载使用相同的子网配置和安全组配置。
- [通过控制台创建命名空间类型的容器网络配置]
  1. 登录[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)，单击集群名称进入集群。
  
  2. 单击集群名称进入集群，在左侧选择"配置中心"，选择"网络配置"页签。
  
  3. 查看"容器网络配置"，单击"添加自定义容器网络配置"，在弹窗中配置容器子网和安全组等信息。 
     - 名称：自定义容器网络配置名称，最长支持63个字符。default-network、default、mgnt0、mgnt1四个名称为系统预留，请勿使用。
     
     - 关联资源类型：自定义容器网络配置关联的资源类型，详情请参见[表1]。创建命名空间类型的容器网络配置请选择"命名空间"类型。
     
     - 命名空间：请选择您需要关联的命名空间。不同容器网络配置之间关联的命名空间不可重复。若无命名空间可选请单击后方的"创建命名空间"进行创建。
     
     - 容器子网：请选择子网，最多可选择100个子网。若无子网可选请单击后方的"创建子网"进行创建，创建完成后单击刷新按钮。
     
     - 关联安全组：默认为容器ENI安全组，您也可以选择单击后方的"创建安全组"进行创建，创建完成后单击刷新按钮。最多可选择5个安全组。
     
     
     图2创建命名空间类型的容器网络配置   
     ![](https://support.huaweicloud.com/usermanual-cce-autopilot/zh-cn_image_0000002133566589.png "点击放大")
     
     
     
  
  4. 完成基本配置后单击"确定"，创建完成后页面自动返回到自定义容器网络配置列表，可以看到新创建的容器网络配置已在列表中。 
     图3容器网络配置列表   
     ![](https://support.huaweicloud.com/usermanual-cce-autopilot/zh-cn_image_0000002133608653.png "点击放大")
     
     
     
   
- [通过kubectl命令行创建命名空间类型的容器网络配置]
  创建命名空间类型的容器网络配置后，该命名空间下创建的所有工作负载使用相同的子网配置和安全组配置。
  1. 请参见[通过kubectl连接集群](https://support.huaweicloud.com/usermanual-cce-autopilot/cce_11_0107.html)，使用kubectl连接集群。
  
  2. 创建YAML文件networkattachment-test.yaml，用于创建自定义容器网络配置并关联命名空间，文件名称可自定义。 
     ```
     vim networkattachment-test.yaml
     ```
     文件内容如下：
     ```
     apiVersion: k8s.cni.cncf.io/v1
     kind: NetworkAttachmentDefinition
     metadata:
       annotations:
         yangtse.io/project-id: 05e38**       
       name: example                   
       namespace: kube-system                 
     spec:
       config: |
        {
         "type":"eni-neutron",                
         "args":{
           "securityGroups":"41891**",        
           "subnets":[
             {
               "subnetID":"27d95**"           
             }
           ]
         },
         "selector":{
           "namespaceSelector":{             
             "matchLabels":{
               "kubernetes.io/metadata.name":"default"
             }
           }
         }
        }
     ```
     表2关键参数说明 
     | 参数                    | 是否必填 | 参数类型   | 描述                                                                                                                          |
     |:---|:---|:---|:---|
     | apiVersion           | 是   | String  | 表示API的版本号，固定为k8s.cni.cncf.io/v1。                                                                                              |
     | kind                  | 是   | String | 创建的对象类别，固定为NetworkAttachmentDefinition。                                                                                      |
     | yangtse.io/project-id | 是   | String | 当前所在Region的项目ID，获取方式请参见[获取项目ID](https://support.huaweicloud.com/api-cce/cce_02_0341.html)。                                   |
     | name                 | 是    | String   | 配置名称，可自定义。名称由小写字母、数字、横线（-）和点组成，且必须以字母或数字开头和结尾，最长支持63个字符。default-network、default、mgnt0、mgnt1四个名称为系统预留，请勿使用。                     |
     | namespace              | 是   | String   | 配置资源所在命名空间，固定为kube-system。                                                                                                   |
     | config                | 是   | Object | 配置内容，为json格式的字符串。 config字段数据结构具体说明，请参见[表2 config字段数据结构说明]。 |
        
      表3config字段数据结构说明 
     | 参数        | 是否必填 | 参数类型      | 描述                                                                                                          |
     |:---|:---|:---|:---|
     | type     | 是     | String | 表示网络类型，固定为eni-neutron。                                                                                       |
     | args    | 是      | Object  | 安全组和子网的配置参数。 args字段数据结构具体说明，请参见[表4]。      |
     | selector | 否   | Object | 选择该配置所作用的命名空间。 selector字段数据结构具体说明，请参见[表5]。 |
        
      表4args字段数据结构说明 
     | 参数            | 是否必填 | 参数类型                      | 描述                                                                                                                                                                                                                                                                                                                                                         |
     |:---|:---|:---|:---|
     | securityGroups | 否   | String                   | 需要配置的安全组ID，最多关联5条安全组。如果没有对安全组进行规划，请和default-network中的安全组保持一致。 获取方式： 登录[VPC控制台](https://console.huaweicloud.com/vpc/#/vpc/vpcs/list)，在左侧导航栏选择"访问控制 \> 安全组"，单击安全组名称，在"基本信息"页签下找到"ID"字段复制即可。                                                                                                    |
     | subnets        | 是     | Array of subnetID Objects | 容器子网ID列表，至少需填写1个，最多可填写100个，具体格式如下： ``` [{"subnetID":"27d95**"},{"subnetID":"827bb**"},{"subnetID":"bdd6b**"}] ``` 容器子网要求与集群在同一VPC下。 获取方式： 登录[VPC控制台](https://console.huaweicloud.com/vpc/#/vpc/vpcs/list)，在左侧导航栏选择"虚拟私有云 \> 子网"，单击子网名称，在"基本信息"页签下找到"子网ID"字段复制即可。 |
        
      表5selector字段数据结构说明 
     | 参数             | 是否必填 | 参数类型             | 描述                                                                                                                                                       |
     |:---|:---|:---|:---|
     | namespaceSelector | 否   | matchLabels Object | 该选择器为Kubernetes标准的选择器，需填写命名空间标签，格式如下： ``` "matchLabels":{ "kubernetes.io/metadata.name":"default" } ``` 不同配置之间的命名空间不可重合。 |
        
     
     
  
  3. 创建NetworkAttachmentDefinition。 
     ```
     kubectl create -f networkattachment-test.yaml
     ```
     回显如下，表示NetworkAttachmentDefinition已创建。
     ```
     networkattachmentdefinition.k8s.cni.cncf.io/example created
     ```
     
     
   
#### 创建工作负载类型的容器网络配置
创建工作负载类型的容器网络配置后，需要为工作负载关联容器网络配置，指定了相同容器网络配置的工作负载使用相同的子网配置和安全组配置。
- [通过控制台创建工作负载类型的容器网络配置]
  1. 登录[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)。
  
  2. 单击集群名称进入集群，在左侧选择"配置中心"，选择"网络配置"页签。
  
  3. 查看"容器网络配置"，单击"添加自定义容器网络配置"，在弹窗中配置容器子网和安全组等信息。 
     - 名称：自定义容器网络配置名称，最长支持63个字符。default-network、default、mgnt0、mgnt1四个名称为系统预留，请勿使用。
     
     - 关联资源类型：自定义容器网络配置关联的资源类型，详情请参见[表1]。创建工作负载类型的容器网络配置请选择"工作负载"类型。
     
     - 容器子网：请选择子网，最多可选择100个子网。若无子网可选请单击后方的"创建子网"进行创建，创建完成后单击刷新按钮。
     
     - 关联安全组：默认为容器ENI安全组，您也可以选择单击后方的"创建安全组"进行创建，创建完成后单击刷新按钮。最多可选择5个安全组。
     
     
     图4创建工作负载类型的容器网络配置   
     ![](https://support.huaweicloud.com/usermanual-cce-autopilot/zh-cn_image_0000002133613461.png "点击放大")
     
     
     
  
  4. 完成基本配置后单击"确定"，创建完成后页面自动返回到自定义容器网络配置列表，可以看到新创建的容器网络配置已在列表中。 
     图5容器网络配置列表   
     ![](https://support.huaweicloud.com/usermanual-cce-autopilot/zh-cn_image_0000002098175262.png "点击放大")
     
     
     
  
  5. 在创建工作负载时，可选择自定义的容器网络配置。 
     1. 在左侧导航栏中选择"工作负载"，在右侧选择"无状态负载"页签。
     
     2. 单击页面右上角"创建工作负载"，在"高级配置"中选择"网络配置"页签，并选择是否开启指定容器网络配置。
     
     3. 选择一个已有的容器网络配置。如果没有可用的网络配置，可单击"添加自定义容器网络配置"进行创建。
        图6选择容器网络配置   
        ![](https://support.huaweicloud.com/usermanual-cce-autopilot/zh-cn_image_0000002133619741.png "点击放大")
        
        
     
     4. 工作负载其余信息都配置完成后，单击"创建工作负载"。 返回到"配置中心"，在容器网络配置列表里可以看到创建的容器网络配置关联的资源名称。
        图7查看容器网络配置关联的资源   
        ![](https://support.huaweicloud.com/usermanual-cce-autopilot/zh-cn_image_0000002133701545.png "点击放大")
        
        
     
     
     
     
   
- [通过kubectl命令行创建工作负载类型的容器网络配置]
  创建工作负载类型的容器网络配置后，需要为工作负载关联容器网络配置，关联相同容器网络配置的工作负载将使用相同的子网配置和安全组配置。
  1. 请参见[通过kubectl连接集群](https://support.huaweicloud.com/usermanual-cce-autopilot/cce_11_0107.html)，使用kubectl连接集群。
  
  2. 创建YAML文件networkattachment-test.yaml，用于自定义容器网络配置，文件名称可自定义。 
     ```
     vim networkattachment-test.yaml
     ```
     文件内容如下：
     ```
     apiVersion: k8s.cni.cncf.io/v1
     kind: NetworkAttachmentDefinition
     metadata:
       annotations:
         yangtse.io/project-id: 80d5a**    
       name: example                       
       namespace: kube-system                     
     spec:
       config: |
        {
         "type":"eni-neutron",                    
         "args":{
           "securityGroups":"f4983**",   
           "subnets":[
             {
               "subnetID":"5594b**"       
             }
           ]
         }
        }
     ```
     表6关键参数说明 
     | 参数                     | 是否必填 | 参数类型   | 描述                                                                                                         |
     |:---|:---|:---|:---|
     | apiVersion            | 是    | String  | 表示API的版本号。固定为k8s.cni.cncf.io/v1。                                                                            |
     | kind                 | 是    | String  | 创建的对象类别。固定为NetworkAttachmentDefinition。                                                                     |
     | yangtse.io/project-id | 是     | String  | 当前所在Region的项目ID，获取方式请参见[获取项目ID](https://support.huaweicloud.com/api-cce/cce_02_0341.html)。                |
     | name                    | 是      | String   | 配置名称，可自定义。名称由小写字母、数字、横线（-）和点组成，且必须以字母或数字开头和结尾，最长支持63个字符。default-network、default、mgnt0、mgnt1四个名称为系统预留，请勿使用。 |
     | namespace               | 是     | String | 配置资源所在命名空间，固定为kube-system。                                                                                |
     | config               | 是     | Object  | 配置内容，为json格式的字符串。 config字段数据结构具体说明，请参见[表7]。 |
        
      表7config字段数据结构说明 
     | 参数  | 是否必填 | 参数类型          | 描述                                                                                                   |
     |:---|:---|:---|:---|
     | type | 是     | String        | 表示网络类型，固定为eni-neutron。                                                                                |
     | args | 是    |  Object | 安全组和子网的配置参数。 args字段数据结构具体说明，请参见[表8]。 |
        
      表8args字段数据结构说明 
     | 参数            | 是否必填 | 参数类型                        | 描述                                                                                                                                                                                                                                                                                                                                                           |
     |:---|:---|:---|:---|
     | securityGroups | 否    | String                  | 需要配置的安全组ID，最多关联5条安全组。如果没有对安全组进行规划，请和default-network中的安全组保持一致。 获取方式： 登录[VPC控制台](https://console.huaweicloud.com/vpc/#/vpc/vpcs/list)，在左侧导航栏选择"访问控制 \> 安全组"，单击安全组名称，在"基本信息"页签下找到"ID"字段复制即可。                                                                                                      |
     | subnets         | 是     | Array of subnetID Objects | 容器子网ID列表，至少需填写1个，最多可填写100个，具体格式如下： ``` [{"subnetID":"27d95**"},{"subnetID":"827bb**"},{"subnetID":"bdd6b**"}] ``` 容器子网要求与集群在同一VPC下。 获取方式： 登录[VPC控制台](https://console.huaweicloud.com/vpc/#/vpc/vpcs/list)，在左侧导航栏选择"虚拟私有云 \> 子网"，单击子网名称，在"基本信息"页签下找到"子网ID"字段复制即可。 |
        
     
     
  
  3. 创建NetworkAttachmentDefinition。 
     ```
     kubectl create -f networkattachment-test.yaml
     ```
     回显如下，表示NetworkAttachmentDefinition已创建。
     ```
     networkattachmentdefinition.k8s.cni.cncf.io/example created
     ```
     
     
  
  4. 创建YAML文件deploy.yaml，用于创建工作负载并关联刚创建的容器网络配置（此处创建Deployment类型的工作负载），文件名称可自定义。 
     ```
     vim deploy.yaml
     ```
     文件内容如下：
     ```
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: nginx
     spec:
       replicas: 1
       selector:
         matchLabels:
           app: nginx
       template:
         metadata:
           labels:
             app: nginx
             yangtse.io/network: "example"  # 自定义容器网络配置名称，便于通过label查找所有关联此容器网络配置的Pod        
           annotations:
             yangtse.io/network: "example"  # 自定义容器网络配置名称
         spec:
           containers:
             - name: container-0
               image: nginx:alpine
               resources:
                 limits:
                   cpu: 100m
                   memory: 200Mi
                 requests:
                   cpu: 100m
                   memory: 200Mi
           imagePullSecrets:
             - name: default-secret
     ```
     - yangtse.io/network：指定的自定义容器网络配置名称，只能指定未关联命名空间的容器网络配置。请在label上同时添加此参数，便于通过label查找所有关联此容器网络配置的Pod。
       ![](https://support.huaweicloud.com/usermanual-cce-autopilot/public_sys-resources/notice_3.0-zh-cn.png)
       yangtse.io/network指定的自定义容器网络配置名称与networkattachment-test.yaml中name值一致。
       
     
     
     
     
  
  5. 创建Deployment。 
     ```
     kubectl create -f deploy.yaml
     ```
     回显如下：
     ```
     deployment.apps/nginx created
     ```
     
     
   
#### 验证命名空间/工作负载是否绑定容器网络配置
本节主要介绍如何确认工作负载是否成功绑定容器网络配置中的子网和安全组。如果您需要验证命名空间级别的绑定情况，可以通过该命名空间中的具体工作负载实现，验证步骤与本节一致。
1. 验证子网是否绑定成功。 
   1. 查看工作负载中Pod对应的IP地址。
      ```
      kubectl get pod -o wide
      ```
      回显结果如下：
      ```
      NAME                     READY   STATUS    RESTARTS   AGE     IP              NODE                                   NOMINATED NODE   READINESS GATES
      nginx-85dbdb8c5d-ng5bb   1/1     Running   0          5d18h   192.168.60.5   ca50a5ae-e1ef-41c6-b3fc-6ebcd10a1e07   <none>           <none>
      ```
      
   
   2. 进入[网络控制台](https://console.huaweicloud.com/vpc/)，左侧导航栏单击"虚拟私有云 \> 子网"，单击对应的子网名称。
   
   3. 单击"IP地址管理"，"IP地址管理"中若有Pod对应的IP地址则说明子网绑定成功。
      图8查看子网绑定的IP地址   
      ![](https://support.huaweicloud.com/usermanual-cce-autopilot/zh-cn_image_0000002024602226.png "点击放大")
      
      
   
   
   
   
2. 验证安全组是否绑定成功。 
   1. 返回[网络控制台](https://console.huaweicloud.com/vpc/)，左侧导航栏单击"访问控制 \> 安全组"，单击对应的安全组名称。
   
   2. 单击"关联实例"，当前页签中单击"辅助弹性网卡"。
   
   3. "辅助弹性网卡"页签中，若私有IP地址列表有Pod对应的IP地址，则说明安全组绑定成功。
      图9查看安全组绑定的IP地址   
      ![](https://support.huaweicloud.com/usermanual-cce-autopilot/zh-cn_image_0000002024448098.png "点击放大")
      
      
   
   
   
   
 
 #### 删除网络配置
您可以查看新添加网络配置的YAML，也可以对新添加的配置进行"删除"操作。
在删除网络配置时，需先删除该配置所对应的容器，否则将删除失败。
1. 执行以下命令筛选集群中使用该配置的Pod（其中example为示例配置名称，请自行替换）：
   ```
   kubectl get pod -A -o jsonpath="{range .items[?(@.metadata.annotations.cni\\.yangtse\\.io/network-status=='[{\"name\":\"example\"}]')]}{.metadata.namespace}{'\t'}{.metadata.name}{'\n'}{end}"
   ```
   返回结果中包含了该配置关联的Pod名字及命名空间。
   
2. 删除创建该Pod的Owner，其Owner可能为Deployment、StatefulSet、Job和CronJob类型的工作负载。
   ```
   kubectl delete deployment nginx
   ```
   回显如下：
   ```
   deployment.apps "nginx" deleted
   ```
   
3. 删除创建的容器网络配置。
   ```
   kubectl delete -f networkattachment-test.yaml -n kube-system
   ```
   回显如下：
   ```
   networkattachmentdefinition.k8s.cni.cncf.io "example" deleted
   ```
   
 
