使用资源重写来自定义由 Azure Kubernetes Fleet Manager 资源放置所部署的资源

适用于: ✔️具有中心群集的 Fleet Manager

Azure Kubernetes Fleet Manager 智能资源放置可用于将同一资源部署到队列中的多个群集。 通常,需要修改资源配置,以在不同的环境(开发、测试、生产)中强制实施有关行为的规则。 为此,Fleet Manager 提供了资源替代,该功能在概念上类似于 Helm 模板和 Kustomize 修补程序的使用方式。

修改资源配置的示例包括:

  • 我想在所有群集上使用一个ClusterRole命名secret-reader,但在生产群集上,该角色的允许的操作范围更小。
  • 我想在所有群集上使用相同 Deployment ,但在生产群集上使用其他容器映像或端口。

本文介绍如何为由 Fleet Manager 资源放置所部署的资源创建覆盖配置。

Azure Kubernetes Fleet Manager 支持两个替代范围:

  • 群集范围ClusterResourceOverrideClusterResourcePlacement 用于管理基础设施级更改的集群管理员。
  • 命名空间范围:用于ResourceOverrideResourcePlacement管理其特定命名空间内推出的应用程序团队。

可以从文章顶部的范围类型选项中选择最适用的范围。

群集范围的资源替代

ClusterResourceOverride 具有以下属性:

  • clusterResourceSelectors:指定为重写选择的群集资源集。
  • policy:指定要应用于所选群集资源的规则集。

注释

Policy 对于群集和命名空间范围内的资源,定义是相同的。

让我们使用名为ClusterRolesecret-reader示例来演示ClusterResourceOverride的工作原理。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

选择群集资源

可以在ClusterResourceOverride中包含一个或多个clusterResourceSelector资源以选择需要替代的资源。 每个 clusterResourceSelector 字段都支持以下字段。

  • group:资源的 API 组。
  • version:资源的 API 版本。
  • kind:资源的种类。
  • name:资源的名称。

注释

如果选择命名空间 ClusterResourceSelector,替代将应用于命名空间中的所有资源。

使用我们的示例 ClusterRole,让我们看看如何在一个 ClusterResourceOverride示例中选择它。

apiVersion: placement.kubernetes-fleet.io/v1
kind: ClusterResourceOverride
metadata:
  name: example-cro
spec:
  clusterResourceSelectors:
    - group: rbac.authorization.k8s.io
      kind: ClusterRole
      version: v1
      name: secret-reader

命名空间范围的资源替代(预览版)

ResourceOverride 具有以下属性:

  • resourceSelectors:指定要覆盖的资源集。
  • policy:指定要应用于所选资源的规则集。

注释

Policy 对于群集和命名空间范围内的资源,定义是相同的。

让我们使用名为Deploymentnginx-sample示例来演示ResourceOverride的工作原理。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-sample
  namespace: nginx-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.25
          ports:
            - containerPort: 80

选择命名空间资源

可以在ResourceOverride中包含一个或多个resourceSelector资源以选择需要替代的资源。 每个 resourceSelector 字段都支持以下字段。

  • group:资源的 API 组。
  • version:资源的 API 版本。
  • kind:资源的种类。
  • name:资源的名称。

要重写的资源的命名空间是通过在namespacemetadata中指定的ResourceOverride集合来确定的。

使用我们的示例 Deployment,让我们看看如何在一个 ResourceOverride示例中选择它。

apiVersion: placement.kubernetes-fleet.io/v1
kind: ResourceOverride
metadata:
  name: example-resource-override
  namespace: nginx-demo
spec:
  resourceSelectors:
    -  group: apps
       kind: Deployment
       version: v1
       name: nginx-sample

重要

  • 如果在resourceSelectorkind: Namespace)中选择一个命名空间,则该重写将应用于命名空间中的所有资源。
  • 需要 ResourceOverride 与要重写的资源位于同一命名空间中。

