在 GKE 节点中自定义 containerd 配置

本页面介绍如何在 Google Kubernetes Engine (GKE) 节点上自定义 containerd 容器运行时的配置。在阅读本文档之前,请确保您熟悉什么是容器运行时以及为什么要对其进行自定义。

GKE 中的 containerd 配置简介

您可以在运行 Container-Optimized OS 等操作系统的 GKE 节点上手动配置 containerd 运行时中的一组选项。通过自定义运行时,您可以配置特殊要求,例如访问私有映像注册表。如需设置这些选项,请创建一个名为运行时配置文件的 YAML 文件,并在创建或更新集群或节点池时将该文件传递给 GKE。

这种自定义 containerd 的方法可让您避免部署特权 DaemonSet,这会带来安全风险。当您向 GKE 提供运行时配置文件时,GKE 会重新创建节点,并使用您的配置在每个节点上更新 containerd config.toml 文件。此配置在节点终止、升级和重新创建的过程中保持不变。

您可以在集群级层或节点池级层配置 containerd 设置。节点池级配置会替换这些选项的集群级配置。 当您更新集群级 containerd 配置选项(例如 registryHostswritableCgroups)时,GKE 只会更新并重新创建没有针对这些选项设置自己的节点池级设置的节点池中的节点。如果节点池针对该选项具有自己的节点池级配置,则不会更新或重新创建该节点池,并且该节点池会继续使用自己的设置。

运行时配置文件仅允许您在 containerd 中配置选项。GKE 还支持使用称为节点系统配置文件的单独文件来配置特定的 kubelet 选项和低层级 Linux 内核选项。如需了解详情,请参阅自定义节点系统配置

限制

您无法使用运行时配置文件更改 Windows 节点映像中的 containerd 设置。

可用的 containerd 配置选项

以下部分介绍了您可以使用运行时配置文件配置的选项。

privateRegistryAccessConfig

使用您存储在 Secret Manager 中的私有凭证访问私有映像注册表。

对于 Container-Optimized OS 节点映像,此选项适用于 GKE 版本 1.27.3-gke.1700 或更高版本;对于 Ubuntu 节点映像,此选项适用于 GKE 版本 1.33 或更高版本。

如需查看相关说明,请参阅使用私有 CA 证书访问私有注册表

privateRegistryAccessConfig:
  enabled: true
  certificateAuthorityDomainConfig:
  - gcpSecretManagerCertificateConfig:
    secretURI: "SECRET_LOCATION"
  fqdns:
  - "FQDN1"
  - "FQDN2"

此配置包含以下字段:

  • enabled:一个布尔值,用于启用私有注册表配置。如果您设置了 enabled: false,请删除 privateRegistryAccessConfig 项中的任何其他字段。
  • certificateAuthorityDomainConfig:最多包含五个证书和 FQDN 定义。
  • gcpSecretManagerCertificateConfig:包含存储在 Secret Manager 中的证书和一组 FQDN。
  • secretURI:证书在 Secret Manager 中的位置。privateRegistryAccessConfig 仅在 secretURI 中支持全局密钥。
  • fqdns:私有注册表的完全限定域名列表。您也可以使用 IPv4 地址,但我们建议使用 FQDN。

registryHosts

为 containerd 注册表配置高级设置,例如功能、自定义标头和证书。这对应于 containerd 的 hosts.toml

此选项适用于 GKE 1.34.1-gke.2980000 版或更高版本。

registryHosts:
- server: "REGISTRY_SERVER_FQDN"
  hosts:
  - host: "MIRROR_FQDN"
    capabilities:
    - "HOST_CAPABILITY_PULL"
    - "HOST_CAPABILITY_RESOLVE"
    - "HOST_CAPABILITY_PUSH"
    overridePath: false
    dialTimeout: "30s"
    header:
    - key: "HEADER_KEY"
      value:
      - "HEADER_VALUE_1"
      - "HEADER_VALUE_2"
    ca:
    - gcpSecretManagerSecretUri: "projects/PROJECT_ID_OR_NUMBER/secrets/CA_SECRET/versions/VERSION"
    client:
    - cert:
        gcpSecretManagerSecretUri: "projects/PROJECT_ID_OR_NUMBER/secrets/CLIENT_CERT_SECRET/versions/VERSION"
      key:
        gcpSecretManagerSecretUri: "projects/PROJECT_ID_OR_NUMBER/secrets/CLIENT_KEY_SECRET/versions/VERSION"

此配置包含以下字段:

  • server:注册服务器的主机名(例如 example.com)。此名称用于命名节点上的配置文件。应为不含方案、端口或路径的完全限定域名或 IP 地址。
  • hosts:针对 server 的特定于主机的配置列表。
  • host:注册表镜像的主机名(例如 https://mirror.example.com:8000/12341.2.3.4:80)。这应该是完全限定域名或 IP 地址。支持协议、端口和路径。架构只能为 httphttps
  • capabilities:一个功能列表,用于指定主机能够执行哪些操作。支持的值包括以下任一值:
    • HOST_CAPABILITY_PULL:表示按摘要提取清单和 blob 的功能。
    • HOST_CAPABILITY_RESOLVE:表示按名称提取清单的功能。
    • HOST_CAPABILITY_PUSH:表示推送 blob 和清单的功能。
    如果未指定,则启用所有功能。
  • overridePath:一个布尔值。如果值为 true,则表示主机的 API 根端点是在网址路径中定义的,而不是通过 API 规范定义的。这可用于缺少 /v2 前缀的不合规 OCI 注册表。默认值为 false
  • dialTimeout:时长字符串(例如 "30s"),用于指定允许连接尝试完成的最长时长。允许的最大值为 "180s"。如果未设置,containerd 会将默认值设置为 "30s"。该值应为以秒为单位的小数,并带有 s 后缀。
  • header:要发送到注册表主机的自定义 HTTP 标头列表。
    • key:标头键。
    • value:标头值列表。
  • ca:注册表主机的证书授权机构 (CA) 的证书配置列表。如需创建证书 Secret 并配置所需权限,请参阅将 CA 公钥存储在 Secret Manager 中中的说明。
    • gcpSecretManagerSecretUri:Secret Manager 中包含 CA 证书的 Secret 的 URI。它同时支持全球级 Secret 和区域级 Secret。对于各个密文类型,格式如下:
      • 全局 Secret 格式:projects/PROJECT_ID_OR_NUMBER/secrets/SECRET_NAME/versions/VERSION
      • 区域级 Secret 格式:projects/PROJECT_ID_OR_NUMBER/locations/REGION/secrets/SECRET_NAME/versions/VERSION
  • client:用于向注册表主机进行身份验证的客户端证书和密钥对列表。如需创建证书 Secret 并配置所需权限,请参阅将 CA 公钥存储在 Secret Manager 中中的说明。
    • cert:客户端证书配置。
      • gcpSecretManagerSecretUri:Secret Manager 中包含客户端证书的 Secret 的 URI。它同时支持全球级 Secret 和区域级 Secret。
    • key:客户端私钥配置。
      • gcpSecretManagerSecretUri:Secret Manager 中包含客户端密钥的 Secret 的 URI。它同时支持全球级 Secret 和区域级 Secret。

writableCgroups

以读写模式装载 /sys/fs/cgroup 文件系统,以便工作负载可以管理其子进程的资源。

此选项适用于 GKE 1.34.1-gke.2541000 版或更高版本。

如需了解详情,请参阅为容器配置可写入的 cgroup

writableCgroups:
  enabled: true

将 containerd 配置应用于新集群

本部分介绍如何在创建新的 GKE 集群时应用 containerd 配置文件。

运行以下命令以创建 Autopilot 集群:

gcloud container clusters create-auto CLUSTER_NAME \
    --location=LOCATION \
    --scopes="cloud-platform" \
    --containerd-config-from-file="PATH_TO_CONFIG_FILE"

替换以下内容:

  • CLUSTER_NAME:新集群的名称。
  • LOCATION:新集群的 Compute Engine 位置。
  • PATH_TO_CONFIG_FILE:您创建的配置文件的路径,例如 ~/containerd-configuration.yaml

您可以运行带有相同选项的 gcloud container clusters create 命令,在新的 Standard 集群上启用 containerd 配置。除非您指定其他 containerd 配置,否则在集群中创建的新节点池会继承集群级默认 containerd 配置。

将 containerd 配置应用于新节点池

您可以使用以下命令将 containerd 配置应用于新的 GKE 节点池:

gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=LOCATION \
    --scopes="cloud-platform" \
    --containerd-config-from-file="PATH_TO_CONFIG_FILE"

替换以下内容:

  • NODE_POOL_NAME:新节点池的名称。
  • CLUSTER_NAME:现有集群的名称。
  • LOCATION:新节点池的 Compute Engine 位置。
  • PATH_TO_CONFIG_FILE:您创建的配置文件的路径,例如 ~/containerd-configuration.yaml

将 containerd 配置应用于现有集群

本部分介绍如何将 containerd 配置应用于现有集群和节点。

更新集群级 containerd 配置仅适用于未在节点池级定义自己的设置(例如 registryHostswritableCgroups)的节点池。GKE 会重新创建这些节点池中的节点,以应用新配置。具有节点池级设置的节点池会继续使用自己的配置,并且其节点不会重新创建。 使用 containerd 配置更新集群或节点池时,会重新创建节点来应用配置。这可能会导致正在运行的工作负载暂时中断。只有在启用了自动升级时,GKE 才会重新创建节点。重新创建操作会遵循您设置的任何维护窗口。在未启用自动升级的 Standard 集群中,您必须手动重新创建节点以应用配置。

检查访问权限范围

如果您的配置文件使用 Secret Manager 中的 Secret,则集群或节点池必须具有 cloud-platform 访问权限范围。本部分介绍如何检查访问权限范围,并使用新的或修改后的运行时配置文件更新现有集群。

如需详细了解新集群中的默认访问权限范围,请参阅 GKE 中的访问权限范围

检查 Autopilot 访问权限范围

运行以下命令:

gcloud container clusters describe CLUSTER_NAME \
    --location=LOCATION \
    --flatten=nodeConfig \
    --format='csv[delimiter="\\n",no-heading](oauthScopes)'

如果您使用的是 Secret Manager 中的 Secret,但您的集群没有 https://www.googleapis.com/auth/cloud-platform 访问权限范围,请创建一个具有此访问权限范围的新集群。

检查 Standard 访问权限范围

如需检查 Standard 集群访问权限范围,请检查节点池:

gcloud container node-pools describe NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=LOCATION \
    --format='value[delimiter="\\n"](config.oauthScopes)'

NODE_POOL_NAME 替换为节点池的名称。

如果您使用的是 Secret Manager 中的 Secret,并且您的集群没有 https://www.googleapis.com/auth/cloud-platform 访问权限范围,请创建一个具有 cloud-platform 访问权限范围的新节点池,并删除现有节点池。

更新集群以使用配置文件

运行以下命令:

gcloud container clusters update CLUSTER_NAME \
    --location=LOCATION \
    --containerd-config-from-file="PATH_TO_CONFIG_FILE"

更新节点池以使用配置文件

如需更新节点池的 containerd 配置,请运行以下命令:

gcloud container node-pools update NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=LOCATION \
    --containerd-config-from-file="PATH_TO_CONFIG_FILE"

替换以下内容:

  • NODE_POOL_NAME:您要更新的节点池的名称。
  • CLUSTER_NAME:现有集群的名称。
  • LOCATION:集群的 Compute Engine 位置。
  • PATH_TO_CONFIG_FILE:您创建的配置文件的路径,例如 ~/containerd-configuration.yaml

在 Standard 集群中重新创建节点

如果您的 Standard 集群不使用自动升级,则您必须手动重新创建节点池以应用新配置。如需触发手动重新创建节点的操作,请将集群升级到其已在使用的 GKE 版本。

gcloud container clusters upgrade CLUSTER_NAME \
    --location=LOCATION \
    --cluster-version=VERSION

VERSION 替换为集群已在使用的同一 GKE 补丁版本。

停用 containerd 配置选项

停用 privateRegistryAccessConfig

  1. 更新配置文件,在 privateRegistryAccessConfig 中指定 enabled: false,并删除该项中的任何其他字段,如以下示例所示:

    privateRegistryAccessConfig:
      enabled: false
  2. 将更新后的配置文件应用到集群。如需了解相关说明,请参阅将 containerd 配置应用于现有集群

停用 registryHosts

  1. 更新配置文件,以在 registryHosts 项中指定一个空数组,如以下示例所示:

    registryHosts: []
  2. 将更新后的配置文件应用到集群。如需了解相关说明,请参阅将 containerd 配置应用于现有集群