从 Policy Controller 迁移

本文档介绍了如何从 Policy Controller 迁移准入政策,以降低政策执行出现漏洞的风险。Policy Controller 将于 2026 年 11 月 12 日弃用,并于 2027 年 12 月 31 日停止支持。在 1.39 及更高版本中,Google Kubernetes Engine (GKE) 集群不支持 Policy Controller。

您可以将使用 Policy Controller 强制执行的准入政策迁移到 Kubernetes ValidatingAdmissionPolicies 或自行管理的 Open Policy Agent (OPA) Gatekeeper。迁移不会影响已在运行的工作负载。Policy Controller 会评估创建或更新资源的请求,因此移除它不会重启或更改正在运行的工作负载。

本文档适用于在舰队中管理 Policy Controller 的运维人员和安全专家。如需详细了解我们在Google Cloud 内容中提及的常见角色和示例任务,请参阅常见的 GKE 用户角色和任务。

已屏蔽升级到 GKE 1.39 版

对于已安装 Policy Controller 的集群,GKE 会阻止升级到 1.39 及更高版本。在将集群升级到 1.39 版之前,请迁移政策并从该集群中移除 Policy Controller。在迁移政策之前,请勿仅为了解除升级屏蔽而移除 Policy Controller,因为这样做会导致集群没有政策强制执行。

选择替换照片

评估 Policy Controller 中的每个准入政策,并从下表中为该政策选择一个替换选项。您不必为整个集群选择一个替代方案。您可以根据每项政策的要求,在同一集群上组合使用这些选项:

Policy Controller 替换选项对比
选项 何时使用 运营和支持
ValidatingAdmissionPolicy(推荐) 在创建或更新单个资源时检查该资源的政策。 Policy Controller 模板库中的大多数模板都以这种方式运行。 ValidatingAdmissionPolicies 内置于 Kubernetes 中,可在 GKE 1.30 版及更高版本中使用,无需额外付费。 Cloud Customer Care 支持将 ValidatingAdmissionPolicies 作为 GKE 的一部分。
Pod 安全准入(推荐用于 Pod 安全软件包) pss-baseline-v2022、pss-restricted-v2022 或 psp-v2022 软件包中预定义的 Pod 安全控制。如需了解详情,请参阅将 Pod 安全准入用于 Pod 安全包。 Pod 安全准入内置于 Kubernetes 中,默认在 GKE 中启用,无需额外付费。 客户服务支持将 Pod 安全准入作为 GKE 的一部分。
自行管理的 OPA Gatekeeper ValidatingAdmissionPolicies 无法表达的政策,例如读取集群中其他资源的引用政策、您希望保留在 Rego 中的政策以及对现有资源的审核。您还可以向 Gatekeeper ConstraintTemplate 添加通用表达式语言 (CEL) 规则,以便 Gatekeeper 生成 ValidatingAdmissionPolicy 以供 API 服务器强制执行,并让其审核控制器检查现有资源。 您负责安装、升级和操作 Gatekeeper。客户服务不支持开源 Gatekeeper。Gatekeeper 社区通过 GitHub 提供支持。

盘点和分类政策

默认情况下,Policy Controller 模板库会安装每个模板,而政策包会使用 dryrun 违规处置措施安装其限制条件。因此,集群上的模板和限制条件不一定与您强制执行的政策相匹配。如需了解您强制执行的内容,请按以下步骤操作:

  1. 确定舰队中运行 Policy Controller 的集群:

    gcloud container fleet policycontroller describe \
        --project=PROJECT_ID
    

    将 PROJECT_ID 替换为您的舰队宿主项目的 ID。

  2. 在您确定的每个集群上,列出您的限制条件:

    kubectl get constraints \
        -o custom-columns='KIND:.kind,NAME:.metadata.name,'\
    'ACTION:.spec.enforcementAction,VIOLATIONS:.status.totalViolations,'\
    'BUNDLE:.metadata.labels.policycontroller\.gke\.io/bundleName'
    

    输出会显示每个限制条件的违规处置措施、最近一次审核中的违规次数,以及安装了该限制条件的任何软件包。ACTION 列中没有值的限制条件会使用默认的 deny 违规处置措施。

  3. 将 ConstraintTemplate 和限制条件备份到单独的文件中:

    kubectl get constrainttemplates -o yaml \
        > policy-controller-templates-backup.yaml
    kubectl get constraints -o yaml \
        > policy-controller-constraints-backup.yaml
    
  4. 可选:执行以下其他备份操作:

    • 如果您在 Policy Controller 中启用了参照规则,请备份同步配置:

      kubectl get config.config.gatekeeper.sh -n gatekeeper-system -o yaml \
          > policy-controller-config-backup.yaml
      
    • 如果您在 Policy Controller 中启用了变更,请备份变更器:

      kubectl get assign,assignmetadata,assignimage,modifyset -o yaml \
          > policy-controller-mutators-backup.yaml
      

