×

使用 Secrets Store CSI 驱动程序和 GitOps 管理密钥概述

某些应用程序需要敏感信息,例如密码和用户名,这些信息必须作为良好的安全实践加以隐藏。如果由于在集群上未正确配置基于角色的访问控制 (RBAC) 而导致敏感信息泄露,则任何具有 API 或 etcd 访问权限的人员都可以检索或修改密钥。

任何有权在命名空间中创建 Pod 的人都可以使用该 RBAC 读取该命名空间中的任何密钥。使用 SSCSI 驱动程序操作符,您可以使用外部密钥存储库安全地存储和向 Pod 提供敏感信息。

将 OpenShift Container Platform SSCSI 驱动程序与 GitOps Operator 集成的过程包括以下步骤

优势

将 SSCSI 驱动程序与 GitOps Operator 集成可提供以下优势

  • 增强 GitOps 工作流的安全性和效率

  • 促进将密钥作为卷安全地附加到部署 Pod 中

  • 确保安全高效地访问敏感信息

密钥存储提供程序

以下密钥存储提供程序可用于 Secrets Store CSI 驱动程序操作符

  • AWS Secrets Manager

  • AWS Systems Manager 参数存储

  • Microsoft Azure Key Vault

例如,假设您使用 AWS Secrets Manager 作为您的密钥存储提供程序,并使用 SSCSI Driver Operator。以下示例显示了 GitOps 仓库中准备使用 AWS Secrets Manager 中密钥的目录结构。

GitOps 仓库中的示例目录结构
├── config
│   ├── argocd
│   │   ├── argo-app.yaml
│   │   ├── secret-provider-app.yaml (3)
│   │   ├── ...
│   └── sscsid (1)
│       └── aws-provider.yaml (2)
├── environments
│   ├── dev (4)
│   │   ├── apps
│   │   │   └── app-taxi (5)
│   │   │       ├── ...
│   │   ├── credentialsrequest-dir-aws (6)
│   │   └── env
│   │       ├── ...
│   ├── new-env
│   │   ├── ...
1 存储aws-provider.yaml文件的目录。
2 安装 AWS Secrets Manager 提供程序并为其部署资源的配置文件。
3 创建应用程序并为 AWS Secrets Manager 部署资源的配置文件。
4 存储部署 Pod 和凭据请求的目录。
5 存储SecretProviderClass资源以定义密钥存储提供程序的目录。
6 存储credentialsrequest.yaml文件的文件夹。此文件包含将密钥挂载到部署 Pod 的凭据请求配置。

先决条件

  • 您具有使用cluster-admin权限访问集群的权限。

  • 您可以访问 OpenShift Container Platform Web 控制台。

  • 您已提取并准备了ccoctl二进制文件。

  • 您已安装jq CLI 工具。

  • 您的集群安装在 AWS 上并使用 AWS 安全令牌服务 (STS)。

  • 您已配置 AWS Secrets Manager 以存储所需的密钥。

  • SSCSI Driver Operator 已安装在您的集群上。.

  • Red Hat OpenShift GitOps Operator 已安装在您的集群上。

  • 您有一个 GitOps 仓库,可以准备使用密钥。

  • 您已使用 Argo CD 管理员帐户登录到 Argo CD 实例。

在 GitOps 仓库中存储 AWS Secrets Manager 资源

本指南提供带有示例的说明,以帮助您将 GitOps 工作流与 Secrets Store Container Storage Interface (SSCSI) Driver Operator 结合使用,将密钥从 AWS Secrets Manager 挂载到 OpenShift Container Platform 中的 CSI 卷。

在托管控制平面集群中不支持将 SSCSI Driver Operator 与 AWS Secrets Manager 结合使用。

先决条件
  • 您具有使用cluster-admin权限访问集群的权限。

  • 您可以访问 OpenShift Container Platform Web 控制台。

  • 您已提取并准备了ccoctl二进制文件。

  • 您已安装jq CLI 工具。

  • 您的集群安装在 AWS 上并使用 AWS 安全令牌服务 (STS)。

  • 您已配置 AWS Secrets Manager 以存储所需的密钥。

  • SSCSI Driver Operator 已安装在您的集群上。.

  • Red Hat OpenShift GitOps Operator 已安装在您的集群上。

  • 您有一个 GitOps 仓库,可以准备使用密钥。

  • 您已使用 Argo CD 管理员帐户登录到 Argo CD 实例。