现在我们已经选择了资源。 让我们看看如何使用 policy 来配置覆盖。

Policy

policy 组成的一组 overrideRules 用于指定要应用于所选资源的更改。 各个 overrideRules 支持以下字段:

  • clusterSelector:指定替代规则应用到的群集集。
  • jsonPatchOverrides:指定要应用于所选资源的更改。

群集选择器

可以使用 clusterSelectoroverrideRules 字段来指定规则适用的群集。 clusterSelector 支持以下字段:

  • clusterSelectorTerms:指定选择群集的条件的术语列表。 每个术语都包含一个 labelSelector 字段,用于定义一组要匹配的标签。

重要

labelSelectorclusterSelectorTerms 字段中受支持。

JSON 补丁覆盖

您可以在jsonPatchOverridesoverrideRules中指定要应用于所选资源的“更改”。 该 JsonPatch 属性支持以下字段:

  • op:要执行的操作。 支持的操作包括:

    • add:向指定路径添加新值。
    • remove:删除指定路径处的值。
    • replace:替换指定路径处的值。
  • path:要修改的字段的路径。 有关指定路径的指南包括:

    • 必须以斜杠 (/) 字符开头。
    • 不能为空或包含空字符串。
    • 不能是字段 TypeMeta/kind/apiVersion)。
    • 不能是 Metadata 字段(/metadata/name/metadata/namespace),但可以是字段 /metadata/labels/metadata/annotations
    • 不能是资源状态中的任何字段。

    有效路径的示例包括:

    • /metadata/labels/new-label
    • /metadata/annotations/new-annotation
    • /spec/template/spec/containers/0/resources/limits/cpu
    • /spec/template/spec/containers/0/resources/requests/memory
  • value:要添加、删除或替换的值。 op如果是remove,则无法指定value

这些 jsonPatchOverrides 字段遵循 RFC 6902 对所选资源应用 JSON 修补程序。

在扩展我们示例的过程中,我们配置了一个policy,以从list中名为ClusterRole且标有secret-reader标签的群集上删除env:prod动词。

apiVersion: placement.kubernetes-fleet.io/v1
kind: ClusterResourceOverride
metadata:
  name: example-cro
spec:
  clusterResourceSelectors:
    - group: rbac.authorization.k8s.io
      kind: ClusterRole
      version: v1
      name: secret-reader
  policy:
    overrideRules:
      - clusterSelector:
          clusterSelectorTerms:
            - labelSelector:
                matchLabels:
                  env: prod
        jsonPatchOverrides:
          - op: remove
            path: /rules/0/verbs/2

扩展示例后,我们将配置policy,以将Deployment容器镜像替换为nginx:1.30.0镜像,适用于具有env: prod标签的群集。

apiVersion: placement.kubernetes-fleet.io/v1
kind: ResourceOverride
metadata:
  name: example-resource-override
  namespace: test-namespace
spec:
  resourceSelectors:
    -  group: apps
       kind: Deployment
       version: v1
       name: test-nginx
  policy:
    overrideRules:
      - clusterSelector:
          clusterSelectorTerms:
            - labelSelector:
                matchLabels:
                  env: prod
        jsonPatchOverrides:
          - op: replace
            path: /spec/template/spec/containers/0/image
            value: "nginx:1.30.0"

定义多个替代

可以添加多个 jsonPatchOverrides 字段,以便 overrideRules 对所选群集资源应用多个更改。 下面是一个示例:

本示例删除了在具有标签ClusterRole的群集中的名为secret-readerenv: prod的样本中的谓词“list”和“watch”。

apiVersion: placement.kubernetes-fleet.io/v1
kind: ClusterResourceOverride
metadata:
  name: cro-1
spec:
  clusterResourceSelectors:
    - group: rbac.authorization.k8s.io
      kind: ClusterRole
      version: v1
      name: secret-reader
  policy:
    overrideRules:
      - clusterSelector:
          clusterSelectorTerms:
            - labelSelector:
                matchLabels:
                  env: prod
        jsonPatchOverrides:
          - op: remove
            path: /rules/0/verbs/2
          - op: remove
            path: /rules/0/verbs/1

此示例在带有 Deployment 标签的群集内,将容器映像和端口 443 替换为 env: prod

apiVersion: placement.kubernetes-fleet.io/v1
kind: ResourceOverride
metadata:
  name: example-resource-override
  namespace: test-namespace
spec:
  resourceSelectors:
    -  group: apps
       kind: Deployment
       version: v1
       name: test-nginx
  policy:
    overrideRules:
      - clusterSelector:
          clusterSelectorTerms:
            - labelSelector:
                matchLabels:
                  env: prod
        jsonPatchOverrides:
          - op: replace
            path: /spec/template/spec/containers/0/image
            value: "nginx:1.30.0"
          - op: replace
            path: /spec/template/spec/containers/0/ports/0/containerPort
            value: "443"

JSON 修补程序重写值中的保留变量

保留变量在位置处由 JSON 补丁覆盖规则的 value 替换。 当前支持的保留变量:

  • ${MEMBER-CLUSTER-NAME}:替换为memberCluster的名称。

例如,若要创建包含群集名称的 Azure DNS 主机名,该示例ResourceOverride会在 Azure 区域中的群集fleet-clustername-chinanorth3上添加一个值eastus

apiVersion: placement.kubernetes-fleet.io/v1
kind: ResourceOverride
metadata:
  name: ro-kuard-demo-chinanorth3
  namespace: kuard-demo
spec:
  placement:
    name: crp-kuard-demo
  resourceSelectors:
    -  group: ""
        kind: Service
        version: v1
        name: kuard-svc
  policy:
    overrideRules:
      - clusterSelector:
          clusterSelectorTerms:
            - labelSelector:
                matchLabels:
                  fleet.azure.com/location: chinanorth3
        jsonPatchOverrides:
          - op: add
            path: /metadata/annotations
            value:
              {"service.beta.kubernetes.io/azure-dns-label-name":"fleet-${MEMBER-CLUSTER-NAME}-chinanorth3"}

多个替代规则

可以将多个 overrideRules 添加到 policy 字段,以便对所选资源应用多个更改。 这是一个针对ResourceOverride的示例。

此示例将在 Deployment 中的容器镜像替换为:

  • 带有nginx:1.20.0标签的env: prod群集的图像。
  • 带有nginx:latest标签的env: test群集的图像。
apiVersion: placement.kubernetes-fleet.io/v1
kind: ResourceOverride
metadata:
  name: ro-1
  namespace: test
spec:
  resourceSelectors:
    -  group: apps
       kind: Deployment
       version: v1
       name: test-nginx
  policy:
    overrideRules:
      - clusterSelector:
          clusterSelectorTerms:
            - labelSelector:
                matchLabels:
                  env: prod
        jsonPatchOverrides:
          - op: replace
            path: /spec/template/spec/containers/0/image
            value: "nginx:1.20.0"
      - clusterSelector:
          clusterSelectorTerms:
            - labelSelector:
                matchLabels:
                  env: test
        jsonPatchOverrides:
          - op: replace
            path: /spec/template/spec/containers/0/image
            value: "nginx:latest"

