添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

在大规模运行安全且动态的容器化应用程序时,密钥管理是难度较大却至关重要的一个方面。密钥需要安全地分发到正在运行的应用程序,Kubernetes 提供了原生功能来满足这一需求,将密钥以 Kubernetes 密钥 的形式进行管理。但是,许多客户选择使用外部密钥存储服务(如 Amazon Secrets Manager )来集中管理其 Kubernetes 集群之外的密钥,旨在改善其密钥使用的安全性、管理能力和可审计性。

使用外部密钥存储服务中的密钥通常需要修改应用程序代码,这样才能支持密钥存储服务特定的 API 调用,从而允许在应用程序运行时检索密钥。这可能会增加应用程序代码库的复杂性,并且可能降低容器化应用程序在环境之间移动,甚至利用不同的密钥存储服务时的可移植性。但是,在 Amazon EKS 上运行应用程序时,您有一个更简洁的替代方案,可以大幅减少代码更改。具体而言,您可以利用 Amazon Secrets and Configuration Provider (ASCP) 和 Kubernetes Secrets Store CSI Driver 。ASCP 充当 Amazon Secrets Manager 和 Kubernetes 环境之间的桥梁,将您的应用程序密钥作为挂载存储卷中的文件直接挂载到 Pod 中。此方法可简化管理并增强工作负载的可移植性,并且无需对应用程序级代码进行大量修改即可访问密钥。

本教程以本系列第 1 部分中的 Amazon EKS 集群为基础,详细介绍如何为 Kubernetes Secrets Store CSI Driver 设置 Amazon Secrets and Configuration Provider (ASCP)。上次教程的集群配置中包括 OpenID Connect (OIDC) 端点,供 ASCP 服务账户的 IAM 角色 (IRSA) 使用。如需本系列的第 1 部分,请参阅 构建为运行高流量微服务预配置的 Amazon EKS 集群。或者,若要使用本教程所需的组件设置现有集群,请遵循 EKS 官方文档中 创建 IAM OpenID Connect (OIDC) 端点 部分的说明。