步骤
  1. 安装 AWS Secrets Manager 提供程序并添加资源

    1. 在您的 GitOps 仓库中,创建一个目录,并在其中添加aws-provider.yaml文件,其中包含以下配置以部署 AWS Secrets Manager 提供程序的资源。

      SSCSI 驱动程序的 AWS Secrets Manager 提供程序是上游提供程序。

      此配置是从上游AWS 文档中提供的配置修改而来的,以便它能够与 OpenShift Container Platform 正确配合使用。对该配置的更改可能会影响功能。

      aws-provider.yaml文件示例
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: csi-secrets-store-provider-aws
        namespace: openshift-cluster-csi-drivers
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: csi-secrets-store-provider-aws-cluster-role
      rules:
      - apiGroups: [""]
        resources: ["serviceaccounts/token"]
        verbs: ["create"]
      - apiGroups: [""]
        resources: ["serviceaccounts"]
        verbs: ["get"]
      - apiGroups: [""]
        resources: ["pods"]
        verbs: ["get"]
      - apiGroups: [""]
        resources: ["nodes"]
        verbs: ["get"]
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: csi-secrets-store-provider-aws-cluster-rolebinding
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: csi-secrets-store-provider-aws-cluster-role
      subjects:
      - kind: ServiceAccount
        name: csi-secrets-store-provider-aws
        namespace: openshift-cluster-csi-drivers
      ---
      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
        namespace: openshift-cluster-csi-drivers
        name: csi-secrets-store-provider-aws
        labels:
          app: csi-secrets-store-provider-aws
      spec:
        updateStrategy:
          type: RollingUpdate
        selector:
          matchLabels:
            app: csi-secrets-store-provider-aws
        template:
          metadata:
            labels:
              app: csi-secrets-store-provider-aws
          spec:
            serviceAccountName: csi-secrets-store-provider-aws
            hostNetwork: false
            containers:
              - name: provider-aws-installer
                image: public.ecr.aws/aws-secrets-manager/secrets-store-csi-driver-provider-aws:1.0.r2-50-g5b4aca1-2023.06.09.21.19
                imagePullPolicy: Always
                args:
                    - --provider-volume=/etc/kubernetes/secrets-store-csi-providers
                resources:
                  requests:
                    cpu: 50m
                    memory: 100Mi
                  limits:
                    cpu: 50m
                    memory: 100Mi
                securityContext:
                  privileged: true
                volumeMounts:
                  - mountPath: "/etc/kubernetes/secrets-store-csi-providers"
                    name: providervol
                  - name: mountpoint-dir
                    mountPath: /var/lib/kubelet/pods
                    mountPropagation: HostToContainer
            tolerations:
            - operator: Exists
            volumes:
              - name: providervol
                hostPath:
                  path: "/etc/kubernetes/secrets-store-csi-providers"
              - name: mountpoint-dir
                hostPath:
                  path: /var/lib/kubelet/pods
                  type: DirectoryOrCreate
            nodeSelector:
              kubernetes.io/os: linux
    2. 在您的 GitOps 仓库中添加一个secret-provider-app.yaml文件,以创建应用程序并为 AWS Secrets Manager 部署资源。

      secret-provider-app.yaml文件示例
      apiVersion: argoproj.io/v1alpha1
      kind: Application
      metadata:
        name: secret-provider-app
        namespace: openshift-gitops
      spec:
        destination:
          namespace: openshift-cluster-csi-drivers
          server: https://kubernetes.default.svc
        project: default
        source:
          path: path/to/aws-provider/resources
          repoURL: https://github.com/<my-domain>/<gitops>.git (1)
        syncPolicy:
          automated:
          prune: true
          selfHeal: true
      1 更新repoURL字段的值以指向您的 GitOps 仓库。
  2. 与默认 Argo CD 实例同步资源以将其部署到集群中。

    1. 为您的应用程序部署所在的openshift-cluster-csi-drivers命名空间添加标签,以便openshift-gitops命名空间中的 Argo CD 实例可以管理它。

      $ oc label namespace openshift-cluster-csi-drivers argocd.argoproj.io/managed-by=openshift-gitops
    2. 将 GitOps 仓库中的资源(包括您刚刚推送的aws-provider.yaml文件)应用到您的集群。

      示例输出
      application.argoproj.io/argo-app created
      application.argoproj.io/secret-provider-app created
      ...

在 Argo CD UI 中,您可以观察到csi-secrets-store-provider-aws daemonset 继续同步资源。要解决此问题,您必须将 SSCSI 驱动程序配置为从 AWS Secrets Manager 挂载密钥。

