aibangjuxin / knowledge

My knowledge
1 stars 0 forks source link

GCP secret manager #130

Open aibangjuxin opened 7 months ago

aibangjuxin commented 7 months ago

对于GCP工程我有最后一个场景 想要通过auth 的账户和密码写一个Python访问一个接口地址获取一些数据、 1 我的请求是放在GKE里面的Pod 2 我想要将对应的账户和密码放在gap secret manager 里面 。那么大概的操作逻辑应该是怎么样的? 或者是我具体的实现方式是什么样的?

要在 GKE Pod 中配置访问 Secret Manager 的权限,您需要:

  1. 创建 Kubernetes ServiceAccount
kubectl create serviceaccount my-service-account
  1. 授予 ServiceAccount 访问 Secret Manager 的权限
kubectl create rolebinding my-role-binding \
  --role roles/secretmanager.secretAccessor \
  --serviceaccount=default:my-service-account
  1. 将 ServiceAccount 附加到 Pod
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  serviceAccountName: my-service-account
  # ...

现在,您的 Pod 将能够访问 Secret Manager 中的秘密。

注意:

其他方法:

除了使用 ServiceAccount 之外,您还可以使用以下方法授予 Pod 访问 Secret Manager 的权限:

选择哪种方法取决于您的特定需求和安全要求。

操作逻辑:

  1. 创建一个 Secret Manager 密钥,其中包含用于访问接口的凭据(用户名和密码)。
  2. 在 GKE Pod 中使用 Secret Manager 客户端库检索密钥。
  3. 使用检索到的凭据向接口发出请求。

具体实现(Python):

import os

from google.cloud import secretmanager
from google.cloud.secretmanager_v1.types import service

# Create a Secret Manager client.
client = secretmanager.SecretManagerServiceClient()

# Build the resource name of the secret version.
name = client.secret_version_path(
    "projects/my-project", "secrets/my-secret", "versions/latest"
)

# Access the secret version.
response = client.access_secret_version(request={"name": name})

# Parse the secret payload.
payload = response.payload.data.decode("UTF-8")
credentials = json.loads(payload)

# Use the credentials to access the API.
# ...

在 GKE Pod 中部署:

  1. 将上述 Python 代码保存到一个文件中,例如 get_secret.py
  2. 将 Secret Manager 密钥安装到 Pod 中。
  3. 在 Pod 中运行以下命令:
python get_secret.py

这将检索 Secret Manager 密钥并使用凭据向接口发出请求。

注意:

其他方法:

除了使用 Python 客户端库之外,您还可以使用以下方法在 GKE Pod 中访问 Secret Manager:

选择哪种方法取决于您的特定需求和安全要求。

是的,您是对的。在 GKE Pod 中使用 Secret Manager 客户端库时,您不应检索密钥本身,而应直接使用密钥。

修改后的 Python 代码如下:

import os

from google.cloud import secretmanager
from google.cloud.secretmanager_v1.types import service

# Create a Secret Manager client.
client = secretmanager.SecretManagerServiceClient()

# Build the resource name of the secret version.
name = client.secret_version_path(
    "projects/my-project", "secrets/my-secret", "versions/latest"
)

# Access the secret version.
response = client.access_secret_version(request={"name": name})

# Parse the secret payload.
payload = response.payload.data.decode("UTF-8")
credentials = json.loads(payload)

# Use the credentials to access the API.
# ...

在上面的代码中,我们直接使用 response.payload.data,它包含秘密的实际值(例如,凭据)。

注意:

对于您描述的场景,可以按照以下步骤来实现:

  1. 创建 Secret

    • 在 Google Cloud Console 中,进入 Secret Manager 服务页面
    • 创建一个新的 Secret,并将您的账户和密码信息存储在其中,通常建议将账号和密码分别存储在两个不同的 Secret 中,以提高安全性。
  2. 配置工作负载身份(Workload Identity)

    • 在 GCP 项目中启用 Workload Identity 功能
    • 为您的 GKE 集群创建一个 Kubernetes Service Account(KSA)
    • 将 KSA 与 GCP 服务账户(Service Account)关联,并授予服务账户访问 Secret Manager 的权限。
  3. 访问 Secret 数据

    • 在 GKE 集群的 Pod 中,您可以使用 Google Cloud Client Libraries 或 Secret Manager API 来访问 Secret。
    • 使用步骤 2 中配置的 KSA 身份,您的应用程序可以无需提供任何凭证即可访问 Secret。
  4. Python 示例代码