在本教程中,您将学习如何为 Amazon EKS 集群上的 Kubernetes Secrets Store CSI Driver 设置 Amazon Secrets and Configuration Provider (ASCP),以及如何设置 Amazon Secrets Manager 来存储应用程序密钥。您将利用 ASCP 向在 EKS 上运行的应用程序公开密钥,从而提高工作负载的安全性和可移植性。

  • 安装最新版本的 kubectl 。若要检查版本,请运行: kubectl version --short
  • 已安装最新版本的 eksctl。若要检查版本,请运行: eksctl info
  • 安装最新版本的 Helm 。若要检查版本,请运行: helm version
  • 已安装最新版本的 Amazon CLI (v2) 。若要检查版本,请运行: aws --version
  • 已获取在现有 EKS 集群上配置的 IAM OIDC 提供商
  • 本教程是使用 Amazon EKS 管理高流量微服务平台系列的一部分,专门介绍如何使用 Kubernetes Secrets Store CSI Driver Amazon Secrets and Configuration Provider (ASCP) 管理应用程序密钥。本教程不仅会展示如何使用 EKS 工作负载中的外部密钥,还会展示如何在 Amazon Secrets Manager 中创建密钥。本教程包括以下部分:

  • 创建密钥 — 在 Amazon Secrets Manager 中创建应用程序密钥,供示例 Pod 使用。
  • 验证身份 — 这是服务账户的 IAM 角色(IRSA)映射所需的,用于启用 Kubernetes Pod 与亚马逊云科技服务之间的通信。这包括将用于通过 Amazon Secrets and Configuration Provider (ASCP) 访问 Amazon Secrets Manager 密钥的 Pod 服务账户。
  • 设置 ASCP — 部署 Amazon Secrets and Configuration Provider (ASCP) 和 Kubernetes Secrets Store CSI Driver
  • 部署示例应用程序 — 部署示例 Pod 以从 Amazon Secrets Manager 挂载密钥,并在 Pod 中执行命令以验证密钥是否可访问。
  • 步骤 1:设置环境变量

    在使用 Helm 或其他命令行工具与 Amazon EKS 集群进行交互之前,请务必定义好封装集群详细信息的特定环境变量。这些变量将在后续命令中使用,确保它们指向正确的集群和资源。

  • 首先,请确认您是在正确的集群上下文中进行操作。这样可确保任何后续命令可以发送到预期的 Kubernetes 集群。您可以执行以下命令来验证当前上下文:
  • kubectl config current-context
    Code snippet copied
  • 为 EKS 集群定义 CLUSTER_NAME 环境变量。替换集群 region 的示例值。如果您使用的是自己的现有 EKS 集群,请替换 name 的示例值。
  • export CLUSTER_NAME=$(aws eks describe-cluster --region us-east-2 --name managednodes-quickstart --query "cluster.name" --output text)
    Code snippet copied
  • 为 EKS 集群定义 CLUSTER_REGION 环境变量。替换集群 region 的示例值。
  • export CLUSTER_REGION=$(aws eks describe-cluster --name ${CLUSTER_NAME} --region us-east-2 --query "cluster.arn" --output text | cut -d: -f4)
    Code snippet copied

    若要验证变量是否已设置正确,请运行以下命令。验证输出是否与特定输入相匹配。

    echo $CLUSTER_REGION
    echo $CLUSTER_NAME
    Code snippet copied

    步骤 2:在 Amazon Secrets Manager 中创建密钥

    在 Amazon Secrets Manager 中创建密钥是安全管理应用程序敏感信息的首要步骤。您将使用 Amazon CLI 存储一个示例密钥,稍后 Kubernetes 集群会访问该密钥。这样就无需在应用程序中对敏感信息进行硬编码,从而增强了安全性。

    SECRET_ARN=$(aws secretsmanager create-secret --name eksSecret --secret-string '{"username":"eksdemo", "password":"eksRocks!"}' --region "$CLUSTER_REGION" --query ARN) 
    Code snippet copied

    上述命令会将密钥的 ARN 存储在变量中,以供后续使用。若要验证密钥是否已创建成功,请运行以下命令输出变量:

    echo $SECRET_ARN
    Code snippet copied

    预期的输出应如下所示:

    "arn:aws:secretsmanager:us-east-2:0123456789:secret:eksSecret-JeuuzY"
    Code snippet copied

    步骤 3:创建用于在 Amazon Secrets Manager 中访问密钥的 IAM 策略

    在这一步中,您将使用 Amazon CLI 创建一个 IAM 策略,该策略会授予特定权限来访问存储在 Amazon Secrets Manager 中的密钥。通过使用上一步中的 $SECRET_ARN 变量,您将指定 IAM 策略要应用于哪个密钥。此方法可确保 Kubernetes 集群中获得授权的实体只能访问指定的密钥。在下一步中,我们会将此 IAM 策略关联到 Kubernetes 服务账户。

    POLICY_ARN=$(aws --region "$CLUSTER_REGION" --query Policy.Arn --output text iam create-policy --policy-name eksdemo-secretsmanager-policy --policy-document '{
     "Version": "2012-10-17",
     "Statement": [ {
     "Effect": "Allow",
     "Action": ["secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret"],
     "Resource": ['$SECRET_ARN']
              Code snippet copied 
            

    上述命令会将该策略的 ARN 存储在变量中,以供后续使用。若要验证策略是否已创建成功,请运行以下命令输出变量:

    echo $POLICY_ARN
    Code snippet copied

    预期的输出应如下所示:

    `arn:aws:iam::0123456789:policy/eksdemo-secretsmanager-policy`
    Code snippet copied

    步骤 4:创建 IAM 角色并与 Kubernetes 服务账户关联

    在这一步中,您将使用服务账户的 IAM 角色 (IRSA) 将 Kubernetes 服务账户映射到 Amazon IAM 角色,从而为在 EKS 上运行的应用程序启用精细化的权限管理。您将使用 eksctl 创建一个 Amazon IAM 角色,并将其与 EKS 集群中的特定 Kubernetes 服务账户相关联。您还将使用 Secret Store CSI Driver 在应用程序 Pod 级别(而非 CSI 驱动程序 Pod 级别)应用 IAM 权限。这样可以确保只有利用 IRSA 关联的 Kubernetes 服务账户的特定应用程序 Pod 才有权访问存储在 Amazon Secrets Manager 中的密钥。我们会将在上一步中创建的 IAM 策略关联到新创建的 IAM 角色。请注意,在运行这些命令之前,您必须具有与集群相关联的 OpenID Connect (OIDC) 端点

    eksctl create iamserviceaccount --name eksdemo-secretmanager-sa --region="$CLUSTER_REGION" --cluster "$CLUSTER_NAME" --attach-policy-arn "$POLICY_ARN" --approve --override-existing-serviceaccounts
    Code snippet copied 完成后,您应当会看到以下输出结果:
    [2023-08-07 15](tel:2023080715):45:32 [ℹ] created serviceaccount "default/eksdemo-secretmanager-sa"
    Code snippet copied 确保在集群的“default”命名空间中正确设置了“eksdemo-secretmanager-sa”服务账户。
    kubectl get sa eksdemo-secretmanager-sa -o yaml
    Code snippet copied

    预期的输出应如下所示:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
     annotations:
     eks.amazonaws.com/role-arn: arn:aws:iam::01234567890:role/eksctl-managednodes-quickstart-addon-iamserv-Role1-WRJJQSRMC4LK
     creationTimestamp: "2023-09-12T18:32:23Z"
     labels:
     app.kubernetes.io/managed-by: eksctl
     name: eksdemo-secretmanager-sa
     namespace: default
     resourceVersion: "4456"
     uid: 5c7989b7-2cdb-42f6-a9ee-db20a7e484d9
    Code snippet copied

    步骤 5:安装 ASCP 和 Secrets Store CSI Driver

    在这一步中,您将使用 Helm 安装 Amazon Secrets and Configuration Provider (ASCP) 和 Secrets Store CSI Driver,二者会在 Amazon Secrets Manager 和 Kubernetes 集群之间建立安全的桥梁。这样,您的集群就能够访问存储在 Amazon Secrets Manager 中的密钥,并且无需对应用程序代码进行复杂的更改。ASCP 和 Secrets Store CSI Driver 将分别作为 DaemonSet 进行安装,确保驱动程序和提供程序的副本可以在集群中的每个节点上运行。

    以下命令会将 Secrets Store CSI Driver Helm 图表存储库添加到本地 Helm 索引以允许安装:

    helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts
    Code snippet copied

    预期的输出应如下所示:

    "secrets-store-csi-driver" has been added to your repositories
    Code snippet copied

    以下命令会将 Amazon Secrets and Configuration Provider (ASCP) Helm 图表存储库添加到本地 Helm 索引以允许安装:

    helm repo add aws-secrets-manager https://aws.github.io/secrets-store-csi-driver-provider-aws
    Code snippet copied

    预期的输出应如下所示:

    "aws-secrets-manager" has been added to your repositories
    Code snippet copied

    若要安装 Secrets Store CSI Driver,请运行以下 Helm 命令:

    helm install -n kube-system csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver
    Code snippet copied

    预期的输出应如下所示:

    NAME: csi-secrets-store
    LAST DEPLOYED: Fri Sep 29 17:30:00 2023
    NAMESPACE: kube-system
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    NOTES:
    The Secrets Store CSI Driver is getting deployed to your cluster.
    To verify that Secrets Store CSI Driver has started, run:
    kubectl --namespace=kube-system get pods -l "app=secrets-store-csi-driver"
    Now you can follow these steps https://secrets-store-csi-driver.sigs.k8s.io/getting-started/usage.html
    to create a SecretProviderClass resource, and a deployment using the SecretProviderClass.
    Code snippet copied

    如输出内容所述,若要验证 Secrets Store CSI Driver 是否已启动,请运行以下命令:

    kubectl --namespace=kube-system get pods -l "app=secrets-store-csi-driver"
    Code snippet copied

    您应当会看到以下输出结果。确保所有 Pod 的 STATUS 均为 Running:

    NAME READY STATUS RESTARTS AGE
    csi-secrets-store-secrets-store-csi-driver-5l4sr 3/3 Running 0 2m31s
    csi-secrets-store-secrets-store-csi-driver-jhbnf 3/3 Running 0 2m31s
    csi-secrets-store-secrets-store-csi-driver-qsdm6 3/3 Running 0 2m31s
    Code snippet copied

    若要安装 Amazon Secrets and Configuration Provider(ASCP),请运行以下 Helm 命令:

    helm install -n kube-system secrets-provider-aws aws-secrets-manager/secrets-store-csi-driver-provider-aws
    Code snippet copied

    预期的输出应如下所示:

    NAME: secrets-provider-aws
    LAST DEPLOYED: Tue Sep 12 18:33:45 2023
    NAMESPACE: kube-system
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    Code snippet copied

    您还可以运行以下 Helm 命令来验证安装是否已完成:

    `helm list -n kube-system` 
    Code snippet copied

    您会看到如下输出结果:

    NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
    csi-secrets-store kube-system [1 2023-08-07 15](tel:12023080715):39:24.856932796 +0000 UTC deployed secrets-store-csi-driver-1.3.4 1.3.4
    secrets-provider-aws kube-system [1 2023-08-07 15](tel:12023080715):39:55.851595668 +0000 UTC deployed secrets-store-csi-driver-provider-aws-0.3.4
    Code snippet copied

    步骤 6:创建 ASCP SecretProviderClass 资源

    在这一步中,您将定义 SecretProviderClass Kubernetes 对象,该对象为 Kubernetes 工作负载中的无缝密钥管理奠定了基础。这个资源充当 Amazon Secrets and Configuration Provider (ASCP) 的一组指令,指定哪些密钥可以从 Amazon Secrets Manager 中获取以及如何将这些密钥挂载到 Pod 中。请注意,SecretProviderClass 必须部署在与引用它的工作负载相同的命名空间中。若要了解详细信息,请参阅 SecretProviderClass 文档

    创建名为 eksdemo-spc.yaml 的 Kubernetes 清单,并将以下内容粘贴到其中:

    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
     name: eks-demo-aws-secrets
     namespace: default
    spec:
     provider: aws
     parameters:
     objects: |
     - objectName: "eksSecret"
     objectType: "secretsmanager"
    Code snippet copied

    应用 YAML 清单。

    `kubectl apply -f eksdemo-spc.yaml`
    Code snippet copied

    若要验证 SecretProviderClass 是否已创建成功,请运行以下命令:

    kubectl describe secretproviderclass eks-demo-aws-secrets
    Code snippet copied

    预期的输出应如下所示:

    Name: eks-demo-aws-secrets
    Namespace: default
    Labels: <none>
    Annotations: <none>
    API Version: secrets-store.csi.x-k8s.io/v1
    Kind: SecretProviderClass
    Metadata:
     Creation Timestamp: 2023-08-09T21:13:50Z
     Generation: 1
     Resource Version: 9853
     UID: d11bbadc-f3c8-4e70-8b1e-effe72b1518e
    Spec:
     Parameters:
     Objects: - objectName: "eksSecret"
     objectType: "secretsmanager"
     Provider: aws
    Events: <none>
    Code snippet copied

    步骤 7:部署示例工作负载以使用密钥

    在这一步中,您将部署一个示例工作负载,以桥接您的应用程序和 Amazon Secrets Manager。通过将密钥作为文件挂载到工作负载的文件系统上,您将完成在 Kubernetes 环境中安全管理和访问密钥的端到端过程。在 Pod 模板中,您将指定 Secrets Store CSI 作为卷驱动程序,然后指定挂载密钥的路径,操作方式与挂载传统卷相同。在此示例中,我们将在 /mnt/secrets-store 位置挂载密钥。

    创建名为 eksdemo-app.yaml 的 Kubernetes 清单,并将以下内容粘贴到其中:

    apiVersion: v1
    kind: Pod
    metadata:
     name: busybox
     namespace: default
    spec:
     serviceAccountName: eksdemo-secretmanager-sa
     volumes:
     - name: secrets-store-inline
     driver: secrets-store.csi.k8s.io
     readOnly: true
     volumeAttributes:
     secretProviderClass: "eks-demo-aws-secrets"
     containers:
     - image: public.ecr.aws/docker/library/busybox:1.36
     command:
     - sleep
     - "3600"
     imagePullPolicy: IfNotPresent
     name: busybox
     volumeMounts:
     - name: secrets-store-inline
     mountPath: "/mnt/secrets-store"
     readOnly: true
     restartPolicy: Always
    Code snippet copied

    应用 YAML 清单。

    `kubectl apply ``-``f eksdemo-app.yaml`
    Code snippet copied

    若要验证 Pod 是否已创建成功,请运行以下命令:

    kubectl get pod busybox
    Code snippet copied

    您应当会看到以下输出结果。确保 Pod STATUS 为 Running:

    NAME READY STATUS RESTARTS AGE
    busybox 1/1 Running 0 11s
    Code snippet copied # Delete the SecretProviderClass Resources kubectl delete secretproviderclass eks-demo-aws-secrets # Remove IAM Roles for Service Accounts (IRSA `eksctl ``delete`` iamserviceaccount` --cluster="$CLUSTER_NAME" --name=eksdemo-secretmanager-sa --region="$CLUSTER_REGION" # Delete AWS Secrets Manager Secret without recovery window aws secretsmanager delete-secret --secret-id eksSecret --region "$CLUSTER_REGION" --force-delete-without-recovery # Uninstall the AWS Secrets and Configuration Provider helm uninstall -n kube-system csi-secrets-store helm uninstall -n kube-system secrets-provider-aws # Delete IAM Policy aws iam delete-policy --policy-arn $POLICY_ARN
    Code snippet copied AWS 对 Internet Explorer 的支持将于 07/31/2022 结束。受支持的浏览器包括 Chrome、Firefox、Edge 和 Safari。 了解详情 »