请将这些备份文件保存在安全的地方。移除 Policy Controller 会删除集群上的每个 ConstraintTemplate、限制条件、同步配置和变更器,包括您创建的那些。您需要使用这些备份来转换或重新创建政策。

备份政策后,通过在下表中查看限制条件类型,确定每个限制条件的迁移路径:

按限制条件类型划分的迁移路径
限制条件类型 迁移路径
单资源限制条件 如果某项限制仅评估传入资源中的字段,而不读取 data.inventory,也不属于 Pod 安全包,则使用 ValidatingAdmissionPolicy。
未强制执行的 dryrun 限制条件 如果某项限制条件使用 dryrun 违规处置措施,而您不打算强制执行该限制条件,请删除该限制条件。
Pod 安全包限制条件 如果限制条件来自 pss-baseline-v2022、pss-restricted-v2022 或 psp-v2022 软件包,请使用 Pod 安全准入。对于 Pod 安全准入未涵盖的任何控制措施,请使用 ValidatingAdmissionPolicies。
参照限制条件 如果限制条件使用读取集群中其他资源的参照模板,请使用自行管理的 Gatekeeper。如需查找引用模板,请在备份文件中搜索 data.inventory 引用。
Cloud Service Mesh、Istio 或 Google Cloud限制条件 逐一查看限制条件,检查是否有内置 GKE 功能取代了该政策,或者备份文件中的 ConstraintTemplate 是否显示为 data.inventory。其中大多数模板仅检查传入资源,并在 ValidatingAdmissionPolicies 中运行,但引用 AsmAuthzPolicyDefaultDeny 和 AsmPeerAuthnMeshStrictMtls 模板除外,它们需要自行管理的 Gatekeeper。对于内置替换,请启用 Binary Authorization,而不是使用 K8sRequireBinAuthZ ConstraintTemplate,并配置节点池的节点映像,而不是使用 K8sRequireCosNodeImage ConstraintTemplate。

迁移到 ValidatingAdmissionPolicy

ValidatingAdmissionPolicy 包含政策逻辑,类似于 ConstraintTemplate。ValidatingAdmissionPolicyBinding 会应用政策,就像限制条件一样。ValidatingAdmissionPolicy 使用 CEL 表达式(而非 Rego),并且 API 服务器直接评估表达式,而无需使用网络钩子。

示例:允许的映像库

以下 Policy Controller 限制条件要求 Pod 使用来自一个 Artifact Registry 代码库的映像。它会排除 kube-system 命名空间:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sAllowedRepos
metadata:
  name: allowed-repos
spec:
  enforcementAction: deny
  match:
    kinds:
    - apiGroups: [""]
      kinds: ["Pod"]
    excludedNamespaces: ["kube-system"]
  parameters:
    repos:
    - "us-docker.pkg.dev/example-project/example-repo/"