需要注意的是,在实际应用中,您应当遵循最小权限原则,仅为工作负载身份(KSA)分配访问所需 Secret 的最小权限。另外,Secret 存储的敏感数据应当进行加密保护。

由于我们在步骤2中已经将Kubernetes Service Account(KSA)与GCP服务账户关联,并授予了访问Secret Manager的权限,因此在代码中就无需再显式提供任何认证凭证了。Google Cloud Client Libraries和Secret Manager API在运行时会自动从KSA的凭证中获取认证信息。

因此,对之前给出的Python示例代码进行调整,可以简化为:

from google.cloud import secretmanager

# 创建SecretManagerServiceClient实例,无需提供凭证
client = secretmanager.SecretManagerServiceClient()

# 构建Secret名称
project_id = "your-project-id"
secret_id_user = "your-user-secret-id"
secret_id_pass = "your-pass-secret-id"
user_secret_name = f"projects/{project_id}/secrets/{secret_id_user}/versions/latest"
pass_secret_name = f"projects/{project_id}/secrets/{secret_id_pass}/versions/latest"

# 访问Secret获取数据
user_response = client.access_secret_version(request={"name": user_secret_name})
user_payload = user_response.payload.data.decode("UTF-8")

pass_response = client.access_secret_version(request={"name": pass_secret_name})
pass_payload = pass_response.payload.data.decode("UTF-8")

# 使用账户和密码访问接口
# ...

在这个简化的版本中,我们完全移除了显式提供认证凭证的代码。Google Cloud Client Libraries会自动从KSA的凭证中获取所需的认证信息,从而能够无障碍地访问Secret Manager中的Secret。

这种通过Workload Identity进行无凭证访问的方式,不仅简化了代码,更重要的是增强了安全性,因为敏感凭证不会存在于代码或配置文件中,从而降低了泄露的风险。

aibangjuxin commented 7 months ago

要在 GKE 中使用 Workload Identity 来访问 Secret Manager 中存储的密钥,您需要执行以下步骤:

  1. 启用 Workload Identity 功能

    • 在 GCP 控制台中,进入您的项目
    • 导航到 "IAM & Admin" -> "Identity & Security"
    • 启用 "Workload Identity" 功能
  2. 创建 Kubernetes Service Account (KSA)

    • 在 GKE 集群的命名空间中创建一个 KSA
      kubectl create serviceaccount mysa -n myns
  3. 创建 GCP 服务账户并授权

    • 在 GCP 控制台中创建一个服务账户
    • 将服务账户与 KSA 关联
      gcloud iam service-accounts add-iam-policy-binding \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]" \
      SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com
    • 授予服务账户访问 Secret Manager 的权限
  4. 在 Pod 中使用 KSA 访问 Secret

    • 在 Pod 的 spec 中指定使用 KSA
      apiVersion: v1
      kind: Pod
      metadata:
      name: myapp
      spec:
      serviceAccountName: mysa
      containers:
      - name: main
       image: myimage
    • 在容器中使用 Google 客户端库访问 Secret Manager

      from google.cloud import secretmanager
      
      _, project = google.auth.default()
      client = secretmanager.SecretManagerServiceClient()
      name = f"projects/{project}/secrets/mysecret/versions/latest"
      payload = client.access_secret_version(request={"name": name}).payload.data.decode("UTF-8")

通过这些步骤,您的 GKE Pod 将使用其部署的 KSA 身份,并通过与 KSA 关联的 GCP 服务账户获得访问 Secret Manager 的权限。服务账户的凭证将被 Kubernetes 自动注入到 Pod 中,因此您无需在代码中显式提供它们。

