保护集群元数据


概览

Google Kubernetes Engine (GKE) 使用实例元数据配置节点虚拟机 (VM),但此元数据的一部分可能比较敏感,应该受到保护,以免受到集群上运行的工作负载的影响

准备工作

在开始之前,请确保您已执行以下任务:

  • 确保您已启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 确保您已安装 Cloud SDK
  • 使用以下方法之一为您的项目设置默认 gcloud 命令行工具设置:
    • 使用 gcloud init(如果您想要在系统引导下完成项目默认设置)。
    • 使用 gcloud config(如果您想要单独设置项目 ID、可用区和区域。

    gcloud init

    1. 运行 gcloud init 并按照说明操作:

      gcloud init

      如果您要在远程服务器上使用 SSH,请使用 --console-only 标志来防止命令启动浏览器:

      gcloud init --console-only
    2. 按照说明授权 gcloud 工具使用您的 Google Cloud 帐号。
    3. 创建新配置或选择现有配置。
    4. 选择 Google Cloud 项目。
    5. 选择默认的 Compute Engine 可用区
    6. 选择默认的 Compute Engine 区域

    gcloud config

    1. 设置默认项目 ID
      gcloud config set project PROJECT_ID
    2. 设置默认的 Compute Engine 区域(例如 us-central1):
      gcloud config set compute/region COMPUTE_REGION
    3. 设置默认的 Compute Engine 可用区(例如 us-central1-c):
      gcloud config set compute/zone COMPUTE_ZONE
    4. gcloud 更新到最新版本:
      gcloud components update

    通过设置默认位置,您可以避免 gcloud 工具中出现以下错误:One of [--zone, --region] must be supplied: Please specify location

配置节点服务帐号

每个节点的服务帐号凭据将继续向工作负载公开。默认情况下,您的节点使用 Compute Engine 默认服务帐号。您应该配置具有最低权限的服务帐号,供节点而不是 Compute Engine 默认服务帐号使用。然后,将此服务帐号附加到节点,这样攻击者就无法通过使用 Compute Engine API 直接访问底层虚拟机实例来绕开 GKE 的元数据保护。

如需了解详情,请参阅使用最小权限节点服务帐号

如需创建最小权限节点服务帐号,请执行以下步骤:

  1. 创建新的 Identity and Access Management (IAM) 服务帐号并将电子邮件地址保存在环境变量中:

    gcloud iam service-accounts create NODE_SA_NAME \
        --display-name="DISPLAY_NAME"
    export NODE_SA_EMAIL=$(gcloud iam service-accounts list --format='value(email)' \
        --filter='displayName:DISPLAY_NAME')
    

    替换以下内容:

    • NODE_SA_NAME:新节点服务帐号的名称。
    • DISPLAY_NAME:新服务帐号的显示名。

    节点服务帐号电子邮件地址的格式为 NODE_SA_NAME@PROJECT_ID.iam.gserviceaccount.com

  2. 为您的服务帐号配置运行 GKE 节点所需的最小角色和权限:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:$NODE_SA_EMAIL \
        --role=roles/monitoring.metricWriter
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:$NODE_SA_EMAIL \
        --role=roles/monitoring.viewer
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:$NODE_SA_EMAIL \
        --role=roles/logging.logWriter
    

    PROJECT_ID 替换为您的 Google Cloud 项目 ID。

    此外,如果您的集群从 Artifact Registry 中拉取私有映像,请添加 roles/artifactregistry.reader 角色:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:$NODE_SA_EMAIL \
        --role=roles/artifactregistry.reader
    

元数据隐藏

GKE 元数据隐藏可保护一些潜在的敏感系统元数据免受集群上运行的用户工作负载的影响。

在 Kubernetes 1.9.3 及更高版本中,您可以启用元数据隐藏,以防止用户 Pod 访问集群节点的某些虚拟机元数据,例如 Kubelet 凭据和虚拟机实例信息。具体而言,元数据隐藏可为 kube-env(包含 Kubelet 凭据)和虚拟机的实例身份令牌提供访问保护。

元数据隐藏使用防火墙阻隔从用户 Pod(未在 HostNetwork 上运行的 Pod)到集群元数据服务器的流量,仅允许安全查询。防火墙阻止用户 Pod 使用 kubelet 凭据进行提升权限攻击,或使用虚拟机身份进行实例升级攻击。

您只能在创建新集群或在向现有集群添加新节点池时启用元数据隐藏。

限制

  • 元数据隐藏只能为 kube-env 和节点的实例身份令牌提供访问保护。
  • 元数据隐藏不限制对节点服务帐号的访问。
  • 元数据隐藏不限制对其他相关实例元数据的访问。
  • 元数据隐藏不限制对其他旧版元数据 API 的访问。

创建带元数据隐藏的新集群或节点池

创建服务帐号后,您可以使用 gcloud 命令行工具创建新的集群,并启用元数据隐藏。

如需在创建集群的同时启用元数据隐藏,请运行以下命令:

gcloud beta container clusters create CLUSTER_NAME \
  --workload-metadata-from-node=SECURE \
  --service-account=$NODE_SA_EMAIL

CLUSTER_NAME 替换为新集群的名称。

--workload-metadata-from-node 标志采用以下值:

  • SECURE:启用元数据隐藏。
  • EXPOSEDUNSPECIFIED:停用元数据隐藏。

验证集群工作负载中已隐藏身份令牌元数据

元数据隐藏后,应该无法通过节点的实例身份令牌请求签名。如需验证请求会将元数据隐藏明确通知用户,您可以在 Pod 中运行 curl 命令:

curl -H "Metadata-Flavor: Google" \
'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://www.example.com'

输出内容类似如下:

This metadata endpoint is concealed.

停用旧版元数据 API 并从其转换到新版

v0.1v1beta1 Compute Engine 元数据服务器端点已被弃用,并已于 2020 年 9 月 30 日关停。

如需了解关停时间表,请参阅 v0.1v1beta1 元数据服务器端点弃用

后续步骤