与群集资源放置配合使用

  1. 创建一个 ClusterResourcePlacement 以指定用于跨群集基础结构分布群集资源替代的放置规则。 以下代码是一个示例。 请务必选择适当的资源。

    apiVersion: placement.kubernetes-fleet.io/v1
    kind: ClusterResourcePlacement
    metadata:
      name: crp
    spec:
      resourceSelectors:
        - group: rbac.authorization.k8s.io
          kind: ClusterRole
          version: v1
          name: secret-reader
      policy:
        placementType: PickAll
        affinity:
          clusterAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
              clusterSelectorTerms:
                - labelSelector:
                    matchLabels:
                      env: prod
    

    此示例将资源分布到标记 env: prod的所有群集中。 实现更改后,相应的 ClusterResourceOverride 配置将应用于指定的群集。 选择匹配的群集角色资源secret-reader会触发对群集进行配置应用。

  2. ClusterResourcePlacement,使用kubectl apply命令应用。

    kubectl apply -f cluster-resource-placement.yaml
    
  3. 通过ClusterResourceOverride命令检查ClusterResourcePlacement资源的状态,以验证kubectl describe是否已应用于所选资源。

    kubectl describe clusterresourceplacement crp
    

    输出应类似于以下示例:

    Status:
      Conditions:
        ...
        Last Transition Time:   2024-04-27T04:18:00Z
        Message:                The selected resources are successfully overridden in the 10 clusters
        Observed Generation:    1
        Reason:                 OverriddenSucceeded
        Status:                 True
        Type:                   ClusterResourcePlacementOverridden
        ...
      Observed Resource Index:  0
      Placement Statuses:
        Applicable Cluster Resource Overrides:
          example-cro-0
        Cluster Name:  member-50
        Conditions:
          ...
          Message:               Successfully applied the override rules on the resources
          Observed Generation:   1
          Reason:                OverriddenSucceeded
          Status:                True
          Type:                  Overridden
         ...
    

    ClusterResourcePlacementOverridden 条件指示是否已成功将资源替代应用于群集中的所选资源。 每个群集维护自己的 Applicable Cluster Resource Overrides 列表。 此列表包含群集资源替代的快照(如果相关)。 每个群集的单个状态消息指示是否已成功应用替代规则。

与资源放置一起使用

  1. 创建一个 ClusterResourcePlacement 资源,以指定用于跨群集基础结构分配资源替代的放置规则。 以下代码是一个示例。 请务必选择适当的命名空间。

    apiVersion: placement.kubernetes-fleet.io/v1
    kind: ClusterResourcePlacement
    metadata:
      name: crp-example
    spec:
      resourceSelectors:
        - group: ""
          kind: Namespace
          name: test-namespace
          version: v1
      policy:
        placementType: PickAll
        affinity:
          clusterAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
              clusterSelectorTerms:
                - labelSelector:
                    matchLabels:
                      env: prod
                - labelSelector:
                    matchLabels:
                      env: test
    

    在所有标记为test-namespaceenv:prod的群集中分配env:test内的资源。 实现更改后,相应的 ResourceOverride 配置将应用于指定的资源。 选择匹配的部署资源时 my-deployment,会触发将配置的应用程序应用到指定的资源。

  2. 使用命令ClusterResourcePlacement来应用kubectl apply资源。

    kubectl apply -f cluster-resource-placement.yaml
    
  3. 通过ResourceOverride命令检查ClusterResourcePlacement资源的状态,以验证kubectl describe是否已应用于所选资源。

    kubectl describe clusterresourceplacement crp-example
    

    输出应类似于以下示例:

    Status:
      Conditions:
        ...
        Message:                The selected resources are successfully overridden in the 10 clusters
        Observed Generation:    1
        Reason:                 OverriddenSucceeded
        Status:                 True
        Type:                   ClusterResourcePlacementOverridden
        ...
      Observed Resource Index:  0
      Placement Statuses:
        Applicable Resource Overrides:
          Name:        ro-1-0
          Namespace:   test-namespace
        Cluster Name:  member-50
        Conditions:
          ...
          Last Transition Time:  2024-04-26T22:57:14Z
          Message:               Successfully applied the override rules on the resources
          Observed Generation:   1
          Reason:                OverriddenSucceeded
          Status:                True
          Type:                  Overridden
         ...
    

    ClusterResourcePlacementOverridden 条件指示是否已成功将资源替代应用于所选资源。 每个群集维护自己的 Applicable Resource Overrides 列表。 此列表包含资源替代快照(如果相关)。 每个群集的单个状态消息指示是否已成功应用替代规则。