
# 配置ClusterExtensionProfile或ExtensionProfile
对于将工作负载调度到CCI 2.0的场景，用户可以通过配置[ClusterExtensionProfile]或[ExtensionProfile]对象来管理调度到CCI 2.0的Pod，灵活使用*Cluster* 级别的ClusterExtensionProfile，*Namespaced*级别的ExtensionProfile对调度到CCI 2.0的pod进行配置，从而减少对业务YAML的修改。
 #### 配置ClusterExtensionProfile
1. 生成YAML文件。 
   YAML示例：
   ```
   apiVersion: bursting.cci.io/v1
   kind: ClusterExtensionProfile
   metadata:
     name: test-cluster-profile
   spec:
     actions:
       annotations: #给Pod追加Annotations
         annotation1: value1
       labels:      #给Pod追加Labels
         label1: value1
       imageReplacement:    #给Pod添加镜像地址转换策略
       - replaceWith: xxx.com/yyy
         repositoryPrefix: harbor.domain/a/b/c/d
       hostPathReplacement: #给Pod添加HostPath卷转换策略
       - emptyDir:
           sizeLimit: 10Gi
         name: volume1
         policyType: replaceByEmptyDir
       evictions:           #配置Pod磁盘压力驱逐策略
         - type: "Hard"        
           signal: "DiskPressure"  
       podSidecars:         #给Pod添加Sidecar
         containers:
         - image: nginx:latest
           name: nginx
           position: head
         volumes:
         - name: volume2
           configMap:
             name: configmap1
     namespaceLabels:
       matchLabels:
         key2: value2
     policy: override
   ```
   
   

2. 使用以下命令创建配置。 
   ```
   kubectl apply -f <test-cluster-profile>     #所创建的YAML文件名，替换为实际值
   ```
   
   
3. （可选）使用以下命令查询是否配置成功。 
   ```
   kubectl get cextp
   ```
   
   
 
 #### 配置ExtensionProfile
1. 生成YAML文件。 
   YAML示例：
   ```
   apiVersion: bursting.cci.io/v1
   kind: ExtensionProfile
   metadata:
     name: test-profile
   spec:
     actions:
       annotations: #给Pod追加Annotations
         annotation1: value1
       labels:      #给Pod追加Labels
         label1: value1
       imageReplacement:    #给Pod添加镜像地址转换策略
       - replaceWith: xxx.com/yyy
         repositoryPrefix: harbor.domain/a/b/c/d
       hostPathReplacement: #给Pod添加HostPath卷转换策略
       - emptyDir:
           sizeLimit: 10Gi
         name: volume1
         policyType: replaceByEmptyDir
       evictions:           #配置Pod磁盘压力驱逐策略
         - type: "Hard"        
           signal: "DiskPressure"  
       podSidecars:         #给Pod添加Sidecar
         containers:
         - image: nginx:latest
           name: nginx
           position: head
         volumes:
         - name: volume2
           configMap:
             name: configmap1
     objectLabels:
       matchLabels:
         k1: v1
     policy: addOnly
   ```
   
   
2. 使用以下命令创建配置。 
   ```
   kubectl apply -f <test-profile>     #所创建的YAML文件名，替换为实际值
   ```
   
   
3. （可选）使用以下命令查询是否配置成功。 
   ```
   kubectl get extp
   ```
   
   
 
#### spec配置说明
表1spec参数说明 
| 主要参数            | 参数说明                                                                                                                                                                                                                                                              |
|:---|:---|
| policy          | 支持配置策略为addOnly或override，如果某项配置与Pod原有定义冲突，配置为addOnly不会覆盖Pod原有定义，配置为override会覆盖Pod原有定义。默认配置为addOnly。                                                                                                                                                                |
| namespaceLabels | 用于根据命名空间的Label筛选命名空间。                                                                                                                                                                                                                                             |
| objectLabels    | 用于根据Pod的Label筛选Pod。 注意： matchLabels和matchExpressions的用法和匹配策略可参考K8S文档[官方文档](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#resources-that-support-set-based-requirements)。 |
   
#### actions参数说明：
表2actions主要参数说明： 
| 主要参数                | 参数说明                                                                                                                                                       |
|:---|:---|
| annotations         | 用于给Pod追加Annotations。                                                                                                                                       |
| labels              | 用于给Pod追加Labels。                                                                                                                                            |
| imageReplacement    | 结构化配置，详情请参见[镜像地址转换策略](https://support.huaweicloud.com/usermanual-cci2/cci_01_0028.html#cci_01_0028__zh-cn_topic_0000001704663513_section10322175918207)。   |
| hostPathReplacement | 结构化配置，详情请参见[Hostpath卷转换策略](https://support.huaweicloud.com/usermanual-cci2/cci_01_0029.html#cci_01_0029__zh-cn_topic_0000001704622777_section84194417184)。 |
| evictions           | 用于配置Pod磁盘压力驱逐策略。                                                                                                                                           |
| podSidecars         | 用于给Pod添加[sidecar](https://support.huaweicloud.com/usermanual-cci2/cci_01_0128.html)。                                                                       |
   
表3imageReplacement参数说明 
| 替换规则key          | 字段含义                | 字段说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
|:---|:---|:---|
| repositoryPrefix | 用户希望被匹配并被替换的镜像前缀字段。 | - 该字段为空字符串("")，匹配所有image字段不含"/"的容器。  - 该字段不为空，匹配所有image字段最后一个"/"字符前缀相同的容器。  - 该字段字符校验规则与容器镜像名的规则一致，且不能以"/"字符结尾。   |
| replaceWith      | 用户希望替换成的镜像前缀字段。     | - 该字段字符不能与repositoryPrefix相同。  - 该字段字符校验规则与容器镜像名的规则一致，且不能以"/"字符结尾。                                                                                                                                                                                                   |
   
表4hostPathReplacement参数说明： 
| 主要参数       | 参数说明                                                                                                                                                                                                                                                |
|:---|:---|
| name       | pod中配置的hostPath的名称。                                                                                                                                                                                                                                 |
| policyType | remove：删除hostpath。 replaceByEmptyDir：替换为配置的emptydir，如将volume1替换为10Gi的emptyDir的配置如下： ``` hostPathReplacement: - emptyDir: sizeLimit: 10Gi name: volume1 policyType: replaceByEmptyDir ``` |
   
#### profile生效规则
- 仅会在Pod创建时对新建的Pod生效，不会修改已存在的Pod。
- 一个Pod最多生效一个ClusterExtensionProfile或一个ExtensionProfile，若两种类型的profile同时匹配，则先生效ClusterExtensionProfile，再生效ExtensionProfile。ExtensionProfile是在ClusterExtensionProfile已经生效的Pod基础上进行处理，若ExtensionProfile配置为"addOnly"，且ExtensionProfile和ClusterExtensionProfile均配置了相关的action，则：
  - 对于"labels"、"annotations"仅不同键名会生效。
  
  - 对于"imageReplacement"、"hostPathReplacement"、"evictions"、"podSidecars"均不会生效。
  
  
  例如：pod匹配到以下名为cextp1的ClusterExtensionProfile和名为extp1的ExtensionProfile，因为extp1的policy是"addOnly"，则extp1配置的hostpath转换策略不会生效，annotations中因为cextp-1已配置了k1的键，则extp1配置的k1:v2不会生效。最终Pod采用annotations: k1:v1、k2:v2、k3:v3和cextp1中的hostPathReplacement。
  ```
  apiVersion: bursting.cci.io/v1
  kind: ClusterExtensionProfile
  metadata:
    name: cextp1
  spec:
    actions:
      annotations:
        k1: v1
        k2: v2
      hostPathReplacement:
      - emptyDir:
          sizeLimit: 10Gi
        name: hostpath-1
        policyType: replaceByEmptyDir
      ...
    policy: addOnly
  ---
  apiVersion: bursting.cci.io/v1
  kind: ExtensionProfile
  metadata:
    name: extp1
    namespace: default
  spec:
    actions:
      annotations:
        k1: v2
        k3: v3
      hostPathReplacement:
      - name: '*'
        policyType: remove
      ...
    policy: addOnly
  ```
  
- 若Pod所在Namespace的Labels能被多个ClusterExtensionProfile匹配，仅会生效一个最精确匹配的profile。
- 若Pod的Labels能被多个ExtensionProfile匹配，仅会生效一个最精确匹配的一个profile。
- 最精确匹配的定义：
  - profile的objectLabels或namespaceLabels中所有matchLabels和matchExpression的数量之和大的更精确。
  
  - 数量一样的选择profile name字母序最小的。
   
 
#### 支持磁盘压力后Pod驱逐
当磁盘空间不足的情况发生时，可能会影响业务的正常运行。基于Kubernetes的驱逐和调度机制，通过对指定的ClusterExtensionProfile或ExtensionProfile配置驱逐策略，实现磁盘压力后自动驱逐Pod。如果被驱逐的Pod由Deployment管理，Deployment会自动创建新的Pod。
![](https://support.huaweicloud.com/usermanual-cci2/zh-cn_image_0000002227449560.png "点击放大")
在对应的ClusterExtensionProfile或ExtensionProfile增加内容如下，实现配置Pod驱逐策略：
```
actions:    
    evictions:      #仅支持配置type为Hard且signal为DiskPressure
      - type: "Hard"        
        signal: "DiskPressure"
```
- 方式一：通过ClusterExtensionProfile配置指定命名空间标签的Pod驱逐策略
  ```
  apiVersion: bursting.cci.io/v1
  kind: ClusterExtensionProfile
  metadata:  
    name: eviction-cluster-profile
  spec:  
    actions:    
      evictions:      
        - type: "Hard"        
          signal: "DiskPressure"  
    namespaceLabels:    
      matchLabels:      
          key: value
  ```
  
- 方式二：通过ExtensionProfile配置在特定命名空间下的指定Label标识的Pod驱逐策略
  ```
  apiVersion: bursting.cci.io/v1
  kind: ExtensionProfile
  metadata:  
    name: eviction-cluster-profile
    namespace: default
  spec:  
    actions:    
      evictions:      
        - type: "Hard"        
          signal: "DiskPressure"  
    objectLabels:
      matchExpressions:
      - key: key2
        operator: In
        values:
        - v2
        - v3
      - key: key3
        operator: Exists
      matchLabels:
        key1: value1
    policy: addOnly
  ```
  
 
#### 驱逐原理
在配置了磁盘压力驱逐策略后，CCE突发弹性引擎（对接 CCI）插件根据从CCI同步的Pod状态中的NodeFsDiskPressure、ImageFsDiskPressure的condition，对ClusterExtensionProfile或者ExtensionProfile匹配到的Pod进行驱逐。
在未使用[镜像快照](https://support.huaweicloud.com/usermanual-cci2/cci_01_0111.html)的场景下，当pod磁盘空间小于100MiB时，会为Pod上报NodeFsDiskPressure的Condition；在使用镜像快照的场景下，当pod临时存储磁盘空间小于100MiB时或容器镜像磁盘空间小于100MiB时，会分别上报NodeFsDiskPressure或ImageFsDiskPressure的Condition。当pod临时存储磁盘空大于100MiB时或容器镜像磁盘空间大于100MiB时，对应的Condition会被移除。
![](https://support.huaweicloud.com/usermanual-cci2/zh-cn_image_0000002455737905.png "点击放大")
