使用 External Secrets Operator

本页面介绍了如何使用 External Secrets Operator (ESO) 将 Secret Manager 中的 Secret 同步到您的 Google Distributed Cloud 连接的集群。

External Secrets Operator 是一种开源 Kubernetes 运算符,可集成外部 Secret 管理系统。该运算符会从外部 API 读取信息,并自动将值注入到 Kubernetes Secret 中。

前提条件

如需使用 External Secrets Operator,您需要执行以下操作:

  • 创建功能正常的 Distributed Cloud 连接的集群。
  • 验证您的 Google Cloud 项目是否已启用以下 API。 如需了解如何启用 API,请参阅 启用服务
    • secretmanager.googleapis.com
    • iamcredentials.googleapis.com
  • 确保您已安装以下命令行工具:

    • 最新版本的 Google Cloud CLI,其中 包含 gcloud,用于与交互的命令行工具 Google Cloud。
    • kubectl

    如果您使用 Cloud Shell 作为与 Google Cloud交互的 Shell 环境,则系统会为您安装这些工具。

  • 确保您已初始化用于您项目的 gcloud CLI。

  • 在集群上启用 工作负载身份联合。 工作负载身份池会自动提供,并遵循格式 PROJECT_ID.svc.id.goog

  • 在集群上安装 External Secrets Operator。如需了解安装 说明,请参阅 External Secrets Operator 文档。 我们建议您在专用命名空间(例如 external-secrets)中安装该运算符。请勿将其安装在系统管理的命名空间(例如 kube-systemgke-system)中。

Distributed Cloud 连接的集群会自动注册到创建它们的项目中的舰队。

身份验证

External Secrets Operator 需要进行身份验证才能访问 Secret Manager。Distributed Cloud 连接的集群使用舰队 工作负载身份联合,以允许工作负载向 Google Cloud API 进行身份验证。

如需为 External Secrets Operator 配置身份验证,请执行以下操作:

  1. 按照 工作负载身份集群身份验证中的说明,在集群与 Google Cloud 之间建立信任关系。
  2. 确保 External Secrets Operator 使用的 Google 服务帐号对您要访问的 Secret 具有 Secret Manager Secret Accessor (roles/secretmanager.secretAccessor) 角色。
  3. 按照配置工作负载中的说明,将 External Secrets Operator Pod 配置为使用工作负载身份联合。

    大多数客户都使用工作负载身份联合进行身份验证。如需配置工作负载身份联合,您必须使用 Google 服务帐号为运算符使用的 Kubernetes ServiceAccount 添加注解。如需添加此 注解,请运行 kubectl annotate 命令:

    kubectl annotate serviceaccount KSA_NAME \
        --namespace OPERATOR_NAMESPACE \
        iam.gke.io/gcp-service-account=GSA_EMAIL
    

    或者,您也可以将注解添加到 ServiceAccount YAML:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      annotations:
        iam.gke.io/gcp-service-account: GSA_EMAIL
      name: KSA_NAME
      namespace: OPERATOR_NAMESPACE
    

    替换以下值:

    • KSA_NAME:运算符使用的 Kubernetes ServiceAccount 的名称
    • OPERATOR_NAMESPACE:您安装运算符的命名空间
    • GSA_EMAIL:Google 服务账号的电子邮件地址
  4. 向运算符 Pod 提供凭据配置文件。如需了解详情,请参阅 配置工作负载

创建 ESO 资源以同步 Secret

配置身份验证后,您可以创建 External Secrets Operator 资源以同步 Secret。

创建 SecretStore

SecretStore 用于指定如何访问外部 Secret 管理系统。您可以在与 External Secrets Operator 相同的命名空间或应用命名空间中创建 SecretStore 资源。如需了解详情,请参阅 SecretStore在 Kubernetes 文档中。

  1. 创建一个名为 secret-store.yaml 的文件,其中包含以下内容:

    apiVersion: external-secrets.io/v1
    kind: SecretStore
    metadata:
      name: gcp-store
      namespace: NAMESPACE
    spec:
      provider:
        gcpsm:
          projectID: PROJECT_ID
    

    替换以下值:

    • NAMESPACE:您要在其中创建 SecretStore 的命名空间
    • PROJECT_ID:存储 Secret 的项目 ID Google Cloud
  2. 使用 kubectl apply 命令应用清单:

    kubectl apply -f secret-store.yaml
    