aibangjuxin commented 7 months ago

启用 Workload Identity 功能:在 GCP 项目中启用 Workload Identity 功能。这个功能允许将 Kubernetes Service Account (KSA) 与 GCP 服务账户(Service Account) 关联起来。创建 Kubernetes Service Account(KSA):在你的 GKE 集群的特定 namespace 中创建一个 Kubernetes Service Account (KSA)。你可以使用以下命令:kubectl create serviceaccount --namespace= 关联 KSA 与 GCP 服务账户:通过给 KSA 添加 Annotation 的方式,将其关联到 GCP 服务账户上。Annotation 的格式为 iam.gke.io/gcp-service-account: 。例如:apiVersion: v1 kind: ServiceAccount metadata: name: namespace: annotations: iam.gke.io/gcp-service-account: 授予权限:确保你的 GCP 服务账户拥有访问 Secret Manager 的权限。你可以通过在 GCP IAM 中为服务账户添加相应的角色来实现。将账户和密码放在 GCP Secret Manager 中:将你的账户和密码存储在 GCP Secret Manager 中。你可以使用以下命令将其创建并添加到 Secret Manager 中:gcloud secrets create --data-file= Python 代码实现:编写 Python 代码,在 Pod 内部通过 Workload Identity 认证机制,访问 Secret Manager 中的凭据。你可以使用 GCP 的客户端库,例如 google-cloud-secret-manager,来从 Secret Manager 中获取凭据,并使用它们来访问你的接口地址。一个简单的示例代码可能如下所示:from google.cloud import secretmanager

def get_secret(): client = secretmanager.SecretManagerServiceClient() secret_name = "projects/your-project-id/secrets/your-secret-name/versions/latest" response = client.access_secret_version(name=secret_name) return response.payload.data.decode("UTF-8")

def main():

获取账户和密码

username = get_secret()
password = get_secret()

# 使用账户和密码访问接口地址
# 这里写你的代码逻辑...

if name == "main": main() 这样,你的 GKE Pod 就可以安全地访问 Secret Manager 中的凭据,并使用它们来访问你的接口地址了。

aibangjuxin commented 7 months ago

要实现您的场景,您需要按照以下步骤操作:

  1. 启用 Workload Identity 功能:首先,您需要在 Google Cloud Platform (GCP) 项目中启用 Workload Identity 功能。这允许您的 Google Kubernetes Engine (GKE) 集群中的应用程序使用 Google Cloud 服务账户的身份进行身份验证,而无需管理服务账户密钥[5]。

  2. 创建 Kubernetes Service Account (KSA):在您的 GKE 集群的特定命名空间中创建一个 Kubernetes Service Account (KSA)。这个 KSA 将被用来代表您的 Pod 进行身份验证和授权[3]。

  3. 创建 GCP 服务账户并关联 KSA:创建一个 GCP 服务账户,并将其与您刚创建的 KSA 关联。这样,当 KSA 被用于身份验证时,它将具有 GCP 服务账户的身份和权限[5]。

  4. 授予服务账户访问 Secret Manager 的权限:为您的 GCP 服务账户授予访问 Secret Manager 的权限。这样,当使用 KSA 进行身份验证时,它将能够访问存储在 Secret Manager 中的秘密[1]。

  5. 将账户和密码存储在 Secret Manager 中:在 Secret Manager 中创建一个新的秘密,将您想要在 Pod 中使用的账户和密码作为秘密的内容。确保您的 GCP 服务账户有权限访问这个秘密[1]。

  6. 在 Pod 中使用 Workload Identity 访问 Secret Manager:在您的 Pod 中,使用之前设置的 KSA 启动,并通过 Workload Identity 使用 GCP 服务账户的身份访问 Secret Manager。您可以使用 Google Cloud 的客户端库来从 Secret Manager 获取秘密的内容[2]。

具体的实现方式如下:

这样,您的 Pod 就可以在启动时使用 Workload Identity 通过 GCP 服务账户的身份安全地访问存储在 Secret Manager 中的账户和密码了。

Sources [1] 使用Secret Manager 创建和访问Secret - Google Cloud https://cloud.google.com/secret-manager/docs/create-secret-quickstart?hl=zh-cn [2] 使用客户端库访问存储在GKE 集群外部的Secret | Kubernetes Engine https://cloud.google.com/kubernetes-engine/docs/tutorials/workload-identity-secrets?hl=zh-cn [3] 使用Kubernetes 服务账号 https://cloud.google.com/kubernetes-engine/docs/how-to/kubernetes-service-accounts?hl=zh-cn [4] GKE 元数据服务器在Workload Identity 中是如何工作的 - DevPress官方社区 https://devpress.csdn.net/k8s/62ffc02fc67703293080614e.html [5] 使用适用于GKE 的工作负载身份联合 - Google Cloud https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity?hl=zh-cn [6] Kubernetes 的无服务器框架的评估 - 云原生社区 https://cloudnative.to/blog/evaluation-of-serverless-frameworks-for-kbe/ [7] 在权限管理中加入Google Cloud Platform (GCP) 项目 - Microsoft Learn https://learn.microsoft.com/zh-cn/entra/permissions-management/onboard-gcp [8] 快速入门:创建Secret | Secret Manager 文档 - Google Cloud https://cloud.google.com/secret-manager/docs/create-secret?hl=zh-cn [9] Google Cloud 中的Kubernetes 集群的要求 - NetApp https://docs.netapp.com/zh-cn/bluexp-kubernetes/requirements/kubernetes-reqs-gke.html [10] 使用舰队Workload Identity | 舰队管理 - Google Cloud https://cloud.google.com/anthos/fleet-management/docs/use-workload-identity?hl=zh-cn [11] 使用容器镜像库 - GitLab文档 https://docs.gitlab.cn/charts/charts/registry/ [12] 达曼区域访问| 文档 - Google Cloud https://cloud.google.com/docs/dammam-region-access?hl=zh-cn [13] GKE 服务账号简介| Google Kubernetes Engine (GKE) https://cloud.google.com/kubernetes-engine/docs/how-to/service-accounts?hl=zh-cn [14] 创建可用区级集群| Google Kubernetes Engine (GKE) https://cloud.google.com/kubernetes-engine/docs/how-to/creating-a-zonal-cluster?hl=zh-cn [15] 在加入完成后在权限管理中启用或禁用控制器 - Microsoft Learn https://learn.microsoft.com/zh-cn/entra/permissions-management/onboard-enable-controller-after-onboarding [16] 将您的开发者账号与Google 服务相关联- Play 管理中心帮助 https://support.google.com/googleplay/android-developer/answer/6110967?hl=zh-Hans [17] 在GCP中通过另一个项目授权访问项目 - 火山引擎 https://www.volcengine.com/theme/4292300-Z-7-1 [18] 第10 步(可选):在GKE 上配置Workload Identity | Apigee | Google Cloud https://cloud.google.com/apigee/docs/hybrid/v1.11/install-workload-identity?hl=zh-cn [19] 启用GKE 工作负载标识_devops_weixin_0010034-CI/CD - DevPress官方社区 https://devpress.csdn.net/cicd/62ee1014c6770329307f3275.html [20] 使用GKE 和Workload Identity 的应用无法通过Node.js 客户端库访问Secret Manager 的秘密。 - 火山引擎 https://www.volcengine.com/theme/7499271-S-7-1

aibangjuxin commented 7 months ago