以下 ValidatingAdmissionPolicy 和 ValidatingAdmissionPolicyBinding 强制执行相同的规则。ValidatingAdmissionPolicyBinding 使用 Warn 和 Audit 操作,以便您在强制执行 ValidatingAdmissionPolicy 之前比较结果:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: allowed-repos
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
    - apiGroups: [""]
      apiVersions: ["v1"]
      operations: ["CREATE", "UPDATE"]
      resources: ["pods", "pods/ephemeralcontainers"]
  variables:
  - name: repos
    expression: "['us-docker.pkg.dev/example-project/example-repo/']"
  - name: images
    expression: >-
      object.spec.containers.map(c, c.image) +
      (has(object.spec.initContainers) ?
        object.spec.initContainers.map(c, c.image) : []) +
      (has(object.spec.ephemeralContainers) ?
        object.spec.ephemeralContainers.map(c, c.image) : [])
  validations:
  - expression: >-
      variables.images.all(image,
        variables.repos.exists(repo, image.startsWith(repo)))
    messageExpression: >-
      'container images must come from one of these repositories: ' +
      variables.repos.join(', ')
    reason: Forbidden
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: allowed-repos
spec:
  policyName: allowed-repos
  validationActions: ["Warn", "Audit"]
  matchResources:
    namespaceSelector:
      matchExpressions:
      - key: kubernetes.io/metadata.name
        operator: NotIn
        values: ["kube-system", "gatekeeper-system"]

在此示例中,repos 变量存储来自限制条件的 parameters 字段的值。验证表达式会为符合 ValidatingAdmissionPolicy 的 Pod 返回 true 值,这与 Rego 违规规则相反。如需在提供不同值的多个 ValidatingAdmissionPolicyBinding 之间重复使用一个 ValidatingAdmissionPolicy,请使用参数资源,而不是变量。如需详细了解参数资源,请参阅 Kubernetes 文档中的参数资源。

下表显示了限制条件字段如何映射到 ValidatingAdmissionPolicy 和 ValidatingAdmissionPolicyBinding 字段:

Policy Controller 限制条件字段与 ValidatingAdmissionPolicy 和 ValidatingAdmissionPolicyBinding 字段的映射
限制条件字段 ValidatingAdmissionPolicy 或 ValidatingAdmissionPolicyBinding 字段
spec.enforcementAction ValidatingAdmissionPolicyBinding 中的 validationActions 字段,用于将 deny、warn 和 dryrun 操作映射到 ["Deny"]、["Warn"] 和 ["Audit"] 值
spec.parameters ValidatingAdmissionPolicy 中的 variables 字段,或 ValidatingAdmissionPolicyBinding 在 paramRef 字段中引用的参数资源
spec.match.kinds ValidatingAdmissionPolicy 中的 matchConstraints.resourceRules 字段,该字段使用 API 组和资源名称(例如 pods 资源),而不是种类
spec.match.namespaces 和 spec.match.excludedNamespaces ValidatingAdmissionPolicyBinding 中的 matchResources.namespaceSelector 字段,对 kubernetes.io/metadata.name 标签使用 In 或 NotIn 运算符
spec.match.labelSelector ValidatingAdmissionPolicyBinding 中的 matchResources.objectSelector 字段
spec.match.namespaceSelector ValidatingAdmissionPolicyBinding 中的 matchResources.namespaceSelector 字段
spec.match.scope 每个资源规则的 scope 字段

如需详细了解如何编写表达式,请参阅 Kubernetes 文档中的 Kubernetes 中的 CEL。

使用 Policy Controller 测试政策

如需在不中断强制执行的情况下替换限制条件,请在强制执行 ValidatingAdmissionPolicy 之前,在限制条件旁边运行 ValidatingAdmissionPolicy:

  1. 应用 ValidatingAdmissionPolicy 和具有 validationActions: ["Warn", "Audit"] 设置的 ValidatingAdmissionPolicyBinding。保留 Policy Controller 限制条件。
  2. 使用替换违规报告中的审核日志查询来比较结果。如果 ValidatingAdmissionPolicy 标记了 Policy Controller 允许的请求,或者反之,请修复 ValidatingAdmissionPolicy。对于与 Pod 匹配的 ValidatingAdmissionPolicies,请勿依赖警告。控制器会为 Deployment 和其他工作负载创建 Pod,因此控制器会收到警告。
  3. 结果匹配后,将 ValidatingAdmissionPolicyBinding 更改为使用 validationActions: ["Deny"] 设置。
  4. 删除 Policy Controller 限制条件。

针对行为差异做好规划

