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 存储库中的目录结构示例
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。
流程
为 Vault CSI 供应商创建 Argo CD 应用程序资源。
创建 Argo CD Application 资源来部署 Vault CSI 供应商。将此资源添加到 GitOps 存储库中,如
config/argocd/vault-secret-provider-app.yaml
:vault-secret-provider-app.yaml
文件示例Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意Helm 值中的
server.enabled: true
和dataStorage.enabled: false
设置使用临时存储部署 HashiCorp Vault 服务器实例。此设置适用于开发或测试环境。对于生产环境,您可以使用持久性卷(PV)启用dataStorage
,或使用外部 Vault 集群,并将server.enabled
设置为false
。如果已部署了 Vault 服务器,您可以将server.enabled
设置为false
。
将
vault-secret-provider-app.yaml
文件从 GitOps 存储库应用到集群:oc apply -f vault-secret-provider-app.yaml
$ oc apply -f vault-secret-provider-app.yaml
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 部署 Vault CSI 供应商后,
vault-csi-provider
DaemonSet 可能无法运行。出现这个问题的原因是,OpenShift Container Platform 默认限制特权容器。另外,Vault CSI 供应商和 Secrets Store CSI Driver 需要访问hostPath
挂载,OpenShift Container Platform 块会因为 pod 以特权方式运行。要解决 OpenShift Container Platform 中的权限问题:
对
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}}]
$ 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 Copied! Toggle word wrap Toggle overflow 授予 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
$ oc adm policy add-scc-to-user privileged \ system:serviceaccount:openshift-cluster-csi-drivers:secrets-store-csi-driver-operator
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 为 Vault CSI Provider 服务帐户授予 OpenShift Container Platform 中特权安全性上下文约束(SCC)的访问权限。
oc adm policy add-scc-to-user privileged \ system:serviceaccount:vault-csi-provider:vault-csi-provider
$ oc adm policy add-scc-to-user privileged \ system:serviceaccount:vault-csi-provider:vault-csi-provider
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 注意如果在 Helm Chart 中将
server.enabled
设为true
,则 Vault 服务器 Pod 默认使用 OpenShift Container Platform 块的特定用户 ID (UID)或组 ID (GID)运行。为 Vault 服务器服务帐户授予所需的安全性上下文约束(SCC)权限。
oc adm policy add-scc-to-user anyuid system:serviceaccount:vault-csi-provider:vault
$ oc adm policy add-scc-to-user anyuid system:serviceaccount:vault-csi-provider:vault
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.4.2. 初始化并配置 Vault 以存储 Secret 复制链接链接已复制到粘贴板!
使用 Argo CD 部署 Vault 并应用必要的 SCC 权限和 DaemonSet 补丁后,初始化 Vault,取消密封,并配置 Kubernetes 身份验证以启用安全的 secret 存储和访问。
流程
访问 Vault Pod。
如果 Vault 在 OpenShift Container Platform 集群中运行,例如,作为
vault-csi-provider
命名空间中的vault-0
pod,请运行以下命令访问 pod 中的 Vault CLI:oc exec -it vault-0 -n vault-csi-provider -- /bin/sh
$ oc exec -it vault-0 -n vault-csi-provider -- /bin/sh
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
初始化 Vault。
如果您的 Vault 实例尚未初始化,请运行以下命令:
vault operator init
$ vault operator init
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 因此,会显示以下输出。
5 Unseal Keys - required to unseal the Vault. Initial Root Token - required to log in and configure Vault.
5 Unseal Keys - required to unseal the Vault. Initial Root Token - required to log in and configure Vault.
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 重要安全地存储这些凭据。对于不密封 Vault,至少需要 3 个非密封密钥。如果密钥丢失,则永久阻止对存储的 secret 的访问。
非密封 Vault.
Vault 以密封状态启动。运行以下命令使用上一步中获取的五个 Unseal Keys 的三个内容:
vault operator unseal <Unseal Key 1>
$ vault operator unseal <Unseal Key 1> vault operator unseal <Unseal Key 2> vault operator unseal <Unseal Key 3>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 取消密封后,Vault 变为活动状态并可供使用。
登录 Vault。
要使用 root 令牌登录到 Vault,请运行以下命令:
vault login <Initial Root Token>
$ vault login <Initial Root Token>
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 这为管理员提供了启用和配置 secret 引擎和身份验证方法的访问权限。
在 Vault 中启用 Kubernetes 身份验证。
运行以下命令,以在 Vault 中启用 Kubernetes 身份验证。
vault auth enable kubernetes
$ vault auth enable kubernetes
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 这允许 Kubernetes 工作负载(如 pod)使用其服务帐户通过 Vault 进行身份验证。
在 Vault 中配置 Kubernetes 验证方法。
要配置 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
$ 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 Copied! Toggle word wrap Toggle overflow 因此,会显示以下输出。
Success! Data written to: auth/kubernetes/config
Success! Data written to: auth/kubernetes/config
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 其中:
-
<issuer
> 是 Kubernetes 令牌签发者 URL 的名称。 -
<token_reviewer_jwt
> 是一个 JSON Web Token (JWT),Vault 用来调用 KubernetesTokenReview
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。
流程
启用 KV Secrets Engine
使用 Key-Value (KV)版本 2 secret 引擎来存储支持版本控制的任意 secret。运行以下命令在路径 secret/ 中启用 KV secret 引擎:
vault secrets enable -path=secret/ kv
$ vault secrets enable -path=secret/ kv
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
在 Vault 中存储机密。
使用 KV Version 2 secret 引擎存储 secret。运行以下命令,将 secret 数据、用户名和密码存储在路径
secret/demo/config
:vault kv put secret/demo/config username="demo-user" password="demo-pass"
$ vault kv put secret/demo/config username="demo-user" password="demo-pass"
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
创建 Vault 策略。
要创建授予对 secret 的读取访问权限的策略,请运行以下命令:
vault policy write demo-app-policy -<<EOF path "secret/demo/config" { capabilities = ["read"] } EOF
$ vault policy write demo-app-policy -<<EOF path "secret/demo/config" { capabilities = ["read"] } EOF
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 此
demo-app-policy
授予对secret/demo/config
的读取访问权限,稍后链接到 Kubernetes 角色。
在 Vault 中创建 Kubernetes 身份验证角色。
要创建将 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
$ 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 Copied! Toggle word wrap Toggle overflow 这允许使用服务帐户向 Vault 进行身份验证并检索该 secret。
其中:
-
<bound_service_account_names
> 是 Vault 信任的 Kubernetes 服务帐户的名称。 -
<bound_service_account_namespaces
> 是服务帐户所在的命名空间的名称。 -
<policies
> 是附加的 Vault 策略的名称。 -
<
;TTL> 是为令牌发布的生存时间
值。
-
2.4.4. 配置 GitOps 受管资源以使用 Vault 挂载的 secret 复制链接链接已复制到粘贴板!
使用 Secret Store CSI 驱动程序和 Vault 供应商,安全地将 HashiCorp Vault 中的 secret 注入 GitOps 管理的 Kubernetes 工作负载。secret 挂载为 pod 文件系统中文件,允许应用程序在不将其存储在 Kubernetes Secret 对象中的情况下访问数据。
流程
创建
SecretProviderClass
。在应用程序的清单目录中创建一个
SecretProviderClass
资源,如environments/dev/apps/demo-app/manifest/secretProviderClass.yaml
。此资源定义 Secret Store CSI 驱动程序如何从 Vault 检索 secret。vault-secret-provider-app.yaml
文件示例Copy to Clipboard Copied! Toggle word wrap Toggle overflow
创建一个应用程序,如
ServiceAccount
。为应用程序工作负载创建一个 Kubernetes
ServiceAccount
。ServiceAccount
名称必须与 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
apiVersion: v1 kind: ServiceAccount metadata: name: demo-app-sa namespace: demo-app
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
创建应用程序部署:
修改应用程序的部署,以使用指定的
ServiceAccount
并使用 CSI 卷挂载 secret。将更新的清单存储在 GitOps 存储库中,如environments/dev/apps/demo-app/manifest/deployment.yaml
:deployment.yaml
文件示例Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
serviceAccountName
- 分配 KubernetesServiceAccount
名称,如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
。
为工作负载定义 Argo CD 应用程序:
定义 Argo CD 应用程序资源以部署应用程序组件,如
ServiceAccount
、SecretProviderClass
和来自 GitOps 存储库的Deployment
。将 Argo CD 清单存储在目录位置,如environments/dev/apps/demo-app/argocd/demo-app.yaml
。demo-app.yaml
文件示例Copy to Clipboard Copied! Toggle word wrap Toggle overflow
2.4.5. 验证 secret 注入 复制链接链接已复制到粘贴板!
验证 secret 注入,以确保 Vault 包含预期值。
流程
检查 Pod 状态。
在 Argo CD 应用程序同步并部署了所有资源后,验证应用程序 pod 是否在
demo-app
命名空间中运行。运行以下命令:oc get pods -n demo-app
$ oc get pods -n demo-app
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
打开 Shell 会话。
使用应用容器集的名称打开 shell 会话。将
<your-app-pod-name&
gt; 替换为实际的 pod 名称。oc exec -it <your-app-pod-name> -n demo-app -- sh
$ oc exec -it <your-app-pod-name> -n demo-app -- sh
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
验证挂载的 secret。
要验证 secret 是否挂载到预期的路径中,请运行以下命令:
ls -l /mnt/secrets-store
$ ls -l /mnt/secrets-store cat /mnt/secrets-store/demoAppUsername cat /mnt/secrets-store/demoAppPassword
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 验证挂载的 secret 文件
demoAppUsername
和demoAppPassword
是否包含来自 Vault 的预期值。