2.4. 使用 GitOps 将 HashiCorp Vault 配置为 OpenShift 上的 secret 供应商


您可以通过在 OpenShift Container Platform 上使用 Secrets Store CSI Driver Operator 将 HashiCorp Vault 配置为 secret 供应商。与 Argo CD 管理的 GitOps 工作流结合使用时,此设置可让您安全地从 Vault 检索 secret,并将其注入到 OpenShift 上运行的应用程序。

构建 GitOps 存储库并配置 Vault CSI 供应商,以便与 OpenShift Container Platform 中的 Secret Store CSI Driver 集成。

以下 GitOps 存储库布局示例用于将 Vault 与应用程序集成。

GitOps 存储库中的目录结构示例

├── config
│   ├── argocd 
1

│   │   ├── vault-secret-provider-app.yaml
│   │   ├── ...
│── environments
│   ├── dev
│   │   ├── apps
│   │   │   ├── demo-app
│   │   │       ├── manifest 
2

│   │   │       |    ├── secretProviderClass.yaml
│   │   │       |    ├── serviceAccount.yaml
│   │   │       |    ├── deployment.yaml
│   │   │       ├── argocd 
3

│   │   │            ├── demo-app.yaml
Copy to Clipboard Toggle word wrap

1
config/argocd/ - 存储集群范围的工具(如 Vault CSI 供应商)的 Argo CD 应用程序定义。
2
environments/<env>/apps/<app-name>/manifest/: 包含特定于特定环境中的应用程序的 Kubernetes 清单。
3
environments/<env>/apps/<app-name>/argocd/: 包含部署应用程序及其资源的 Argo CD Application 定义。

2.4.1. 使用 GitOps 安装 Vault CSI 供应商

通过部署使用 HashiCorp 的官方 Helm Chart 的 Argo CD 应用程序来安装 Vault CSI 供应商。这个方法通过一个版本控制的 Argo CD Application 资源以声明性方式管理安装来遵循 GitOps 最佳实践。

先决条件

  • 以管理员身份登陆到 OpenShift Container Platform 集群。
  • 访问 OpenShift Container Platform web 控制台。
  • 在集群中安装了 SSCSI Driver Operator
  • 您已在 OpenShift Container Platform 集群上安装了 Red Hat OpenShift GitOps
  • 您有一个 GitOps 存储库可以使用 secret。

流程

  1. 为 Vault CSI 供应商创建 Argo CD 应用程序资源。

    1. 创建 Argo CD Application 资源来部署 Vault CSI 供应商。将此资源添加到 GitOps 存储库中,如 config/argocd/vault-secret-provider-app.yaml

      vault-secret-provider-app.yaml 文件示例

      apiVersion: argoproj.io/v1alpha1
      kind: Application
      metadata:
        name: vault-secret-provider-app
        namespace: openshift-gitops
      spec:
        destination:
          namespace: vault-csi-provider
          server: https://kubernetes.default.svc
        project: default
        source:
          repoURL: https://helm.releases.hashicorp.com
          chart: vault
          targetRevision: 0.30.0
          helm:
            releaseName: vault
            values: |
              csi:
                enabled: true
              server:
                enabled: true
                dataStorage:
                   enabled: false
              injector:
                enabled: false
        syncPolicy:
          automated:
            prune: true
            selfHeal: true
          syncOptions:
          - CreateNamespace=true
        ignoreDifferences:
        - kind: DaemonSet
          group: apps
          jsonPointers:
            - /spec/template/spec/containers/0/securityContext/privileged
      Copy to Clipboard Toggle word wrap

      注意

      Helm 值中的 server.enabled: truedataStorage.enabled: false 设置使用临时存储部署 HashiCorp Vault 服务器实例。此设置适用于开发或测试环境。对于生产环境,您可以使用持久性卷(PV)启用 dataStorage,或使用外部 Vault 集群,并将 server.enabled 设置为 false。如果已部署了 Vault 服务器,您可以将 server.enabled 设置为 false

  2. vault-secret-provider-app.yaml 文件从 GitOps 存储库应用到集群:

    $ oc apply -f vault-secret-provider-app.yaml
    Copy to Clipboard Toggle word wrap

    部署 Vault CSI 供应商后,vault-csi-provider DaemonSet 可能无法运行。出现这个问题的原因是,OpenShift Container Platform 默认限制特权容器。另外,Vault CSI 供应商和 Secrets Store CSI Driver 需要访问 hostPath 挂载,OpenShift Container Platform 块会因为 pod 以特权方式运行。

    1. 要解决 OpenShift Container Platform 中的权限问题:

      1. vault-csi-provider DaemonSet 进行补丁,使其容器作为特权运行:

        $ oc patch daemonset vault-csi-provider -n vault-csi-provider --type=json --patch='[{"op":"add","path":"/spec/template/spec/containers/0/securityContext","value":{"privileged":true}}]
        Copy to Clipboard Toggle word wrap
      2. 授予 Secrets Store CSI Driver 服务帐户对 OpenShift Container Platform 中特权安全上下文约束(SCC)的访问权限。

        $ oc adm policy add-scc-to-user privileged \ system:serviceaccount:openshift-cluster-csi-drivers:secrets-store-csi-driver-operator
        Copy to Clipboard Toggle word wrap
      3. 为 Vault CSI Provider 服务帐户授予 OpenShift Container Platform 中特权安全性上下文约束(SCC)的访问权限。

        $ oc adm policy add-scc-to-user privileged \
        system:serviceaccount:vault-csi-provider:vault-csi-provider
        Copy to Clipboard Toggle word wrap
        注意

        如果在 Helm Chart 中将 server.enabled 设为 true,则 Vault 服务器 Pod 默认使用 OpenShift Container Platform 块的特定用户 ID (UID)或组 ID (GID)运行。

      4. 为 Vault 服务器服务帐户授予所需的安全性上下文约束(SCC)权限。

        $ oc adm policy add-scc-to-user anyuid  system:serviceaccount:vault-csi-provider:vault
        Copy to Clipboard Toggle word wrap