ValidatingAdmissionPolicies 在以下方面与 Policy Controller 的行为不同,这可能会阻止请求或在强制执行中留下漏洞:

  • 失败政策:Policy Controller webhook 故障开放,这意味着如果 Policy Controller 未响应,API 服务器会接受请求。如果表达式返回错误或超出 CEL 费用限制,则具有 failurePolicy: Fail 设置的 ValidatingAdmissionPolicy 会拒绝请求。如果引用的参数资源不存在,并且 ValidatingAdmissionPolicyBinding 中的 paramRef.parameterNotFoundAction 字段值为 Deny,ValidatingAdmissionPolicy 也会拒绝请求。如果值为 Allow,则无论 failurePolicy 设置如何,API 服务器都会跳过缺失的参数资源。测试每个 ValidatingAdmissionPolicy,并为这两个字段选择值。
  • 缺少字段:Rego 将缺少字段视为不违反,但 CEL 会返回错误。在读取可选字段之前,请使用 has() 宏检查该字段是否存在。
  • 豁免:ValidatingAdmissionPolicy 默认不会豁免命名空间,也不会使用 admission.gatekeeper.sh/ignore 标签。在 GKE Standard 集群上,ValidatingAdmissionPolicyBinding 适用于集群中的每个命名空间,包括 kube-system 命名空间等系统命名空间,除非您在 ValidatingAdmissionPolicyBinding 的 matchResources.namespaceSelector 字段中或 ValidatingAdmissionPolicy 的 matchConstraints.namespaceSelector 或 matchConditions 字段中排除它们。在 Autopilot 集群上,GKE 会自动排除代管式命名空间,并拒绝与 nodes、persistentVolumes、certificatesigningrequests 或 tokenreviews 资源匹配的 ValidatingAdmissionPolicy。如需了解详情,请参阅 GKE Autopilot 安全措施。
  • 子资源:Policy Controller 会检查添加临时容器的 Pod 更新。如需保留该覆盖范围,请在资源规则中添加 pods/ephemeralcontainers 子资源,如示例所示。
  • 不审核现有资源:ValidatingAdmissionPolicy 仅评估传入的 API 服务器请求。它不会报告违反 ValidatingAdmissionPolicy 的现有资源。
  • 每个请求一条消息:ValidatingAdmissionPolicy 会报告第一个失败的验证,而不是每个违规行为。

对 Pod 安全捆绑包使用 Pod 安全准入

如果您使用 pss-baseline-v2022 或 pss-restricted-v2022 软件包,请将软件包替换为 Pod 安全准入,而不是转换每个限制条件。Pod 安全准入使用内置 Kubernetes PodSecurity 准入控制器,根据命名空间标签强制执行 Kubernetes Pod 安全标准中的预定义规则。pss-baseline-v2022 软件包对应于 baseline 级别,pss-restricted-v2022 软件包对应于 restricted 级别。

Pod 安全准入不涵盖 psp-v2022 软件包中的每个控制,例如主机路径、用户、功能和 sysctl 的许可清单。请使用 ValidatingAdmissionPolicies 进行这些控制。Pod 安全准入也无法豁免特定映像,例如使用 exemptImages 参数的 Policy Controller 限制条件。GKE 不支持配置 Pod 安全准入豁免。如果您需要例外情况,请对受影响的政策使用 ValidatingAdmissionPolicies。

如需详细了解如何配置 Pod 安全准入,请参阅使用 PodSecurity 应用预定义的 Pod 级层安全政策。

迁移到自行管理的 OPA Gatekeeper

对于 ValidatingAdmissionPolicies 无法表达的政策,请选择 Gatekeeper。Policy Controller 基于 Gatekeeper,因此您的 ConstraintTemplate 和限制条件在 Gatekeeper 中使用相同的 API。Policy Controller 模板库中的所有模板都可在 Gatekeeper 中运行,而无需更改其逻辑。不过,Gatekeeper 使用更新的 Rego 引擎和更严格的验证,可能会拒绝自定义 ConstraintTemplate。

使用自行管理的 Gatekeeper 时,您需要负责Google Cloud 为 Policy Controller 执行的任务,例如在每个集群上安装、升级、伸缩和监控 Gatekeeper。客户服务不支持开源 Gatekeeper。如需帮助,请使用 Gatekeeper GitHub 问题跟踪器。