要实现您的场景,我们需要按照以下步骤操作:

  1. 启用 Workload Identity:需要在 Google Cloud Platform (GCP) 项目中启用 Workload Identity。这可以通过 Google Cloud Console 或使用命令行工具(如 gcloud)来完成。

  2. 为 GKE 集群配置 Workload Identity:为您的 GKE 集群启用 Workload Identity,以便您的 Kubernetes Pods 可以使用 GCP 的服务账户。

  3. 创建 Kubernetes Service Account (KSA):在 GKE 集群中创建一个 Kubernetes Service Account(KSA),用于与 GCP 中的服务账户进行关联。

  4. 创建 GCP 服务账户:在 GCP 中创建一个服务账户,并授予它对 Secret Manager 的正确权限。

  5. 绑定 KSA 与 GCP 服务账户:将 Kubernetes Service Account 关联到 GCP 中的服务账户。

  6. 存储账户和密码:在 GCP 的 Secret Manager 中创建一个新的秘密,用于存储您的认证信息(账户和密码)。

  7. 在 Pod 中使用 KSA:配置 Deployment,以确保 Pod 启动时使用创建的 Kubernetes Service Account。

  8. 从 Pod 中访问 Secret Manager:在 Pod 中的应用程序使用 GCP 的 SDK 或者 API 客户端来通过与 Pod 关联的服务账户的身份从 Secret Manager 获取存储的账户和密码信息。

以下是详细的步骤和配置示例:

步骤 1: 启用 GKE 集群的 Workload Identity

gcloud container clusters update CLUSTER_NAME \
  --zone COMPUTE_ZONE \
  --workload-pool=PROJECT_ID.svc.id.goog

替换 CLUSTER_NAME, COMPUTE_ZONE, 和 PROJECT_ID 为您的集群名称,计算区域和项目ID。

步骤 2: 创建 Kubernetes Service Account (KSA)

kubectl create serviceaccount KSA_NAME --namespace KSA_NAMESPACE

替换 KSA_NAME 和 KSA_NAMESPACE 为您想要的 Service Account 名称和所属的命名空间。

步骤 3: 创建 GCP 服务账户

gcloud iam service-accounts create GCP_SA_NAME

替换 GCP_SA_NAME 为您的服务账户名称。

步骤 4: 授予服务账户相应的权限

gcloud projects add-iam-policy-binding PROJECT_ID \
  --member="serviceAccount:GCP_SA_NAME@PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/secretmanager.secretAccessor"

替换 PROJECT_ID 和 GCP_SA_NAME 为您的项目ID和服务账户名称。

步骤 5: 将 Kubernetes Service Account 关联到 GCP 服务账户

gcloud iam service-accounts add-iam-policy-binding \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:PROJECT_ID.svc.id.goog[KSA_NAMESPACE/KSA_NAME]" \
  GCP_SA_NAME@PROJECT_ID.iam.gserviceaccount.com

确保 --member 的值匹配您的项目ID、命名空间以及 KSA 名称。

步骤 6: 在 Kubernetes Service Account 中添加注释

kubectl annotate serviceaccount \
  --namespace KSA_NAMESPACE \
  KSA_NAME \
  http://iam.gke.io/gcp-service-account=GCP_SA_NAME@PROJECT_ID.iam.gserviceaccount.com

步骤 7: 配置您的 Deployment 以使用 KSA

在您的 Deployment YAML 文件中,确保您有这样的配置:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: DEPLOYMENT_NAME
spec:
  ...
  template:
    ...
    spec:
      serviceAccountName: KSA_NAME
      ...

在此示例中,您把 serviceAccountName 设置为您的 Kubernetes Service Account 名称。

步骤 8: 从 Pod 中访问 Secret Manager

现在您可以在 Pod 中的 Python 应用程序内部使用 Google Cloud 客户端库来获取 Secret Manager 中的秘密。确保您的代码使用的是与 Pod 关联的 GCP 服务账户的身份。这是一个 Python 代码片段示例:

from google.cloud import secretmanager

client = secretmanager.SecretManagerServiceClient()
name = f"projects/PROJECT_ID/secrets/SECRET_NAME/versions/latest"
response = client.access_secret_version(name=name)

secret_string = response.payload.data.decode("UTF-8")

在代码中替换 PROJECT_ID 和 SECRET_NAME。

整个操作过程涉及配置 Kubernetes 和 GCP 之间的适当权限和连接,以及在应用程序中安全地使用这些凭证。