创建 ClusterSecretStore

ClusterSecretStore 是一种集群级资源,ExternalSecret 资源可以在任何命名空间中使用它。如需了解详情,请参阅 Kubernetes 文档中的 ClusterSecretStore

  1. 创建一个名为 cluster-secret-store.yaml 的文件,其中包含以下内容:

    apiVersion: external-secrets.io/v1
    kind: ClusterSecretStore
    metadata:
      name: gcp-cluster-store
    spec:
      provider:
        gcpsm:
          projectID: PROJECT_ID
    

    PROJECT_ID 替换为存储 Secret 的 Google Cloud 项目 ID。

  2. 应用清单:

    kubectl apply -f cluster-secret-store.yaml
    

创建 ExternalSecret

ExternalSecret 用于声明要提取哪些数据以及将其存储在集群中的哪个位置。在应用 Pod 使用生成的 Kubernetes Secret 的命名空间中创建 ExternalSecret 资源。如需了解详情, 请参阅 Kubernetes 文档中的ExternalSecret

  1. 创建一个名为 external-secret.yaml 的文件,其中包含以下内容:

    apiVersion: external-secrets.io/v1
    kind: ExternalSecret
    metadata:
      name: EXTERNAL_SECRET
      namespace: NAMESPACE
    spec:
      refreshInterval: 1h
      secretStoreRef:
        kind: SecretStore
        name: gcp-store
      target:
        name: K8S_SECRET_NAME
        creationPolicy: Owner
      data:
      - secretKey: K8S_SECRET_KEY
        remoteRef:
          key: SECRET_NAME
    

    替换以下值:

    • EXTERNAL_SECRETExternalSecret 资源的名称。
    • NAMESPACE:您创建 SecretStore 的命名空间。
    • K8S_SECRET_NAME:ESO 要创建的 Kubernetes Secret 的名称。
    • K8S_SECRET_KEY:Kubernetes Secret 数据中的键。
    • SECRET_NAME:Secret Manager 中的 Secret 名称。Google Cloud

    如果您使用 ClusterSecretStore,请设置 kind: ClusterSecretStore,并更新 name 中的 secretStoreRef

  2. 应用清单:

    kubectl apply -f external-secret.yaml
    

从 JSON Secret 同步多个键

如果 Secret Manager 中的 Secret 包含 JSON 字符串,您可以将所有键提取为 Kubernetes Secret 中的单独条目。

  1. 创建一个名为 external-secret-json.yaml 的文件,其中包含以下内容:

    apiVersion: external-secrets.io/v1
    kind: ExternalSecret
    metadata:
      name: EXTERNAL_SECRET
      namespace: NAMESPACE
    spec:
      refreshInterval: 1h
      secretStoreRef:
        kind: SecretStore
        name: gcp-store
      target:
        name: K8S_SECRET_NAME
        creationPolicy: Owner
      dataFrom:
      - extract:
          key: SECRET_NAME
    
  2. 应用清单:

    kubectl apply -f external-secret-json.yaml
    

JSON Secret 中的每个键值对都会映射到生成的 Kubernetes Secret 中的键值对。

问题排查

如果您的 Secret 未同步,请按照以下步骤进行问题排查:

  1. 使用 kubectl get 命令检查 ExternalSecret 资源的状态:

    kubectl get externalsecret EXTERNAL_SECRET -n NAMESPACE -o yaml
    

    检查 status 部分是否有任何错误消息或失败的条件。

  2. 使用 kubectl logs 命令检查 External Secrets Operator 控制器 Pod 的日志:

    kubectl logs -l app.kubernetes.io/name=external-secrets -n OPERATOR_NAMESPACE
    
  3. 验证运算符使用的 Kubernetes ServiceAccount 是否已使用 Google 服务帐号电子邮件地址正确添加注解。如需了解详情,请参阅集群上的工作负载身份联合

  4. 验证 Google 服务帐号是否具有必要的权限,以及工作负载身份联合是否已正确配置。如需了解详情, 请参阅集群上的工作负载身份联合

后续步骤