设置多租户日志记录


本页面介绍如何为 Google Kubernetes Engine (GKE) 集群配置多租户日志记录。

多个团队通常会共享一个 GKE 集群。共享集群具有多项优势,包括简化服务发现、简化安全性,以及减少集群管理员需要维护的集群。但是,各个应用团队通常会有单独的项目。这种结构称为多租户,具有一个主 GKE 集群,但每个应用团队都有单独的命名空间。应用团队的项目称为租户。

借助 Google Cloud,GKE 集群管理员可以创建一个系统,其中集群的日志保留在主 GKE 项目中,并且租户日志会分配到租户项目。如需以这种方式配置日志,请使用日志路由器。通过日志路由器,您可以控制 Google Cloud 项目中的日志流以及如何将日志路由到支持的目的地。

如需创建特定于租户的日志,集群管理员需要创建一个接收器,以将日志条目路由到每个租户的项目。在每个租户项目中,各个团队可以控制日志的存储和使用方式,例如通过配置基于日志的指标和基于日志的提醒来监控日志。

我们建议主 GKE 项目中的 _Default 接收器包含排除项过滤条件。排除项过滤条件会阻止租户日志注入到主 GKE 项目和租户项目。

前提条件

配置多租户日志记录

您可以使用 Google Cloud CLI 或 Google Cloud 控制台来配置多租户日志记录。

gcloud

如需为 GKE 集群配置多租户日志记录,请完成以下步骤:

  1. 设置以下环境变量:

    export TENANT_NAMESPACE="TENANT_NAMESPACE"
    export MAIN_PROJECT="MAIN_PROJECT_ID"
    export TENANT_PROJECT="TENANT_PROJECT_ID"
    

    请替换以下内容:

    • TENANT_NAMESPACE:租户项目命名空间的名称
    • MAIN_PROJECT_ID:主项目的项目 ID
    • TENANT_PROJECT_ID:租户项目的项目 ID
  2. 在多租户集群中创建命名空间:

    kubectl create namespace $TENANT_NAMESPACE
    
  3. 在主 GKE 项目中创建日志接收器:

    gcloud logging sinks create gke-$TENANT_NAMESPACE-sink \
    logging.googleapis.com/projects/$TENANT_PROJECT \
        --project=$MAIN_PROJECT \
        --log-filter=resource.labels.namespace_name="$TENANT_NAMESPACE" \
        --description="Log sink to $TENANT_PROJECT for $TENANT_NAMESPACE namespace"
    

    此命令会创建一个日志接收器,以将与 $TENANT_NAMESPACE 命名空间相关的所有日志发送到租户项目。

    您可能需要使用限制性更强的 --log-filter。例如,如果您的集群和租户具有相同的命名空间,请添加集群过滤条件。

    如需详细了解这些字段,请参阅 gcloud logging sinks create API 文档

  4. 从主项目的接收器中获取写入者身份,并将其分配给环境变量。

    export SERVICE_ACCOUNT=$(gcloud logging sinks describe gke-$TENANT_NAMESPACE-sink \
        --project=$MAIN_PROJECT \
        --format='value(writerIdentity)')
    
  5. 向接收器使用的服务账号授予 Logs Writer (logging.bucketWriter) 角色。以下命令会为主项目授予将日志写入租户项目的权限:

     gcloud projects add-iam-policy-binding $TENANT_PROJECT \
         --member=$SERVICE_ACCOUNT --role='roles/logging.logWriter' \
         --condition="expression=resource.name.endsWith(\"projects/$TENANT_PROJECT\"),title=Log writer for $TENANT_NAMESPACE,description=Grants Logs Writer role to service account $SERVICE_ACCOUNT used by gke-$TENANT_NAMESPACE-sink"
    

    如需详细了解这些字段,请参阅 gcloud projects add-iam-policy-binding API 文档

  6. (可选)为将日志路由到主项目的 _Default 存储桶的接收器创建排除项过滤条件。如果您未在 _Default 存储桶上创建排除项过滤条件,则路由的日志会同时显示在主项目的 _Default 存储桶和租户日志存储桶中。如需创建排除项过滤条件,请执行以下操作:

    gcloud logging sinks update _Default --project=$MAIN_PROJECT \
        --add-exclusion="name=gke-$TENANT_NAMESPACE-default-exclusion,description=\"Exclusion filter on the _Default bucket for $TENANT_NAMESPACE\",filter=resource.labels.namespace_name=\"$TENANT_NAMESPACE\""
    

    如需详细了解这些字段,请参阅 gcloud logging sinks update API 文档

控制台

如需为 GKE 实现多租户日志记录,请完成以下步骤:

  1. 在主项目中创建日志接收器:

    1. 使用 Google Cloud 控制台项目选择器选择主 GKE 项目。
    2. 在 Google Cloud 控制台的导航面板中,选择 Logging,然后选择日志路由器

      前往日志路由器

    3. 日志路由器页面中,点击创建接收器
    4. 输入接收器的名称说明,然后点击下一步
    5. 选择接收器服务菜单中,选择其他项目
    6. 接收器目标位置字段中,添加以下目的地:

      logging.googleapis.com/projects/TENANT_PROJECT_ID
      

      TENANT_PROJECT_ID 替换为租户项目的 ID。

    7. 点击下一步

    8. 构建包含项过滤条件中,添加以下过滤条件:

      resource.labels.namespace_name="TENANT_NAMESPACE"
      

      TENANT_NAMESPACE 替换为租户项目命名空间的名称。

      您可能需要使用更严格的包含过滤器。例如,当您的集群和租户具有相同的命名空间时,请考虑添加子句以仅包含特定集群的日志条目。

    9. 点击创建接收器。新接收器会显示在日志路由器接收器列表中。

  2. 将接收器的写入者身份复制到剪贴板:

    1. 日志路由器页面中,找到日志接收器。
    2. 对于该接收器,点击 更多,然后选择查看接收器详情
    3. 接收器详情窗格中,找到写入者身份字段,然后将值复制到剪贴板。省略复制的值中的 serviceAccount:
  3. 在租户项目中,向主项目的接收器使用的服务账号授予 Logs Writer (roles/logging.logWriter) 角色。主项目需要此权限才能将日志写入租户项目。

    1. 在 Google Cloud 控制台的导航面板中,选择 IAM

      前往 IAM

    2. 点击授予使用权限
    3. 新的主账号字段中,添加接收器的服务账号。
    4. 选择角色下拉列表中,选择 Logging,然后选择 Logs Writer
    5. 点击保存
  4. (可选)在主项目的 _Default 存储桶中创建排除项过滤条件,以阻止路由到租户项目的日志写入主项目中的 _Default 日志存储桶:

    1. 在 Google Cloud 控制台的导航面板中,选择 Logging,然后选择日志路由器

      前往日志路由器

    2. _Default 存储分区旁边,点击 更多,然后选择修改接收器
    3. 选择要从接收器中过滤掉的日志部分,点击添加排除项
    4. 添加过滤条件名称。
    5. 构建排除项过滤条件框中,添加以下内容:

      resource.labels.namespace_name="TENANT_NAMESPACE"
      
    6. 点击更新接收器

验证租户日志

开始使用那些使用 TENANT_NAMESPACE 的工作负载后,您可以验证租户项目是否接收特定于租户的日志:

  1. 通过使用 Google Cloud 控制台项目选择器,选择租户项目。
  2. 在 Google Cloud 控制台的导航面板中,选择 Logging,然后选择 Logs Explorer

    前往 Logs Explorer

  3. 在查询编辑器字段中,运行以下查询:

    resource.labels.namespace_name="TENANT_NAMESPACE"
    

    查询结果窗格中,您应该会看到从主项目路由的特定于租户的日志。

使用租户日志

在租户项目中,每个团队都可以控制路由、存储和分析日志的方式。将日志路由到租户项目后,各个应用团队可以选择将其日志路由到支持的目标位置(例如 Logging 存储桶),或使用 Pub/Sub 路由到第三方目标位置。如需了解如何路由日志条目,请参阅将日志路由到支持的目的地

各个应用团队还可以根据日志的内容或从日志派生的指标来设置提醒。如需了解详情,请参阅监控日志

清理

您可以使用 gcloud 或 Google Cloud 控制台移除为多租户日志记录创建的对象。

gcloud

如需移除为多租户日志记录创建的对象,请完成以下步骤:

  1. 设置变量以简化以下命令:

    export TENANT_NAMESPACE="TENANT_NAMESPACE"
    export MAIN_PROJECT="MAIN_PROJECT_ID"
    export TENANT_PROJECT="TENANT_PROJECT_ID"
    

    请替换以下内容:

    • TENANT_NAMESPACE:租户项目命名空间的名称
    • MAIN-PROJECT-ID:主项目的项目 ID
    • TENANT-PROJECT-ID:租户项目的项目 ID
  2. 移除租户项目中服务账号的 Logs Writer (roles/logging.logWriter) 角色:

    export SERVICE_ACCOUNT=$(gcloud logging sinks describe gke-$TENANT_NAMESPACE-sink \
        --project=$MAIN_PROJECT | \
        --format='value(writerIdentity)'
    
    gcloud projects remove-iam-policy-binding $TENANT_PROJECT \
        --member=$SERVICE_ACCOUNT \
        --role='roles/logging.logWriter' \
        --all
    
  3. 删除日志接收器:

    gcloud logging sinks delete gke-$TENANT_NAMESPACE-sink \
        --project=$MAIN_PROJECT
    
  4. 删除命名空间:

    kubectl delete namespace $TENANT_NAMESPACE
    

控制台

  1. 在租户项目中,移除服务账号的 Logs Writer (roles/logging.logWriter) 角色:

    1. 在 Google Cloud 控制台的导航面板中,选择 IAM

      前往 IAM

    2. 对于要删除的服务账号,点击 修改主账号
    3. 修改访问权限面板中,点击 Logs Writer 角色旁边的 删除角色,然后点击保存
  2. 在主项目中,删除日志接收器:

    1. 使用 Google Cloud 控制台项目选择器选择租户 GKE 项目。
    2. 在 Google Cloud 控制台的导航面板中,选择 Logging,然后选择日志路由器

      前往日志路由器

    3. 对于要删除的接收器,点击 更多
    4. 选择删除接收器
    5. 在确认面板中,点击删除

限制

多租户日志记录具有以下限制:

  • 每个项目的日志接收器数量配额为 200。如果您需要的租户超过 200 个,请通过提交支持请求来申请增加配额。
  • 每个日志存储桶最多只能有 50 个排除项过滤条件。如果您希望拥有的租户超过 50 个,则需要修改 _Default 存储桶的排除项过滤条件方法。或者,您也可以执行以下操作:

    • 创建一个排除项过滤条件,以使用以下命令排除所有非系统或非默认命名空间:

      gcloud logging sinks update _Default \
      --project=$MAIN_PROJECT \
      --add-exclusion="name=gke-all-tenant-default-exclusion,description=\"Exclusion filter on the _Default bucket for all tenants\",filter=resource.labels.namespace_name !~ \"kube\" AND resource.labels.namespace_name !~ \"system\ AND resource.labels.namespace_name != \"Default\""
      
    • 通过不创建排除项过滤条件,在租户项目和主项目之间复制日志。

后续步骤