2.4.2. 初始化并配置 Vault 以存储 Secret

使用 Argo CD 部署 Vault 并应用必要的 SCC 权限和 DaemonSet 补丁后,初始化 Vault,取消密封,并配置 Kubernetes 身份验证以启用安全的 secret 存储和访问。

流程

  1. 访问 Vault Pod。

    1. 如果 Vault 在 OpenShift Container Platform 集群中运行,例如,作为 vault-csi-provider 命名空间中的 vault-0 pod,请运行以下命令访问 pod 中的 Vault CLI:

      $ oc exec -it vault-0 -n vault-csi-provider -- /bin/sh
      Copy to Clipboard Toggle word wrap
  2. 初始化 Vault。

    1. 如果您的 Vault 实例尚未初始化,请运行以下命令:

      $ vault operator init
      Copy to Clipboard Toggle word wrap

      因此,会显示以下输出。

      5 Unseal Keys - required to unseal the Vault.
      Initial Root Token - required to log in and configure Vault.
      Copy to Clipboard Toggle word wrap
      重要

      安全地存储这些凭据。对于不密封 Vault,至少需要 3 个非密封密钥。如果密钥丢失,则永久阻止对存储的 secret 的访问。

  3. 非密封 Vault.

    1. Vault 以密封状态启动。运行以下命令使用上一步中获取的五个 Unseal Keys 的三个内容:

      $ vault operator unseal <Unseal Key 1>
        vault operator unseal <Unseal Key 2>
        vault operator unseal <Unseal Key 3>
      Copy to Clipboard Toggle word wrap

      取消密封后,Vault 变为活动状态并可供使用。

  4. 登录 Vault。

    1. 要使用 root 令牌登录到 Vault,请运行以下命令:

      $ vault login <Initial Root Token>
      Copy to Clipboard Toggle word wrap

      这为管理员提供了启用和配置 secret 引擎和身份验证方法的访问权限。

  5. 在 Vault 中启用 Kubernetes 身份验证。

    1. 运行以下命令,以在 Vault 中启用 Kubernetes 身份验证。

      $ vault auth enable kubernetes
      Copy to Clipboard Toggle word wrap

      这允许 Kubernetes 工作负载(如 pod)使用其服务帐户通过 Vault 进行身份验证。

  6. 在 Vault 中配置 Kubernetes 验证方法。

    1. 要配置 Vault 以便与 Kubernetes API 通信,请运行以下命令:

      $ vault write auth/kubernetes/config \
      issuer="https://kubernetes.default.svc" \
      token_reviewer_jwt="$(cat/var/run/secrets/kubernetes.io/serviceaccount/token)" \
      kubernetes_host="https://${KUBERNETES_PORT_443_TCP_ADDR}:443" \
      kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      Copy to Clipboard Toggle word wrap

      因此,会显示以下输出。

      Success! Data written to: auth/kubernetes/config
      Copy to Clipboard Toggle word wrap

      其中:

      • <issuer > 是 Kubernetes 令牌签发者 URL 的名称。
      • <token_reviewer_jwt > 是一个 JSON Web Token (JWT),Vault 用来调用 Kubernetes TokenReview API,用于验证服务帐户令牌。
      • <kubernetes_host > 是 Vault 用于与 Kubernetes API 服务器通信的 URL。
      • <kubernetes_ca_cert > 是 Vault 用于安全与 Kubernetes API 服务器通信的 CA 证书。