Gatekeeper 不包含 Policy Controller 模板库或政策包。备份文件包含集群中的 ConstraintTemplate 和限制条件。对于源自开源 Gatekeeper 库的模板,您可以使用 Gatekeeper 政策库中的模板。模板名称保持不变,但参数和消息可能因版本而异。

如需将政策移至 Gatekeeper,请按照以下步骤操作:

  1. 可选:如果您在替换 Policy Controller 时无法接受强制执行方面的空档期,请先将最重要的政策迁移到 ValidatingAdmissionPolicies。确保这些 ValidatingAdmissionPolicyBindings 排除 gatekeeper-system 命名空间,以免它们阻止 Gatekeeper 安装作业。移除 Policy Controller 后,您的集群将停止强制执行 Gatekeeper 政策,直到您应用相应的 Gatekeeper 限制条件。ValidatingAdmissionPolicies 会继续强制执行,因为它们不依赖于 Policy Controller 或 Gatekeeper。
  2. 如果您使用自定义 ConstraintTemplate,请使用您计划安装的 Gatekeeper 版本中的 gator 命令行工具测试每个自定义模板清单:

    gator test --filename=TEMPLATE_FILE
    

    将 TEMPLATE_FILE 替换为 ConstraintTemplate 清单文件的路径。在移除 Policy Controller 之前,请先修复 Gatekeeper 拒绝的所有自定义 ConstraintTemplate。

  3. 如果您使用 GitOps 工具从 Git 代码库部署约束条件,请准备约束条件使用的 ConstraintTemplate,并在安装 Gatekeeper 时将其添加到代码库中。否则,在您移除 Policy Controller 后,您的限制条件将无法应用,因为其 ConstraintTemplate 不再存在。

  4. 按照移除 Policy Controller 中的步骤移除 Policy Controller。请勿在仍在运行 Policy Controller 的集群上安装 Gatekeeper。它们都使用 gatekeeper-system 命名空间、相同的 CustomResourceDefinition 和相同的网络钩子名称。

  5. 使用 Helm 安装 Gatekeeper,并使用您从下一部分与 Policy Controller 不同的 Gatekeeper 设置中的表格中选择的设置。如需详细了解如何安装 Gatekeeper,请参阅 Gatekeeper 文档中的安装。

    在 Autopilot 集群上,默认 Helm chart 安装会失败,因为 GKE 会拒绝变更网络钩子中的通配符规则。设置 disableMutation: true Helm 值,或设置 mutatingWebhookCustomRules Helm 值,以仅列出 mutator 定位的特定资源。请勿包含 nodes、persistentvolumes、certificatesigningrequests 或 tokenreviews 资源。

  6. 在备份文件中,从您计划重新应用的每个资源中移除以下字段、标签和注解:

    • status 字段。
    • metadata 部分中的 resourceVersion、uid、creationTimestamp、generation、managedFields 和 ownerReferences 字段。
    • kubectl.kubernetes.io/last-applied-configuration 注解。
    • app.kubernetes.io/managed-by: anthospolicycontroller.googleapis.com 标签。如果再次在集群上启用 Policy Controller(例如通过舰队级默认配置),则它会管理具有此标签的资源,并且可以修改或删除这些资源。
    • 键具有 policycontroller. 前缀的标签和注解。
  7. 应用限制条件使用的 ConstraintTemplate,然后检查 Gatekeeper 是否为每个模板创建了 CustomResourceDefinition:

    kubectl get constrainttemplates \
        -o custom-columns='NAME:.metadata.name,CREATED:.status.created'
    

    当每个模板在 CREATED 列中显示 true 值时,应用您的限制条件。

与 Policy Controller 不同的 Gatekeeper 设置

在安装 Gatekeeper 之前,请查看下表中的设置,其中 Gatekeeper Helm 图表默认值与 Policy Controller 不同:

Policy Controller 默认值和 Gatekeeper Helm 图表默认值的比较
设置 Policy Controller 默认 Gatekeeper Helm 图表默认值 建议
变更 除非您已开启,否则处于关闭状态 开启 如果您不使用变更,请设置 disableMutation: true Helm 值。在 Autopilot 集群上,您必须设置 disableMutation: true Helm 值,或配置不含通配符或受限资源的 mutatingWebhookCustomRules Helm 值。如果您未指定其中一个值,则 GKE 会拒绝安装。
豁免命名空间 gatekeeper-system 命名空间和 exemptableNamespaces 列表中的命名空间 安装 Gatekeeper 的命名空间 将豁免的命名空间添加到 controllerManager.exemptNamespaces Helm 值。Gatekeeper 会拒绝更改具有 admission.gatekeeper.sh/ignore 标签的命名空间,除非这些命名空间被豁免。
参照数据 针对参照捆绑包自动同步 未同步 创建一个 Gatekeeper Config 或 SyncSet,其中列出引用模板读取的种类。在这些种类同步到 data.inventory 对象之前,冲突检查会允许违规请求,而存在性检查(例如 K8sRequireNamespaceNetworkPolicies ConstraintTemplate)会拒绝每个匹配的请求,即使所需资源存在也是如此。
ValidatingAdmissionPolicy 生成 不可用 为包含 CEL 代码的模板启用 Policy Controller 模板仅包含 Rego,因此只有在您向 ConstraintTemplate 添加 CEL 时,Gatekeeper 才会生成 ValidatingAdmissionPolicy。如需在网络钩子中保留强制执行,请设置 defaultCreateVAPForTemplates: false 和 defaultCreateVAPBindingForConstraints: false Helm 值。 如需了解详情,请参阅 Gatekeeper 文档中的与 Kubernetes 验证准入政策集成。
副本和资源 每个组件一个副本,内存上限为 1,024 MiB 三个具有不同资源限制的 webhook 副本 根据当前用量配置副本数量和资源限制。
图片 从 Google 管理的注册表中拉取 从 Docker Hub 拉取(openpolicyagent/gatekeeper、openpolicyagent/gatekeeper-crds 和 curlimages/curl 映像) 对于专用集群或强制执行 Binary Authorization 的集群,请将所有三个映像镜像到 Artifact Registry,并在图表中替换其映像值。如果您不镜像 curlimages/curl 映像,请停用网络钩子探测作业。

默认情况下,Gatekeeper 仅公开 Prometheus 指标,其指标名称与 Policy Controller 发送到 Cloud Monitoring 的名称不同。更新使用 Policy Controller 指标的所有信息中心和提醒。

迁移变更政策

如果您在 Policy Controller 中启用了变更,请列出您的变更器:

kubectl get assign,assignmetadata,assignimage,modifyset

对于每个 mutator,请选择以下选项之一:

  • MutatingAdmissionPolicy:您可以在 GKE 1.36 版及更高版本中使用 MutatingAdmissionPolicy。与 ValidatingAdmissionPolicy 一样,MutatingAdmissionPolicy 使用 CEL 表达式,并在 API 服务器中运行,无需网络钩子。Kubernetes 会在 ValidatingAdmissionPolicies 之前运行所有 MutatingAdmissionPolicies,因此请一并测试它们,以确保变更不会导致 ValidatingAdmissionPolicy 拒绝有效清单。在 Autopilot 集群上,GKE 会从 MutatingAdmissionPolicies 中排除代管式命名空间。如需详细了解变更政策,请参阅 Kubernetes 文档中的变更准入政策。
  • 自行管理的 Gatekeeper:在 Standard 集群上,您的 mutator 无需更改即可运行,因为 Gatekeeper 默认会开启变更功能。在 Autopilot 集群上,您必须在 Gatekeeper 图表中设置 mutatingWebhookCustomRules Helm 值,以列出 mutator 针对的具体资源,而不是通配符规则。如需了解详情,请参阅 GKE Autopilot 安全措施。 安装 Gatekeeper 后,从 mutator 备份文件中移除 Policy Controller 元数据,然后重新应用 mutator,就像对限制条件所做的那样。

更新构建流水线中的政策检查

