Kubernetes 的 secret 并不是真正的 secret(下)

简介: Kubernetes 的 secret 并不是真正的 secret

使用 HashiCorp Vault

HashiCorp Vault 是一个流行的 secret 管理器,提供不同的 secret 引擎。ESO 只能与 Vault 提供的 KV Secrets Engine 一起使用。Vault 在 HashiCorp 云平台 (HCP) 上提供了一个您可以自行管理的免费开源版本和一个带有免费等级的托管版本。

确保您在本地 Vault 实例或 HCP cloud 中设置了键值 secret 存储。您还可以使用 Vault Helm chart 将 Vault 部署到 Kubernetes 集群。

  1. 创建一个新的 SecretStore CRD,vault-backend.yaml,以定义与 Vault 的连接详细信息。
# vault-backend.yaml
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: vault-backend
spec:
  provider:
    vault:
      server: 'YOUR_VAULT_ADDRESS'
      path: 'secret'
      version: 'v2'
      namespace: 'admin' # required for HCP Vault
      auth:
        # points to a secret that contains a vault token
        # https://www.vaultproject.io/docs/auth/token
        tokenSecretRef:
          name: 'vault-token'
          key: 'token'
  1. 创建一个 secret 资源来保存 Vault token。使用具有对 Vault KV 存储中的 secret/ 路径具有读取权限的策略的令牌。
kubectl create secret generic vault-token \
  --dry-run=client \
  --from-literal=token=YOUR_VAULT_TOKEN
  1. 在 Vault 中创建一个 secret 。如果您使用的是 Vault CLI,则可以使用以下命令创建一个 secret 。确保您使用适当的策略从 CLI 登录到 vault 实例。
vault kv put secret/mysecret my-value=supersecret
  1. 创建一个 ExternalSecret CRD 来定义需要从 Vault 中获取的数据。
# vault-secret.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: vault-example
spec:
  refreshInterval: '15s'
  secretStoreRef:
    name: vault-backend
    kind: SecretStore
  target:
    name: vault-example-sync
  data:
    - secretKey: secret-from-vault
      remoteRef:
        key: secret/mysecret
        property: my-value
  1. 将上述 CRD 应用到集群,它应该使用从 Vault 获取的数据创建一个名为 vault-example-sync 的 Kubernetes secret。
kubectl apply -f vault-backend.yaml
kubectl apply -f vault-secret.yaml

您可以使用 kubectl describe 命令查看集群中的 secret。

kubectl describe secret vault-example-sync
# output should have the below data
Name:         vault-example-sync
Namespace:    default
Labels:       <none>
Annotations:  reconcile.external-secrets.io/data-hash: ...
Type:  Opaque
Data
====
secret-from-vault:  16 bytes

如果您在创建 secret 时遇到问题,请检查 ExternalSecret 资源描述输出的 events 部分。

kubectl describe externalsecret vault-example

如果您看到权限错误,请确保使用具有正确策略的令牌。

其他 secret managers

设置其他 secret 管理器与上述步骤类似。唯一的区别是 SecretStore CRD 和 ExternalSecret CRD 中的 remoteRef 部分。您可以在 ESO 文档中找到针对不同提供商的官方指南。


Secrets Store CSI Driver

Secrets Store CSI Driver 是一个原生的上游 Kubernetes 驱动程序,可用于从工作负载中抽象出 secret 的存储位置。如果您想使用云提供商的 secret 管理器而不将 secret 公开为 Kubernetes secret 对象,您可以使用 CSI 驱动程序将 secret 作为卷安装在您的 pod 中。如果您使用云提供商来托管您的 Kubernetes 集群,这是一个很好的选择。该驱动程序支持许多云提供商,并且可以与不同的 secret 管理器一起使用。

Secrets Store CSI Driver

Secrets Store CSI Driver 是一个 daemonset 守护进程,它与 secret 提供者通信以检索 SecretProviderClass 自定义资源中指定的 secret 。

