
# 差异化策略 OverridePolicy
#### 概述
OverridePolicy是UCS集群联邦的核心 API 之一，用于定义将一组资源分发到一个或多个目标集群时需要进行差异化修改的策略。它允许在保持资源核心配置不变的前提下，针对不同集群环境进行灵活的配置调整。
差异化策略 OverridePolicy具有以下核心特性：
- **多集群覆盖**：支持将配置差异覆盖到多个目标集群
- **多种覆盖器**：提供镜像、标签、注解、命令、参数和通用明文覆盖
- **灵活选择**：支持通过标签、字段、名称等方式选择目标集群
- **分层策略**：支持命名空间级别和集群级别的差异化策略
差异化策略 OverridePolicy相关类型如下：
- **OverridePolicy:** 用于命名空间作用域的资源差异化修改。详情可参见[什么是命名空间作用域的资源?](https://kubernetes.io/zh-cn/docs/reference/using-api/api-concepts/)
- **ClusterOverridePolicy:** 支持集群作用域的资源差异化修改，包括PersistentVolume、StorageClass、CustomResourceDefinition，也支持任意命名空间（不包括系统命名空间）的差异化修改。详情可参见[什么集群作用域的资源?](https://kubernetes.io/zh-cn/docs/reference/using-api/api-concepts/)
差异化策略 OverridePolicy与分发策略 PropagationPolicy的区别：
- **PropagationPolicy**：定义资源如何分发到集群
- **OverridePolicy**：定义资源分发到集群后的差异化配置
 
#### API规范
基本信息：
```
apiVersion: policy.karmada.io/v1alpha1
kind: OverridePolicy  # ClusterOverridePolicy
```
作用范围：
- **OverridePolicy**: 命名空间级别，只能差异化修改所在命名空间的资源
- **ClusterOverridePolicy**: 集群级别，可差异化修改集群级别资源和任意命名空间的资源
 
#### 资源格式
**OverridePolicy YAML 模板：**
```
apiVersion: policy.karmada.io/v1alpha1
kind: OverridePolicy
metadata:
  name: <string>
  namespace: <string>
spec:
  resourceSelectors: <[]ResourceSelector>
  overrideRules: <[]RuleWithCluster>
```
**ClusterOverrid** **ePolicy YAML 模板：**
```
apiVersion: policy.karmada.io/v1alpha1
kind: ClusterOverridePolicy
metadata:
  name: <string>
spec:
  resourceSelectors: <[]ResourceSelector>
  overrideRules: <[]RuleWithCluster>
```
#### 参数详细说明
1. **metadata** ：标准的Kubernetes资源元数据。包含以下字段：
   - name：OverridePolicy名称
   
   - namespace：所在命名空间（仅 OverridePolicy 需要）
   
   - labels：标签选择器
   
   - annotations：注解信息
    

2. **spec** ：OverridePolicy的规范部分，包含以下字段：
   - **resourceSelectors (必需)** ：选择资源此覆盖策略的资源集合：
     ```
     resourceSelectors:
     - apiVersion: <string>          # 目标资源API版本，如 "apps/v1"
       kind: <string>                # 目标资源类型，如 "Deployment"
       namespace: <string>           # 目标资源命名空间（可选）
       name: <string>                # 目标资源名称（可选）
       labelSelector:                # 标签选择器
         matchLabels: <map[string]string>
         matchExpressions: <[]LabelSelectorRequirement>
     ```
     
   
   - **overrideRules** ：定义覆盖规则数组，推荐的覆盖规则定义方式：
     ```
     overrideRules:
     - targetCluster: <ClusterAffinity>    # 目标集群选择
       overriders: <Overriders>             # 覆盖规则
     ```
     
    
 
#### 覆盖器类型
1. 镜像覆盖器 (imageOverrider)：用于修改容器镜像的各个组件。
```
imageOverrider:
- component: <string>          # 镜像组件: registry, repository, tag
  operator: <string>           # 操作: add, remove, replace
  predicate:                   # 镜像过滤条件（可选）
    path: <string>             # 镜像字段路径，如 "/spec/template/spec/containers/0/image"
  value: <string>              # 新值（add/replace时必需）
```
**支持的操作** ：
- add：添加新的镜像组件
- remove：删除镜像组件
- replace：替换镜像组件 **支持的组件**：
  
- registry：镜像注册表部分
- repository：镜像仓库部分
- tag：镜像标签部分
 
2. 标签覆盖器 (labelsOverrider)：用于修改工作负载的标签。
```
labelsOverrider:
- operator: <string>           # 操作: add, remove, replace
  value: <map[string]string>   # 标签键值对
```
3. 注解覆盖器 (annotationsOverrider)：用于修改工作负载的注解。
```
annotationsOverrider:
- operator: <string>           # 操作: add, remove, replace
  value: <map[string]string>   # 注解键值对
```
4. 命令覆盖器 (commandOverrider)：用于修改容器的启动命令。
```
commandOverrider:
- containerName: <string>      # 容器名称（必需）
  operator: <string>           # 操作: add, remove
  value: <[]string>            # 命令数组
```
5. 参数覆盖器 (argsOverrider)：用于修改容器的启动参数。
```
argsOverrider:
- containerName: <string>      # 容器名称（必需）
  operator: <string>           # 操作: add, remove
  value: <[]string>            # 参数数组
```
6. 明文覆盖器 (plaintext)：通过JSON Patch方式修改任意字段。
```
plaintext:
- operator: <string>           # 操作: add, remove, replace
  path: <string>               # 目标字段路径，如 "/spec/replicas"
  value: <interface{}>         # 新值（remove时可为空）
```
**支持的value类型** ：
- bool：布尔值
- int64：64位整数
- float64：64位浮点数
- string：字符串
- \[\]interface{}：数组
- map\[string\]interface{}：对象
- nil：空值
 
#### 集群选择机制
**ClusterAffinity 结构**
```
clusterNames: <[]string>       # 集群名称列表
exclude: <[]string>            # 排除的集群名称列表
fieldSelector:                 # 字段选择器
  matchExpressions: <[]LabelSelectorRequirement>
labelSelector:                 # 标签选择器
  matchLabels: <map[string]string>
  matchExpressions: <[]LabelSelectorRequirement>
```
**选择方式**
1. 集群名称选择
```
targetCluster:
  clusterNames:
  - "cluster-1"
  - "cluster-2"
  exclude:
  - "cluster-3"
```
2. 字段选择器
```
targetCluster:
  fieldSelector:
    matchExpressions:
    - key: provider
      operator: In
      values: ["aws", "azure"]
    - key: region
      operator: NotIn
      values: ["cn-north-1"]
```
3. 标签选择器
```
targetCluster:
  labelSelector:
    matchLabels:
      environment: production
    matchExpressions:
    - key: tier
      operator: In
      values: ["frontend", "backend"]
```
#### 应用顺序
覆盖器的应用顺序严格遵循以下优先级：
1. **ImageOverrider** - 镜像覆盖器首先应用
2. **CommandOverrider** - 命令覆盖器
3. **ArgsOverrider** - 参数覆盖器
4. **LabelsOverrider** - 标签覆盖器
5. **AnnotationsOverrider** - 注解覆盖器
6. **Plaintext** - 明文覆盖器最后应用
   ![](https://support.huaweicloud.com/api-ucs/public_sys-resources/caution_3.0-zh-cn.png)
   此顺序确保更具体的覆盖（如镜像）先于通用覆盖（如明文）应用。
   
 
#### 使用示例
**示例1：基础镜像覆盖**
```
apiVersion: policy.karmada.io/v1alpha1
kind: OverridePolicy
metadata:
  name: image-override-demo
  namespace: demo
spec:
  resourceSelectors:
  - apiVersion: apps/v1
    kind: Deployment
    namespace: demo
    name: nginx-app
  overrideRules:
  - targetCluster:
      clusterNames:
      - "cluster-beijing"
      - "cluster-shanghai"
    overriders:
      imageOverrider:
      - component: registry
        operator: replace
        value: "registry.internal.com"
      - component: tag
        operator: replace
        value: "v1.0.0"
```
**示例2：多集群差异化配置**
```
apiVersion: policy.karmada.io/v1alpha1
kind: OverridePolicy
metadata:
  name: multi-cluster-config
  namespace: production
spec:
  resourceSelectors:
  - apiVersion: apps/v1
    kind: Deployment
    namespace: production
    labelSelector:
      matchLabels:
        app: web-service
  overrideRules:
  # 生产集群配置
  - targetCluster:
      labelSelector:
        matchLabels:
          environment: production
    overriders:
      imageOverrider:
      - component: registry
        operator: replace
        value: "registry.internal.com"
      plaintext:
      - operator: replace
        path: "/spec/replicas"
        value: 10
      labelsOverrider:
      - operator: add
        value:
          monitoring: "enabled"
          version: "stable"
  # 测试集群配置
  - targetCluster:
      labelSelector:
        matchLabels:
          environment: testing
    overriders:
      plaintext:
      - operator: replace
        path: "/spec/replicas"
        value: 2
      labelsOverrider:
      - operator: add
        value:
          monitoring: "disabled"
          version: "beta"
```
**示例3：容器命令覆盖**
```
apiVersion: policy.karmada.io/v1alpha1
kind: OverridePolicy
metadata:
  name: command-override
  namespace: backend
spec:
  resourceSelectors:
  - apiVersion: apps/v1
    kind: StatefulSet
    namespace: backend
    name: redis-cluster
  overrideRules:
  - targetCluster:
      clusterNames:
      - "high-perf-cluster"
    overriders:
      commandOverrider:
      - containerName: "redis"
        operator: replace
        value: ["redis-server", "--maxmemory", "4gb", "--maxmemory-policy", "allkeys-lru"]
      argsOverrider:
      - containerName: "redis"
        operator: add
        value: ["--appendonly", "yes"]
```
**示例4：标签和注解覆盖**
```
apiVersion: policy.karmada.io/v1alpha1
kind: OverridePolicy
metadata:
  name: labels-annotations-demo
  namespace: app
spec:
  resourceSelectors:
  - apiVersion: apps/v1
    kind: Deployment
    namespace: app
  overrideRules:
  - targetCluster:
      fieldSelector:
        matchExpressions:
        - key: region
          operator: In
          values: ["us-west", "us-east"]
    overriders:
      labelsOverrider:
      - operator: add
        value:
          deployment-zone: "us"
          cost-optimized: "true"
      - operator: replace
        value:
          team: "us-team"
      annotationsOverrider:
      - operator: add
        value:
          deployment.kubernetes.io/revision: "1"
          prometheus.io/scrape: "true"
          prometheus.io/port: "8080"
```
**示例5：复杂明文覆盖**
```
apiVersion: policy.karmada.io/v1alpha1
kind: OverridePolicy
metadata:
  name: complex-plaintext-override
  namespace: infrastructure
spec:
  resourceSelectors:
  - apiVersion: apps/v1
    kind: DaemonSet
    namespace: kube-system
    name: "node-exporter"
  overrideRules:
  - targetCluster:
      labelSelector:
        matchLabels:
          node-type: "worker"
    overriders:
      plaintext:
      # 修改副本数
      - operator: replace
        path: "/spec/updateStrategy/type"
        value: "RollingUpdate"
      # 修改环境变量
      - operator: add
        path: "/spec/template/spec/containers/0/env"
        value:
        - name: "NODE_NAME"
          valueFrom:
            fieldRef:
              fieldPath: "spec.nodeName"
      # 修改资源配置
      - operator: replace
        path: "/spec/template/spec/containers/0/resources"
        value:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"
```