您的构建流水线可能会在部署前根据 Policy Controller 限制条件检查清单。例如,流水线可能会使用 kpt 中的 gatekeeper 函数或 gator 命令行工具。如需了解详情,请参阅在持续集成流水线中根据公司政策验证应用。

如果您的流水线会检查清单,请针对替换清单更新流水线:

  • 如果您使用 Gatekeeper,则可以保留流水线。更新 gator 或 kpt 命令中的文件或目录路径,以引用包含清理后的 Gatekeeper ConstraintTemplate 和限制条件清单的代码库或目录。
  • 如果您使用 ValidatingAdmissionPolicies,则这些工具不会评估您的政策。而是针对测试集群运行服务器端试运行,该集群具有使用 Deny 操作的 ValidatingAdmissionPolicies 和 ValidatingAdmissionPolicyBindings:

    kubectl apply --dry-run=server -f MANIFEST_DIRECTORY
    

    将 MANIFEST_DIRECTORY 替换为包含清单的目录。如果 ValidatingAdmissionPolicy 拒绝清单,则命令会失败。

替换违规报告

ValidatingAdmissionPolicy 不包含信息中心,也不会审核集群中已存在的资源。请改用以下方法:

  • 警告:如果 ValidatingAdmissionPolicyBinding 使用 Warn 操作,则 API 服务器会向发送请求的客户端(例如 kubectl 命令行工具)返回警告。对于控制器创建的 Pod(例如 Deployment 中的 Pod),控制器会收到警告。
  • 审核日志:如果 ValidatingAdmissionPolicyBinding 使用 Audit 操作,则 API 服务器会为每个失败的验证添加审核日志条目注释。GKE 会将创建、更新和删除请求写入 Cloud Logging 中的管理员活动审核日志。如需查找失败的验证,请在 Logs Explorer 中运行以下查询:

    resource.type="k8s_cluster"
    logName:"cloudaudit.googleapis.com%2Factivity"
    labels."validation.policy.admission.k8s.io/validation_failure":*
    

如果您使用的限制条件将 dryrun 违规处置措施作为现有资源的合规性报告,则 ValidatingAdmissionPolicies 无法替换该报告。将这些政策保留在自行管理的 Gatekeeper 上,其审核控制器会按时间表检查现有资源。

移除 Policy Controller

在从集群中移除 Policy Controller 之前,请完成以下任务:

  • 确认您迁移到 ValidatingAdmissionPolicies 或 Pod 安全准入的所有政策均已强制执行,并且您已备份 ConstraintTemplate、限制条件和变更器。移除 Policy Controller 会删除其 CustomResourceDefinition,这会删除集群上的每个 ConstraintTemplate、限制条件和 mutator,包括您创建的那些。
  • 如果您使用 Config Sync 或 Argo CD 等 GitOps 工具从 Git 代码库部署约束条件,请从代码库中移除被替换的约束条件。确认已从集群中移除限制条件。
  • 可选:如需确认没有任何内容依赖于 Policy Controller 网络钩子,请先暂停 Policy Controller。暂停只会移除 webhook 配置,您可以恢复这些配置。

如需移除 Policy Controller,请按照以下步骤操作:

  1. 从集群中卸载 Policy Controller:

    gcloud container fleet policycontroller disable \
        --memberships=MEMBERSHIP_NAME \
        --project=PROJECT_ID
    

    替换以下内容:

    • MEMBERSHIP_NAME:要从中卸载 Policy Controller 的已注册集群的成员资格名称。 如需从多个集群中卸载 Policy Controller,请指定以英文逗号分隔的成员资格名称列表,或将 --memberships=MEMBERSHIP_NAME 标志替换为 --all-memberships 标志。
    • PROJECT_ID:舰队宿主项目的 ID。
  2. 确认 Policy Controller 已从集群中卸载完毕:

    gcloud container fleet policycontroller describe \
        --memberships=MEMBERSHIP_NAME \
        --project=PROJECT_ID \
        --format="yaml(membershipStates)"
    

    等待每个成员资格的顶级 policycontroller.state 字段的值为 NOT_INSTALLED,而不是 DECOMMISSIONING。在 CustomResourceDefinition 清理完成之前,各个 componentStates 条目会达到 NOT_INSTALLED 状态。

    如果您计划安装自行管理的 Gatekeeper,请确认 gatekeeper-system 命名空间不再存在:

    kubectl get namespace gatekeeper-system
    

    等待输出报告未找到 gatekeeper-system 命名空间。

  3. 可选:如需防止您稍后注册的集群获取 Policy Controller,请移除舰队级默认配置:

    gcloud container fleet policycontroller enable \
        --no-fleet-default-member-config \
        --project=PROJECT_ID
    

    此命令仅移除默认配置。它不会在任何集群上安装 Policy Controller。

从舰队外部的集群中移除 Policy Controller

gcloud container fleet policycontroller disable 命令仅从舰队管理的集群中移除 Policy Controller。在以下情况下,集群可以在没有舰队管理的情况下运行 Policy Controller:

  • 您使用 ConfigManagement Operator 安装了 Policy Controller。
  • 在 Policy Controller 完成卸载之前,您已从舰队中取消注册集群,或运行了 gcloud container fleet policycontroller detach 命令。

如需从这些集群中移除 Policy Controller,请将集群纳入舰队管理,然后卸载 Policy Controller:

  1. 按照清点和分类政策中的说明,备份 ConstraintTemplate、限制条件、同步配置和变更器。从 ConfigManagement Operator 安装中获取的备份中清理元数据时,除了 ownerReferences 字段和 policycontroller.* 元数据之外,还要移除 configmanagement.gke.io/* 和 k8s-app: kubernetes-config-management 标签。
  2. 如果您使用 ConfigManagement Operator 安装了 Policy Controller,请从集群上的 ConfigManagement 自定义资源中移除 policyController 字段。等待对账完成。 协调过程可能需要大约两分钟。然后,检查 gatekeeper-system 命名空间是否仍然存在:

    kubectl get namespace gatekeeper-system
    

    在 ConfigManagement Operator 1.17 版及更早版本中,移除 policyController 字段会自动卸载 Policy Controller。如果找不到 gatekeeper-system 命名空间,请跳过本部分中的其余步骤。在 ConfigManagement Operator 1.18 版及更高版本中,gatekeeper-system 命名空间仍保留在集群中,因此请继续执行下一步。

  3. 如果集群未注册到舰队,请将其注册。如需了解详情,请参阅将 Google Cloud 上的集群注册到您的舰队。

  4. 检查集群上是否启用了变更:

    kubectl get mutatingwebhookconfiguration \
        gatekeeper-mutating-webhook-configuration
    
  5. 在集群的成员资格上启用 Policy Controller,以便舰队接管现有安装的管理。如果上述命令返回了 gatekeeper-mutating-webhook-configuration 资源,请添加 --mutation 标志,以便舰队采用并稍后移除集群范围的变更资源:

    gcloud container fleet policycontroller enable \
        --memberships=MEMBERSHIP_NAME \
        --project=PROJECT_ID
    

    替换以下内容:

    • MEMBERSHIP_NAME:已注册集群的成员资格名称。
    • PROJECT_ID:舰队宿主项目的 ID。
  6. 等到成员资格的 policycontroller.state 字段的值为 ACTIVE:

    gcloud container fleet policycontroller describe \
        --memberships=MEMBERSHIP_NAME \
        --project=PROJECT_ID \
        --format="yaml(membershipStates)"
    
  7. 按照移除 Policy Controller 中的步骤卸载 Policy Controller。如果您不安装自行管理的 Gatekeeper,请在移除 gatekeeper-system 命名空间后删除所有剩余的限制条件 CustomResourceDefinition:

    kubectl get crd -o name \
        | grep '\.constraints\.gatekeeper\.sh$' \
        | xargs -r kubectl delete
    
  8. 可选:如果您注册集群只是为了完成此过程,请在 describe 命令显示成员资格的 NOT_INSTALLED 状态后取消注册。对于使用 --enable-fleet 标志注册的集群,请运行带有 --clear-fleet-project 标志的 gcloud container clusters update 命令,而不是 gcloud container fleet memberships unregister 命令。如需了解详情,请参阅取消注册集群。

后续步骤