它的工作原理如下;

  1. 创建一个 SecretProviderClassCRD 来定义从 secret 提供者获取的 secret 的详细信息。
  2. 在 pod 的 volume spec 中引用 SecretProviderClass
  3. 驱动程序将从 secret 提供者那里获取 secret ,并在 pod 启动期间将其作为 tmpfs 卷挂载到 pod 中。该卷也将在 pod 删除后被删除。

驱动程序还可以同步对 secret 的更改。该驱动程序目前支持 Vault、AWS、Azure 和 GCP 提供商。Secrets Store CSI Driver 也可以将加密数据同步为 Kubernetes secret,只需要在安装期间明确启用此行为。

优点

  • secret 存储在安全的外部 secret 管理器中,而不是代码存储库中。
  • 使机密与外部机密管理器保持同步。它还支持 secret 的轮换。
  • 与所有主要的外部 secret 管理者合作。
  • 将密钥作为卷安装在 pod 中,因此它们不会作为 Kubernetes secret 公开。它也可以配置为创建 Kubernetes secret。

缺点

  • 需要精心设置才能使用,并且比 ESO 更复杂。
  • 使用比 ESO 更多的资源,因为它需要在每个节点上运行。
  • 依赖于外部 secret 存储及其访问策略来确保安全。

使用 Google Secret Manager provider

让我们看看如何配置 driver 以使用 Google Secret Manager (GSM) 作为 secret provider。

确保您使用的是启用了 Workload Identity 功能的 Google Kubernetes Engine (GKE) 集群。Workload Identity 允许 GKE 集群中的工作负载模拟身份和访问管理 (IAM) 服务帐户来访问 Google Cloud 服务。您还需要为项目启用 Kubernetes Engine API、Secret Manager API 和 Billing。如果未启用, gcloud CLI 会提示您启用这些 API。

可以使用以下 gcloud CLI 命令创建启用了 Workload Identity 的新集群。

export PROJECT_ID=<your gcp project>
gcloud config set project $PROJECT_ID
gcloud container clusters create hello-hipster \
  --workload-pool=$PROJECT_ID.svc.id.goog

安装 Secrets Store CSI Driver

可以使用 Helm 命令在集群上安装 Secrets Store CSI 驱动程序:

helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts
helm install csi-secrets-store \
    secrets-store-csi-driver/secrets-store-csi-driver \
    --namespace kube-system

这将在 kube-system 命名空间下安装驱动程序和 CRD 。您还需要将所需的 provider 安装到集群中。

安装 GSM provider

让我们将 GSM provider 安装到集群中:

kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/secrets-store-csi-driver-provider-gcp/main/deploy/provider-gcp-plugin.yaml

创建 secret

首先,您需要设置一个工作负载身份服务帐户。

# Create a service account for workload identity
gcloud iam service-accounts create gke-workload
# Allow "default/mypod" to act as the new service account
gcloud iam service-accounts add-iam-policy-binding \
    --role roles/iam.workloadIdentityUser \
    --member "serviceAccount:$PROJECT_ID.svc.id.goog[default/mypodserviceaccount]" \
    gke-workload@$PROJECT_ID.iam.gserviceaccount.com

现在让我们创建一个该服务帐户可以访问的密钥。

# Create a secret with 1 active version
echo "mysupersecret" > secret.data
gcloud secrets create testsecret --replication-policy=automatic --data-file=secret.data
rm secret.data
# grant the new service account permission to access the secret
gcloud secrets add-iam-policy-binding testsecret \
    --member=serviceAccount:gke-workload@$PROJECT_ID.iam.gserviceaccount.com \
    --role=roles/secretmanager.secretAccessor

现在您可以创建一个 SecretProviderClass 资源,用于从 GSM 获取密钥。请记住将 $PROJECT_ID 替换为您的 GCP 项目 ID。

# secret-provider-class.yaml
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: app-secrets
spec:
  provider: gcp
  parameters:
    secrets: |
      - resourceName: "projects/$PROJECT_ID/secrets/testsecret/versions/latest"
        path: "good1.txt"
      - resourceName: "projects/$PROJECT_ID/secrets/testsecret/versions/latest"
        path: "good2.txt"

创建一个 Pod

现在您可以创建一个 pod 去使用该 SecretProviderClass 资源从 GSM 获取密钥。请记住将 $PROJECT_ID 替换为您的 GCP 项目 ID。

# my-pod.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: mypodserviceaccount
  namespace: default
  annotations:
    iam.gke.io/gcp-service-account: gke-workload@$PROJECT_ID.iam.gserviceaccount.com
---
apiVersion: v1
kind: Pod
metadata:
  name: mypod
  namespace: default
spec:
  serviceAccountName: mypodserviceaccount
  containers:
    - image: gcr.io/google.com/cloudsdktool/cloud-sdk:slim
      imagePullPolicy: IfNotPresent
      name: mypod
      resources:
        requests:
          cpu: 100m
      stdin: true
      stdinOnce: true
      terminationMessagePath: /dev/termination-log
      terminationMessagePolicy: File
      tty: true
      volumeMounts:
        - mountPath: '/var/secrets'
          name: mysecret
  volumes:
    - name: mysecret
      csi:
        driver: secrets-store.csi.k8s.io
        readOnly: true
        volumeAttributes:
          secretProviderClass: 'app-secrets'

将上述资源应用到集群中。

kubectl apply -f secret-provider-class.yaml
kubectl apply -f my-pod.yaml

等待 pod 启动,然后 exec 进入 pod 查看挂载文件的内容。

kubectl exec -it mypod /bin/bash
# execute the below command in the pod to see the contents of the mounted secret file
root@mypod:/# cat /var/secrets/good1.txt

其他 secret 管理器

您可以找到服务提供商的类似指南:AWS CSI provider、Azure CSI provider 和 Vault CSI provider。


结论

Sealed Secrets 是小型团队和项目在 Git 中保护 secret 的绝佳解决方案。对于较大的团队和项目,External Secrets OperatorSecrets Store CSI Driver 是安全管理密钥的更好的解决方案。External Secrets Operator 可以与许多 secret 管理系统一起使用,并不限于上述系统。当然,这应该与 RBAC 一起使用,以防止非管理员读取集群中的 secret 。Secrets Store CSI Driver 可能比 ESO 涉及更多,但它是一个更原生的解决方案。

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
目录
相关文章
|
11天前
|
存储 Kubernetes 数据安全/隐私保护
k8s学习-Secret(创建、使用、更新、删除等)
k8s学习-Secret(创建、使用、更新、删除等)
227 0
|
8月前
|
存储 Kubernetes API
Kubernetes 的 secret 并不是真正的 secret(上)
Kubernetes 的 secret 并不是真正的 secret
76 0
|
11天前
|
存储 Kubernetes 数据安全/隐私保护
Kubernetes的ConfigMap和Secret
Kubernetes的ConfigMap和Secret
45 0
|
9月前
|
存储 Kubernetes 数据安全/隐私保护
k8s--配置存储 ConfigMap、Secret
k8s--配置存储 ConfigMap、Secret
|
11天前
|
Kubernetes 数据安全/隐私保护 Docker
云原生|kubernetes|关于secret的一些使用
云原生|kubernetes|关于secret的一些使用
76 0
|
11天前
|
Kubernetes 容器
k8s学习-CKS真题-secret创建、使用
k8s学习-CKS真题-secret创建、使用
52 0
|
10月前
|
存储 Kubernetes 安全
【k8s 系列】k8s 学习二十三-2,ConfigMap 补充 和 Secret
对于上一篇文章我们分享了为什么要使用 ConfigMap ,我们创建 ConfigMap 的时候可以传入单个或者多个键值对,也可以传入文件,还分享了如何简单的传入 ConfigMap 里面的数据作为环境变量
|
存储 JSON 缓存
kubernetes secret使用详解(2)
kubernetes secret使用详解(2)
|
Kubernetes Shell API
kubernetes secret使用详解(1)
kubernetes secret使用详解(1)
kubernetes secret使用详解(1)
|
Kubernetes Cloud Native 应用服务中间件
云原生|kubernetes|关于secret的一些使用(二)
云原生|kubernetes|关于secret的一些使用
118 0