2.4.3. 在 Vault 中管理 Secret、策略和角色

要在 Vault 中创建 secret,请定义 Vault 策略并配置 Kubernetes 身份验证角色,使 Kubernetes 工作负载能够安全地检索 secret。

流程

  1. 启用 KV Secrets Engine

    1. 使用 Key-Value (KV)版本 2 secret 引擎来存储支持版本控制的任意 secret。运行以下命令在路径 secret/ 中启用 KV secret 引擎:

      $ vault secrets enable -path=secret/ kv
      Copy to Clipboard Toggle word wrap
  2. 在 Vault 中存储机密。

    1. 使用 KV Version 2 secret 引擎存储 secret。运行以下命令,将 secret 数据、用户名和密码存储在路径 secret/demo/config

      $ vault kv put secret/demo/config username="demo-user" password="demo-pass"
      Copy to Clipboard Toggle word wrap
  3. 创建 Vault 策略。

    1. 要创建授予对 secret 的读取访问权限的策略,请运行以下命令:

      $ vault policy write demo-app-policy -<<EOF
      path "secret/demo/config" {
        capabilities = ["read"]
      }
      EOF
      Copy to Clipboard Toggle word wrap

      demo-app-policy 授予对 secret/demo/config 的读取访问权限,稍后链接到 Kubernetes 角色。

  4. 在 Vault 中创建 Kubernetes 身份验证角色。

    1. 要创建将 Kubernetes 服务帐户绑定到 Vault 策略的角色,请运行以下命令:

      $ vault write auth/kubernetes/role/app \ bound_service_account_names=demo-app-sa \ bound_service_account_namespaces=demo-app \ policies=demo-app-policy \ ttl=24h
      Copy to Clipboard Toggle word wrap

      这允许使用服务帐户向 Vault 进行身份验证并检索该 secret。

      其中:

      • <bound_service_account_names > 是 Vault 信任的 Kubernetes 服务帐户的名称。
      • <bound_service_account_namespaces > 是服务帐户所在的命名空间的名称。
      • <policies > 是附加的 Vault 策略的名称。
      • &lt;TTL > 是为令牌发布的生存时间 值。

使用 Secret Store CSI 驱动程序和 Vault 供应商,安全地将 HashiCorp Vault 中的 secret 注入 GitOps 管理的 Kubernetes 工作负载。secret 挂载为 pod 文件系统中文件,允许应用程序在不将其存储在 Kubernetes Secret 对象中的情况下访问数据。