配置 SSCSI 驱动程序以从 AWS Secrets Manager 挂载密钥

要安全地存储和管理您的密钥,请使用 GitOps 工作流并配置 Secrets Store Container Storage Interface (SSCSI) Driver Operator 将密钥从 AWS Secrets Manager 挂载到 OpenShift Container Platform 中的 CSI 卷。例如,假设您想将密钥挂载到dev命名空间下的部署 Pod,该命名空间位于/environments/dev/目录下。

先决条件
  • 您的 AWS Secrets Manager 资源已存储在您的 GitOps 仓库中。

步骤
  1. 通过运行以下命令授予csi-secrets-store-provider-aws服务帐户特权访问权限。

    $ oc adm policy add-scc-to-user privileged -z csi-secrets-store-provider-aws -n openshift-cluster-csi-drivers
    示例输出
    clusterrole.rbac.authorization.k8s.io/system:openshift:scc:privileged added: "csi-secrets-store-provider-aws"
  2. 授予服务帐户读取 AWS 密钥对象的权限。

    1. 在 GitOps 仓库中的命名空间范围目录下创建credentialsrequest-dir-aws文件夹,因为凭据请求是命名空间范围的。例如,通过运行以下命令在/environments/dev/目录下的dev命名空间下创建一个credentialsrequest-dir-aws文件夹。

      $ mkdir credentialsrequest-dir-aws
    2. /environments/dev/credentialsrequest-dir-aws/路径中创建一个 YAML 文件,其中包含以下配置用于凭据请求,以将密钥挂载到dev命名空间中的部署 Pod。

      credentialsrequest.yaml文件示例
      apiVersion: cloudcredential.openshift.io/v1
      kind: CredentialsRequest
      metadata:
        name: aws-provider-test
        namespace: openshift-cloud-credential-operator
      spec:
        providerSpec:
          apiVersion: cloudcredential.openshift.io/v1
          kind: AWSProviderSpec
          statementEntries:
          - action:
            - "secretsmanager:GetSecretValue"
            - "secretsmanager:DescribeSecret"
            effect: Allow
            resource: "<aws_secret_arn>" (2)
      secretRef:
        name: aws-creds
        namespace: dev (1)
      serviceAccountNames:
        - default
      1 密钥引用的命名空间。根据您的项目部署设置更新此namespace字段的值。
      2 集群所在区域中密钥的 ARN。<aws_secret_arn><aws_region>必须与集群区域匹配。如果不匹配,请在集群所在的区域中创建密钥的副本。

      要查找您的集群区域,请运行以下命令。

      $ oc get infrastructure cluster -o jsonpath='{.status.platformStatus.aws.region}'
      示例输出
      us-west-2
    3. 通过运行以下命令检索 OIDC 提供程序。

      $ oc get --raw=/.well-known/openid-configuration | jq -r '.issuer'
      示例输出
      https://<oidc_provider_name>

      从输出中复制 OIDC 提供程序名称<oidc_provider_name>,以便在下一步中使用。

    4. 使用ccoctl工具处理凭据请求,方法是运行以下命令。

      $ ccoctl aws create-iam-roles \
          --name my-role --region=<aws_region> \
          --credentials-requests-dir=credentialsrequest-dir-aws \
          --identity-provider-arn arn:aws:iam::<aws_account>:oidc-provider/<oidc_provider_name> --output-dir=credrequests-ccoctl-output
      示例输出
      2023/05/15 18:10:34 Role arn:aws:iam::<aws_account_id>:role/my-role-my-namespace-aws-creds created
      2023/05/15 18:10:34 Saved credentials configuration to: credrequests-ccoctl-output/manifests/my-namespace-aws-creds-credentials.yaml
      2023/05/15 18:10:35 Updated Role policy for Role my-role-my-namespace-aws-creds

      从输出中复制<aws_role_arn>,以便在下一步中使用。例如,arn:aws:iam::<aws_account_id>:role/my-role-my-namespace-aws-creds

    5. 检查 AWS 上的角色策略,以确认角色策略中"Resource"<aws_region>与集群区域匹配。

      角色策略示例
      {
      	"Version": "2012-10-17",
      	"Statement": [
      		{
      			"Effect": "Allow",
      			"Action": [
      				"secretsmanager:GetSecretValue",
      				"secretsmanager:DescribeSecret"
      			],
      			"Resource": "arn:aws:secretsmanager:<aws_region>:<aws_account_id>:secret:my-secret-xxxxxx"
      		}
      	]
      }
    6. 通过运行以下命令将服务帐户与角色 ARN 绑定。

      $ oc annotate -n <namespace> sa/<app_service_account> eks.amazonaws.com/role-arn="<aws_role_arn>"
      命令示例
      $ oc annotate -n dev sa/default eks.amazonaws.com/role-arn="<aws_role_arn>"
      示例输出
      serviceaccount/default annotated
  3. 创建一个命名空间范围的SecretProviderClass资源来定义您的密钥存储提供程序。例如,您可以在 GitOps 仓库的/environments/dev/apps/app-taxi/services/taxi/base/config目录中创建一个SecretProviderClass资源。

    1. 在 GitOps 仓库中目标部署所在的同一目录中创建一个secret-provider-class-aws.yaml文件。

      secret-provider-class-aws.yaml示例
      apiVersion: secrets-store.csi.x-k8s.io/v1
      kind: SecretProviderClass
      metadata:
        name: my-aws-provider (1)
        namespace: dev (2)
      spec:
        provider: aws (3)
        parameters: (4)
          objects: |
            - objectName: "testSecret" (5)
              objectType: "secretsmanager"
      1 密钥提供程序类的名称。
      2 密钥提供程序类的命名空间。命名空间必须与将使用密钥的资源的命名空间匹配。
      3 密钥存储提供程序的名称。
      4 指定提供程序特定的配置参数。
      5 您在 AWS 中创建的密钥名称。
    2. 验证将此 YAML 文件推送到您的 GitOps 仓库后,命名空间范围的SecretProviderClass资源是否已填充到 Argo CD UI 中的目标应用程序页面中。

      如果您的应用程序的同步策略未设置为自动,您可以通过单击 Argo CD UI 中的同步来手动同步SecretProviderClass资源。

配置 GitOps 托管资源以使用已挂载的密钥

您必须通过向部署添加卷挂载配置并将容器 Pod 配置为使用已挂载的密钥来配置 GitOps 托管资源。

先决条件
  • 您的 AWS Secrets Manager 资源已存储在您的 GitOps 仓库中。

  • 您已配置 Secrets Store Container Storage Interface (SSCSI) 驱动程序以从 AWS Secrets Manager 挂载密钥。

步骤
  1. 配置 GitOps 托管资源。例如,假设您想要向 `app-taxi` 应用程序的部署添加卷挂载配置,并且 `100-deployment.yaml` 文件位于 `/environments/dev/apps/app-taxi/services/taxi/base/config/` 目录中。

    1. 将卷挂载添加到部署 YAML 文件,并配置容器 Pod 以使用密钥提供程序类资源和已挂载的密钥。

      YAML 文件示例
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: taxi
        namespace: dev (1)
      spec:
        replicas: 1
        template:
          metadata:
      # ...
          spec:
            containers:
              - image: nginxinc/nginx-unprivileged:latest
                imagePullPolicy: Always
                name: taxi
                ports:
                  - containerPort: 8080
                volumeMounts:
                  - name: secrets-store-inline
                    mountPath: "/mnt/secrets-store" (2)
                    readOnly: true
                resources: {}
          serviceAccountName: default
          volumes:
            - name: secrets-store-inline
              csi:
                driver: secrets-store.csi.k8s.io
                readOnly: true
                volumeAttributes:
                  secretProviderClass: "my-aws-provider" (3)
          status: {}
      # ...
      1 部署的命名空间。这必须与密钥提供程序类的命名空间相同。
      2 在卷挂载中挂载密钥的路径。
      3 密钥提供程序类的名称。
    2. 将更新后的资源 YAML 文件推送到您的 GitOps 存储库。

  2. 在 Argo CD UI 中,单击目标应用程序页面上的**刷新**以应用更新后的部署清单。

  3. 验证所有资源是否已在目标应用程序页面上成功同步。

  4. 验证您是否可以从 Pod 卷挂载中访问 AWS Secrets Manager 中的密钥。

    1. 列出 Pod 挂载中的密钥。

      $ oc exec <deployment_name>-<hash> -n <namespace> -- ls /mnt/secrets-store/
      命令示例
      $ oc exec taxi-5959644f9-t847m -n dev -- ls /mnt/secrets-store/
      示例输出
      <secret_name>
    2. 查看 Pod 挂载中的密钥。

      $ oc exec <deployment_name>-<hash> -n <namespace> -- cat /mnt/secrets-store/<secret_name>
      命令示例
      $ oc exec taxi-5959644f9-t847m -n dev -- cat /mnt/secrets-store/testSecret
      示例输出
      <secret_value>