流程

  1. 创建 SecretProviderClass

    1. 在应用程序的清单目录中创建一个 SecretProviderClass 资源,如 environments/dev/apps/demo-app/manifest/secretProviderClass.yaml。此资源定义 Secret Store CSI 驱动程序如何从 Vault 检索 secret。

      vault-secret-provider-app.yaml 文件示例

      apiVersion: secrets-store.csi.x-k8s.io/v1
        kind: SecretProviderClass
           metadata:
               name: demo-app-creds
               namespace: demo-app
       spec:
              provider: vault 
      1
      
              parameters:
                    vaultAddress: http://vault.vault-csi-provider:8200 # <name>.<namespace>:port 
      2
      
                    roleName: app 
      3
      
              objects: | 
      4
      
                 - objectName: "demoAppUsername"
                   secretPath: "secret/demo/config"
                   secretKey: "username"
                - objectName: "demoAppPassword"
                  secretPath: "secret/demo/config"
                   secretKey: "password"
      Copy to Clipboard Toggle word wrap

      1
      <provider: vault >- 指定 HashiCorp Vault 的名称。
      2
      <vaultAddress >- 指定 Vault 服务器的网络地址。根据您的 Vault 设置,如 in-cluster 服务或外部 URL 来调整它。
      3
      <roleName >- 指定应用程序服务帐户使用的 Vault Kubernetes 身份验证角色。描述定义要检索哪些 secret 以及如何将其映射到文件名的数组。
      4
      &lt;objects>- 指定定义要检索哪些 secret 以及如何将其映射到文件名的数组。KV v2 的 secretPath 包括 /data/
  2. 创建一个应用程序,如 ServiceAccount

    1. 为应用程序工作负载创建一个 Kubernetes ServiceAccountServiceAccount 名称必须与 Vault Kubernetes 身份验证角色中定义的 bound_service_account_names 值匹配。将清单存储在 GitOps 存储库中,如 environments/dev/apps/demo-app/manifest/serviceAccount.yaml

      ServiceAccount.yaml 文件示例

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: demo-app-sa
        namespace: demo-app
      Copy to Clipboard Toggle word wrap

  3. 创建应用程序部署:

    1. 修改应用程序的部署,以使用指定的 ServiceAccount 并使用 CSI 卷挂载 secret。将更新的清单存储在 GitOps 存储库中,如 environments/dev/apps/demo-app/manifest/deployment.yaml

      deployment.yaml 文件示例

      apiVersion: apps/v1
      kind: Deployment
      metadata:
         name: app
         namespace: demo-app
         labels:
           app: demo
      spec:
         replicas: 1
         selector:
           matchLabels:
              app: demo
         template:
            metadata:
             labels:
               app: demo
         spec:
              serviceAccountName: demo-app-sa 
      1
      
              containers:
                 - name: app
                   image: nginxinc/nginx-unprivileged:latest
                   volumeMounts: 
      2
      
                   - name: vault-secrets
                     mountPath: /mnt/secrets-store
                     readOnly: true
         volumes: 
      3
      
              - name: vault-secrets
                csi:
                  driver: secrets-store.csi.k8s.io
                  readOnly: true
                  volumeAttributes:
                  secretProviderClass: demo-app-creds
      Copy to Clipboard Toggle word wrap

      1
      serviceAccountName - 分配 Kubernetes ServiceAccount 名称,如 demo-app-sa,供应用 Pod 使用。此 ServiceAccount 是使用 HashiCorp Vault 进行身份验证的基础,因为它链接到授予授予检索所需 secret 权限的 Vault 角色。
      2
      volumeMounts - 将 vault-secrets 卷挂载到 /mnt/secrets-store 目录中的容器中。
      3
      volumes - 使用 secrets-store.csi.k8s.io 驱动程序定义 vault-secrets 卷,并引用 demo-app-creds SecretProviderClass
  4. 为工作负载定义 Argo CD 应用程序:

    1. 定义 Argo CD 应用程序资源以部署应用程序组件,如 ServiceAccountSecretProviderClass 和来自 GitOps 存储库的 Deployment。将 Argo CD 清单存储在目录位置,如 environments/dev/apps/demo-app/argocd/demo-app.yaml

      demo-app.yaml 文件示例

      apiVersion: argoproj.io/v1alpha1
      kind: Application
      metadata:
        name: demo-app
        namespace: openshift-gitops
      spec:
        project: default
        source:
          repoURL: https://your-git-repo-url.git
          targetRevision: HEAD
          path: environments/dev/apps/demo-app/manifest
        destination:
          server: https://kubernetes.default.svc
          namespace: demo-app
        syncPolicy:
          automated:
            prune: true
            selfHeal: true
          syncOptions:
            - CreateNamespace=true
      Copy to Clipboard Toggle word wrap

2.4.5. 验证 secret 注入

验证 secret 注入,以确保 Vault 包含预期值。

流程

  1. 检查 Pod 状态。

    1. 在 Argo CD 应用程序同步并部署了所有资源后,验证应用程序 pod 是否在 demo-app 命名空间中运行。运行以下命令:

      $ oc get pods -n demo-app
      Copy to Clipboard Toggle word wrap
  2. 打开 Shell 会话。

    1. 使用应用容器集的名称打开 shell 会话。将 <your-app-pod-name& gt; 替换为实际的 pod 名称。

      $ oc exec -it <your-app-pod-name> -n demo-app -- sh
      Copy to Clipboard Toggle word wrap
  3. 验证挂载的 secret。

    1. 要验证 secret 是否挂载到预期的路径中,请运行以下命令:

      $ ls -l /mnt/secrets-store
        cat /mnt/secrets-store/demoAppUsername
        cat /mnt/secrets-store/demoAppPassword
      Copy to Clipboard Toggle word wrap

      验证挂载的 secret 文件 demoAppUsernamedemoAppPassword 是否包含来自 Vault 的预期值。

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat