2.7. 使用外部 secret 存储为 pod 提供敏感数据
有些应用程序需要密码和用户名等敏感信息,但您不希望开发人员持有这些信息。
使用 Kubernetes Secret
对象提供敏感信息的一个替代选择是,使用外部 secret 存储来存储敏感信息。您可以使用 Secrets Store CSI Driver Operator 与外部 secret 存储集成,并将 secret 内容挂载为 pod 卷。
Secret Store CSI Driver Operator 只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。
有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围。
2.7.1. 关于 Secret Store CSI Driver Operator
Kubernetes secret 以 Base64 编码的形式存储。etcd 为这些 secret 提供加密,但在检索 secret 时,它们会被解密并提供给用户。如果没有在集群中正确配置基于角色的访问控制,则具有 API 或 etcd 访问权限的任何人都可以检索或修改 secret。另外,有权在命名空间中创建 pod 的任何人都可以使用该命名空间中的任何 secret 来读取该命名空间中的任何 secret。
要安全地存储和管理您的 secret,您可以将 OpenShift Container Platform Secrets Store Container Storage Interface (CSI) Driver Operator 配置为使用供应商插件从外部 secret 管理系统(如 Azure Key Vault)挂载 secret。应用程序可以使用 secret,但 secret 在应用程序 pod 被销毁后不会在系统中保留。
Secret Store CSI Driver Operator(secrets-store.csi.k8s.io
)允许 OpenShift Container Platform 将存储在企业级外部 secret 中的多个 secret、密钥和证书作为卷挂载到 pod 中。Secrets Store CSI Driver Operator 使用 gRPC 与供应商通信,以从指定的外部 secret 存储获取挂载内容。附加卷后,其中的数据将挂载到容器的文件系统。Secret 存储卷以 in-line 形式挂载。
2.7.1.1. Secret 存储供应商
以下 secret 存储供应商可用于 Secret Store CSI Driver Operator:
- AWS Secrets Manager
- AWS Systems Manager Parameter Store
- Azure Key Vault
- HashiCorp Vault
2.7.1.2. 自动轮转
Secrets Store CSI 驱动程序会定期使用外部 secret 存储中的内容轮转挂载卷中的内容。如果外部 secret 存储中更新了 secret,secret 将在挂载的卷中更新。Secrets Store CSI Driver Operator 每 2 分钟轮询一次更新。
如果启用了将挂载内容作为 Kubernetes secret 同步,则 Kubernetes secret 也会被轮转。
使用 secret 数据的应用程序必须监视是否有对 secret 的更新。
2.7.2. 安装 Secret Store CSI 驱动程序
先决条件
- 访问 OpenShift Container Platform Web 控制台。
- 集群的管理员访问权限。
流程
安装 Secret Store CSI 驱动程序:
安装 Secret Store CSI Driver Operator:
- 登录到 web 控制台。
-
点 Operators
OperatorHub。 - 通过在过滤器框中输入 "Secrets Store CSI" 来查找 Secrets Store CSI Driver Operator。
- 点 Secrets Store CSI Driver Operator 按钮。
- 在 Secrets Store CSI Driver Operator 页面中,点 Install。
在 Install Operator 页面中,确保:
- 选择 All namespaces on the cluster (default)。
- 安装的命名空间 被设置为 openshift-cluster-csi-drivers。
点 Install。
安装完成后,Secret Store CSI Driver Operator 会在 web 控制台的 Installed Operators 部分列出。
为驱动程序创建
ClusterCSIDriver
实例 (secrets-store.csi.k8s.io
):-
点 Administration
CustomResourceDefinitions ClusterCSIDriver。 在 Instances 选项卡上,单击 Create ClusterCSIDriver。
使用以下 YAML 文件:
apiVersion: operator.openshift.io/v1 kind: ClusterCSIDriver metadata: name: secrets-store.csi.k8s.io spec: managementState: Managed
- 点 Create。
-
点 Administration
2.7.3. 将 secret 从外部 secret 存储挂载到 CSI 卷
安装 Secret Store CSI Driver Operator 后,您可以将 secret 从以下外部 secret 存储挂载到 CSI 卷:
2.7.3.1. 从 AWS Secrets Manager 挂载 secret
您可以使用 Secrets Store CSI Driver Operator 将 secret 从 AWS Secrets Manager 挂载到 OpenShift Container Platform 中的 CSI 卷。要从 AWS Secrets Manager 挂载 secret,您的集群必须安装在 AWS 上,并使用 AWS 安全令牌服务 (STS)。
先决条件
- 您的集群安装在 AWS 上,并使用 AWS 安全令牌服务 (STS)。
- 已安装 Secrets Store CSI Driver Operator。具体步骤请参阅 安装 Secret Store CSI 驱动程序。
- 您已将 AWS Secrets Manager 配置为存储所需的 secret。
-
您已提取并准备好
ccoctl
二进制文件。 -
已安装
jq
CLI 工具。 -
您可以使用具有
cluster-admin
角色的用户访问集群。
流程
安装 AWS Secrets Manager 供应商:
使用供应商资源的以下配置创建一个 YAML 文件:
重要Secret Store CSI 驱动程序的 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
运行以下命令,授予
csi-secrets-store-provider-aws
服务帐户的特权访问权限:$ oc adm policy add-scc-to-user privileged -z csi-secrets-store-provider-aws -n openshift-cluster-csi-drivers
运行以下命令来创建供应商资源:
$ oc apply -f aws-provider.yaml
授予服务帐户读取 AWS secret 对象的权限:
运行以下命令,创建一个目录使其包含凭证请求:
$ mkdir credentialsrequest-dir-aws
使用以下配置为凭证请求创建 YAML 文件:
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: "arn:*:secretsmanager:*:*:secret:testSecret-??????" secretRef: name: aws-creds namespace: my-namespace serviceAccountNames: - aws-provider
运行以下命令来检索 OIDC 供应商:
$ oc get --raw=/.well-known/openid-configuration | jq -r '.issuer'
输出示例
https://<oidc_provider_name>
从输出中复制 OIDC 供应商名称
<oidc_provider_name>
,在下一步中使用。运行以下命令,使用
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
。运行以下命令,使用角色 ARN 绑定服务帐户:
$ oc annotate -n my-namespace sa/aws-provider eks.amazonaws.com/role-arn="<aws_role_arn>"
创建 secret 供应商类以定义您的 secret 存储供应商:
创建定义
SecretProviderClass
对象的 YAML 文件:secret-provider-class-aws.yaml
示例apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: my-aws-provider 1 namespace: my-namespace 2 spec: provider: aws 3 parameters: 4 objects: | - objectName: "testSecret" objectType: "secretsmanager"
运行以下命令来创建
SecretProviderClass
对象:$ oc create -f secret-provider-class-aws.yaml
创建部署以使用此 secret 供应商类:
创建定义
Deployment
对象的 YAML 文件:deployment.yaml
示例apiVersion: apps/v1 kind: Deployment metadata: name: my-aws-deployment 1 namespace: my-namespace 2 spec: replicas: 1 selector: matchLabels: app: my-storage template: metadata: labels: app: my-storage spec: serviceAccountName: aws-provider containers: - name: busybox image: k8s.gcr.io/e2e-test-images/busybox:1.29 command: - "/bin/sleep" - "10000" volumeMounts: - name: secrets-store-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "my-aws-provider" 3
运行以下命令来创建
Deployment
对象:$ oc create -f deployment.yaml
验证
验证您可以从 pod 卷挂载中的 AWS Secrets Manager 访问 secret:
列出 pod 挂载中的 secret:
$ oc exec busybox-<hash> -n my-namespace -- ls /mnt/secrets-store/
输出示例
testSecret
查看 pod 挂载中的 secret:
$ oc exec busybox-<hash> -n my-namespace -- cat /mnt/secrets-store/testSecret
输出示例
<secret_value>
2.7.3.2. 从 AWS Systems Manager Parameter Store 中挂载 secret
您可以使用 Secrets Store CSI Driver Operator 将 secret 从 AWS Systems Manager Parameter Store 挂载到 OpenShift Container Platform 中的 CSI 卷。要从 AWS Systems Manager Parameter Store 挂载 secret,您的集群必须安装在 AWS 上,并使用 AWS 安全令牌服务(STS)。
先决条件
- 您的集群安装在 AWS 上,并使用 AWS 安全令牌服务 (STS)。
- 已安装 Secrets Store CSI Driver Operator。具体步骤请参阅 安装 Secret Store CSI 驱动程序。
- 您已配置了 AWS Systems Manager Parameter Store 以存储所需的 secret。
-
您已提取并准备好
ccoctl
二进制文件。 -
已安装
jq
CLI 工具。 -
您可以使用具有
cluster-admin
角色的用户访问集群。
流程
安装 AWS Systems Manager Parameter Store 供应商:
使用供应商资源的以下配置创建一个 YAML 文件:
重要Secret Store CSI 驱动程序的 AWS Systems Manager Parameter Store 供应商是一个上游供应商。
此配置会根据上游 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
运行以下命令,授予
csi-secrets-store-provider-aws
服务帐户的特权访问权限:$ oc adm policy add-scc-to-user privileged -z csi-secrets-store-provider-aws -n openshift-cluster-csi-drivers
运行以下命令来创建供应商资源:
$ oc apply -f aws-provider.yaml
授予服务帐户读取 AWS secret 对象的权限:
运行以下命令,创建一个目录使其包含凭证请求:
$ mkdir credentialsrequest-dir-aws
使用以下配置为凭证请求创建 YAML 文件:
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: - "ssm:GetParameter" - "ssm:GetParameters" effect: Allow resource: "arn:*:ssm:*:*:parameter/testParameter*" secretRef: name: aws-creds namespace: my-namespace serviceAccountNames: - aws-provider
运行以下命令来检索 OIDC 供应商:
$ oc get --raw=/.well-known/openid-configuration | jq -r '.issuer'
输出示例
https://<oidc_provider_name>
从输出中复制 OIDC 供应商名称
<oidc_provider_name>
,在下一步中使用。运行以下命令,使用
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
。运行以下命令,使用角色 ARN 绑定服务帐户:
$ oc annotate -n my-namespace sa/aws-provider eks.amazonaws.com/role-arn="<aws_role_arn>"
创建 secret 供应商类以定义您的 secret 存储供应商:
创建定义
SecretProviderClass
对象的 YAML 文件:secret-provider-class-aws.yaml
示例apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: my-aws-provider 1 namespace: my-namespace 2 spec: provider: aws 3 parameters: 4 objects: | - objectName: "testParameter" objectType: "ssmparameter"
运行以下命令来创建
SecretProviderClass
对象:$ oc create -f secret-provider-class-aws.yaml
创建部署以使用此 secret 供应商类:
创建定义
Deployment
对象的 YAML 文件:deployment.yaml
示例apiVersion: apps/v1 kind: Deployment metadata: name: my-aws-deployment 1 namespace: my-namespace 2 spec: replicas: 1 selector: matchLabels: app: my-storage template: metadata: labels: app: my-storage spec: serviceAccountName: aws-provider containers: - name: busybox image: k8s.gcr.io/e2e-test-images/busybox:1.29 command: - "/bin/sleep" - "10000" volumeMounts: - name: secrets-store-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "my-aws-provider" 3
运行以下命令来创建
Deployment
对象:$ oc create -f deployment.yaml
验证
验证您可以从 pod 卷挂载中的 AWS Systems Manager Parameter Store 访问 secret:
列出 pod 挂载中的 secret:
$ oc exec busybox-<hash> -n my-namespace -- ls /mnt/secrets-store/
输出示例
testParameter
查看 pod 挂载中的 secret:
$ oc exec busybox-<hash> -n my-namespace -- cat /mnt/secrets-store/testSecret
输出示例
<secret_value>
2.7.3.3. 从 Azure Key Vault 挂载 secret
您可以使用 Secrets Store CSI Driver Operator 将 secret 从 Azure Key Vault 挂载到 OpenShift Container Platform 中的 CSI 卷。要从 Azure Key Vault 挂载 secret,您的集群必须安装在 Microsoft Azure 上。
先决条件
- 集群安装在 Azure 上。
- 已安装 Secrets Store CSI Driver Operator。具体步骤请参阅 安装 Secret Store CSI 驱动程序。
- 您已将 Azure Key Vault 配置为存储所需的 secret。
-
已安装 Azure CLI (
az
)。 -
您可以使用具有
cluster-admin
角色的用户访问集群。
流程
安装 Azure Key Vault 供应商:
使用供应商资源的以下配置创建一个 YAML 文件:
重要Secrets Store CSI 驱动程序的 Azure Key Vault 供应商是一个上游供应商。
此配置会根据上游 Azure 文档中提供的配置进行修改,以便它可以与 OpenShift Container Platform 正常工作。对此配置的更改可能会影响功能。
azure-provider.yaml
文件示例apiVersion: v1 kind: ServiceAccount metadata: name: csi-secrets-store-provider-azure namespace: openshift-cluster-csi-drivers --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: csi-secrets-store-provider-azure-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-azure-cluster-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: csi-secrets-store-provider-azure-cluster-role subjects: - kind: ServiceAccount name: csi-secrets-store-provider-azure namespace: openshift-cluster-csi-drivers --- apiVersion: apps/v1 kind: DaemonSet metadata: namespace: openshift-cluster-csi-drivers name: csi-secrets-store-provider-azure labels: app: csi-secrets-store-provider-azure spec: updateStrategy: type: RollingUpdate selector: matchLabels: app: csi-secrets-store-provider-azure template: metadata: labels: app: csi-secrets-store-provider-azure spec: serviceAccountName: csi-secrets-store-provider-azure hostNetwork: true containers: - name: provider-azure-installer image: mcr.microsoft.com/oss/azure/secrets-store/provider-azure:v1.4.1 imagePullPolicy: IfNotPresent args: - --endpoint=unix:///provider/azure.sock - --construct-pem-chain=true - --healthz-port=8989 - --healthz-path=/healthz - --healthz-timeout=5s livenessProbe: httpGet: path: /healthz port: 8989 failureThreshold: 3 initialDelaySeconds: 5 timeoutSeconds: 10 periodSeconds: 30 resources: requests: cpu: 50m memory: 100Mi limits: cpu: 50m memory: 100Mi securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true runAsUser: 0 capabilities: drop: - ALL volumeMounts: - mountPath: "/provider" name: providervol affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: type operator: NotIn values: - virtual-kubelet volumes: - name: providervol hostPath: path: "/var/run/secrets-store-csi-providers" tolerations: - operator: Exists nodeSelector: kubernetes.io/os: linux
运行以下命令,授予
csi-secrets-store-provider-azure
服务帐户的特权访问权限:$ oc adm policy add-scc-to-user privileged -z csi-secrets-store-provider-azure -n openshift-cluster-csi-drivers
运行以下命令来创建供应商资源:
$ oc apply -f azure-provider.yaml
创建服务主体来访问密钥库:
运行以下命令,将服务主体客户端 secret 设置为环境变量:
$ SERVICE_PRINCIPAL_CLIENT_SECRET="$(az ad sp create-for-rbac --name https://$KEYVAULT_NAME --query 'password' -otsv)"
运行以下命令,将服务主体客户端 ID 设置为环境变量:
$ SERVICE_PRINCIPAL_CLIENT_ID="$(az ad sp list --display-name https://$KEYVAULT_NAME --query '[0].appId' -otsv)"
运行以下命令,使用服务主体客户端 secret 和 ID 创建通用 secret:
$ oc create secret generic secrets-store-creds -n my-namespace --from-literal clientid=${SERVICE_PRINCIPAL_CLIENT_ID} --from-literal clientsecret=${SERVICE_PRINCIPAL_CLIENT_SECRET}
应用
secrets-store.csi.k8s.io/used=true
标签,以允许供应商查找此nodePublishSecretRef
secret:$ oc -n my-namespace label secret secrets-store-creds secrets-store.csi.k8s.io/used=true
创建 secret 供应商类以定义您的 secret 存储供应商:
创建定义
SecretProviderClass
对象的 YAML 文件:secret-provider-class-azure.yaml
示例apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: my-azure-provider 1 namespace: my-namespace 2 spec: provider: azure 3 parameters: 4 usePodIdentity: "false" useVMManagedIdentity: "false" userAssignedIdentityID: "" keyvaultName: "kvname" objects: | array: - | objectName: secret1 objectType: secret tenantId: "tid"
运行以下命令来创建
SecretProviderClass
对象:$ oc create -f secret-provider-class-azure.yaml
创建部署以使用此 secret 供应商类:
创建定义
Deployment
对象的 YAML 文件:deployment.yaml
示例apiVersion: apps/v1 kind: Deployment metadata: name: my-azure-deployment 1 namespace: my-namespace 2 spec: replicas: 1 selector: matchLabels: app: my-storage template: metadata: labels: app: my-storage spec: containers: - name: busybox image: k8s.gcr.io/e2e-test-images/busybox:1.29 command: - "/bin/sleep" - "10000" volumeMounts: - name: secrets-store-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "my-azure-provider" 3 nodePublishSecretRef: name: secrets-store-creds 4
运行以下命令来创建
Deployment
对象:$ oc create -f deployment.yaml
验证
验证您可以从 pod 卷挂载中的 Azure Key Vault 访问 secret:
列出 pod 挂载中的 secret:
$ oc exec busybox-<hash> -n my-namespace -- ls /mnt/secrets-store/
输出示例
secret1
查看 pod 挂载中的 secret:
$ oc exec busybox-<hash> -n my-namespace -- cat /mnt/secrets-store/secret1
输出示例
my-secret-value
2.7.3.4. 从 HashiCorp Vault 挂载 secret
您可以使用 Secrets Store CSI Driver Operator 将 secret 从 HashiCorp Vault 挂载到 OpenShift Container Platform 中的 CSI 卷。
使用 Secrets Store CSI Driver Operator 从 HashiCorp Vault 挂载 secret 已使用以下云供应商测试:
- Amazon Web Services (AWS)
- Microsoft Azure
其他云供应商可能可以正常工作,但还没有测试。以后可能会测试其他云供应商。
先决条件
- 已安装 Secrets Store CSI Driver Operator。具体步骤请参阅 安装 Secret Store CSI 驱动程序。
- 您已安装 Helm。
-
您可以使用具有
cluster-admin
角色的用户访问集群。
流程
运行以下命令来添加 HashiCorp Helm 仓库:
$ helm repo add hashicorp https://helm.releases.hashicorp.com
运行以下命令,更新所有仓库以确保 Helm 了解最新版本:
$ helm repo update
安装 HashiCorp Vault 供应商:
运行以下命令,为 Vault 创建一个新项目:
$ oc new-project vault
运行以下命令,为 pod 安全准入标记
vault
命名空间:$ oc label ns vault security.openshift.io/scc.podSecurityLabelSync=false pod-security.kubernetes.io/enforce=privileged pod-security.kubernetes.io/audit=privileged pod-security.kubernetes.io/warn=privileged --overwrite
运行以下命令,授予
vault
服务帐户的特权访问权限:$ oc adm policy add-scc-to-user privileged -z vault -n vault
运行以下命令,授予
vault-csi-provider
服务帐户的访问权限:$ oc adm policy add-scc-to-user privileged -z vault-csi-provider -n vault
运行以下命令来部署 HashiCorp Vault:
$ helm install vault hashicorp/vault --namespace=vault \ --set "server.dev.enabled=true" \ --set "injector.enabled=false" \ --set "csi.enabled=true" \ --set "global.openshift=true" \ --set "injector.agentImage.repository=docker.io/hashicorp/vault" \ --set "server.image.repository=docker.io/hashicorp/vault" \ --set "csi.image.repository=docker.io/hashicorp/vault-csi-provider" \ --set "csi.agent.image.repository=docker.io/hashicorp/vault" \ --set "csi.daemonSet.providersDir=/var/run/secrets-store-csi-providers"
运行以下命令,修补
vault-csi-driver
守护进程,将securityContext
设置为privileged
:$ oc patch daemonset -n vault vault-csi-provider --type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/securityContext", "value": {"privileged": true} }]'
运行以下命令,验证
vault-csi-provider
pod 是否已正确启动:$ oc get pods -n vault
输出示例
NAME READY STATUS RESTARTS AGE vault-0 1/1 Running 0 24m vault-csi-provider-87rgw 1/2 Running 0 5s vault-csi-provider-bd6hp 1/2 Running 0 4s vault-csi-provider-smlv7 1/2 Running 0 5s
配置 HashiCorp Vault 以存储所需的 secret:
运行以下命令来创建 secret:
$ oc exec vault-0 --namespace=vault -- vault kv put secret/example1 testSecret1=my-secret-value
运行以下命令,验证
secret/example1
的路径是否可读:$ oc exec vault-0 --namespace=vault -- vault kv get secret/example1
输出示例
= Secret Path = secret/data/example1 ======= Metadata ======= Key Value --- ----- created_time 2024-04-05T07:05:16.713911211Z custom_metadata <nil> deletion_time n/a destroyed false version 1 === Data === Key Value --- ----- testSecret1 my-secret-value
将 Vault 配置为使用 Kubernetes 身份验证:
运行以下命令来启用 Kubernetes auth 方法:
$ oc exec vault-0 --namespace=vault -- vault auth enable kubernetes
输出示例
Success! Enabled kubernetes auth method at: kubernetes/
配置 Kubernetes auth 方法:
运行以下命令,将令牌查看器设置为环境变量:
$ TOKEN_REVIEWER_JWT="$(oc exec vault-0 --namespace=vault -- cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
运行以下命令,将 Kubernetes 服务 IP 地址设置为环境变量:
$ KUBERNETES_SERVICE_IP="$(oc get svc kubernetes -o go-template="{{ .spec.clusterIP }}")"
运行以下命令来更新 Kubernetes auth 方法:
$ oc exec -i vault-0 --namespace=vault -- vault write auth/kubernetes/config \ issuer="https://kubernetes.default.svc.cluster.local" \ token_reviewer_jwt="${TOKEN_REVIEWER_JWT}" \ kubernetes_host="https://${KUBERNETES_SERVICE_IP}:443" \ kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
输出示例
Success! Data written to: auth/kubernetes/config
运行以下命令,为应用程序创建一个策略:
$ oc exec -i vault-0 --namespace=vault -- vault policy write csi -<<EOF path "secret/data/*" { capabilities = ["read"] } EOF
输出示例
Success! Uploaded policy: csi
运行以下命令,创建一个身份验证角色来访问应用程序:
$ oc exec -i vault-0 --namespace=vault -- vault write auth/kubernetes/role/csi \ bound_service_account_names=default \ bound_service_account_namespaces=default,test-ns,negative-test-ns,my-namespace \ policies=csi \ ttl=20m
输出示例
Success! Data written to: auth/kubernetes/role/csi
运行以下命令,验证所有
vault
pod 是否都正常运行:$ oc get pods -n vault
输出示例
NAME READY STATUS RESTARTS AGE vault-0 1/1 Running 0 43m vault-csi-provider-87rgw 2/2 Running 0 19m vault-csi-provider-bd6hp 2/2 Running 0 19m vault-csi-provider-smlv7 2/2 Running 0 19m
运行以下命令,验证所有
secrets-store-csi-driver
pod 是否正常运行:$ oc get pods -n openshift-cluster-csi-drivers | grep -E "secrets"
输出示例
secrets-store-csi-driver-node-46d2g 3/3 Running 0 45m secrets-store-csi-driver-node-d2jjn 3/3 Running 0 45m secrets-store-csi-driver-node-drmt4 3/3 Running 0 45m secrets-store-csi-driver-node-j2wlt 3/3 Running 0 45m secrets-store-csi-driver-node-v9xv4 3/3 Running 0 45m secrets-store-csi-driver-node-vlz28 3/3 Running 0 45m secrets-store-csi-driver-operator-84bd699478-fpxrw 1/1 Running 0 47m
创建 secret 供应商类以定义您的 secret 存储供应商:
创建定义
SecretProviderClass
对象的 YAML 文件:secret-provider-class-vault.yaml
示例apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: my-vault-provider 1 namespace: my-namespace 2 spec: provider: vault 3 parameters: 4 roleName: "csi" vaultAddress: "http://vault.vault:8200" objects: | - secretPath: "secret/data/example1" objectName: "testSecret1" secretKey: "testSecret1
运行以下命令来创建
SecretProviderClass
对象:$ oc create -f secret-provider-class-vault.yaml
创建部署以使用此 secret 供应商类:
创建定义
Deployment
对象的 YAML 文件:deployment.yaml
示例apiVersion: apps/v1 kind: Deployment metadata: name: busybox-deployment 1 namespace: my-namespace 2 labels: app: busybox spec: replicas: 1 selector: matchLabels: app: busybox template: metadata: labels: app: busybox spec: terminationGracePeriodSeconds: 0 containers: - image: registry.k8s.io/e2e-test-images/busybox:1.29-4 name: busybox imagePullPolicy: IfNotPresent command: - "/bin/sleep" - "10000" volumeMounts: - name: secrets-store-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "my-vault-provider" 3
运行以下命令来创建
Deployment
对象:$ oc create -f deployment.yaml
验证
验证您是否可以从 pod 卷挂载中的 HashiCorp Vault 访问 secret:
运行以下命令,列出 pod 挂载中的 secret:
$ oc exec busybox-<hash> -n my-namespace -- ls /mnt/secrets-store/
输出示例
testSecret1
运行以下命令,查看 pod 挂载中的 secret:
$ oc exec busybox-<hash> -n my-namespace -- cat /mnt/secrets-store/testSecret1
输出示例
my-secret-value
2.7.4. 启用对作为 Kubernetes secret 挂载的内容进行同步
您可以启用同步,从挂载的卷中的内容创建 Kubernetes secret。您可能要启用同步的示例是使用部署中的环境变量来引用 Kubernetes secret。
如果您不想将 secret 存储在 OpenShift Container Platform 集群和 etcd 中,请不要启用同步。仅在需要它时启用此功能,比如当您想要使用环境变量来引用 secret 时。
如果启用了同步,在启动挂载 secret 的 pod 后,来自挂载卷的 secret 会同步为 Kubernetes secret。
当所有挂载内容的 pod 被删除时,同步的 Kubernetes secret 会被删除。
先决条件
- 已安装 Secrets Store CSI Driver Operator。
- 已安装 secret 存储供应商。
- 您已创建了 secret 供应商类。
-
您可以使用具有
cluster-admin
角色的用户访问集群。
流程
运行以下命令来编辑
SecretProviderClass
资源:$ oc edit secretproviderclass my-azure-provider 1
- 1
- 将
my-azure-provider
替换为 secret 供应商类的名称。
使用同步的 Kubernetes secret 配置添加
secretsObjects
部分:apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: my-azure-provider namespace: my-namespace spec: provider: azure secretObjects: 1 - secretName: tlssecret 2 type: kubernetes.io/tls 3 labels: environment: "test" data: - objectName: tlskey 4 key: tls.key 5 - objectName: tlscrt key: tls.crt parameters: usePodIdentity: "false" keyvaultName: "kvname" objects: | array: - | objectName: tlskey objectType: secret - | objectName: tlscrt objectType: secret tenantId: "tid"
- 保存文件以使改变生效。
2.7.5. 查看 pod 卷挂载中的 secret 状态
您可以查看 pod 卷挂载中 secret 的详细信息,包括版本。
Secrets Store CSI Driver Operator 在与 pod 相同的命名空间中创建一个 SecretProviderClassPodStatus
资源。您可以查看此资源来查看详细信息,包括版本,以及 pod 卷挂载中的 secret。
先决条件
- 已安装 Secrets Store CSI Driver Operator。
- 已安装 secret 存储供应商。
- 您已创建了 secret 供应商类。
- 您已部署了从 Secrets Store CSI Driver Operator 挂载卷的 pod。
-
您可以使用具有
cluster-admin
角色的用户访问集群。
流程
运行以下命令,查看 pod 卷挂载中 secret 的详细信息:
$ oc get secretproviderclasspodstatus <secret_provider_class_pod_status_name> -o yaml 1
- 1
- secret 供应商类 pod 状态对象的名称采用
<pod_name>-<namespace>-<secret_provider_class_name>
的格式。
输出示例
... status: mounted: true objects: - id: secret/tlscrt version: f352293b97da4fa18d96a9528534cb33 - id: secret/tlskey version: 02534bc3d5df481cb138f8b2a13951ef podName: busybox-<hash> secretProviderClassName: my-azure-provider targetPath: /var/lib/kubelet/pods/f0d49c1e-c87a-4beb-888f-37798456a3e7/volumes/kubernetes.io~csi/secrets-store-inline/mount
2.7.6. 卸载 Secret Store CSI Driver Operator
先决条件
- 访问 OpenShift Container Platform Web 控制台。
- 集群的管理员访问权限。
流程
卸载 Secret Store CSI Driver Operator:
-
停止所有使用
secrets-store.csi.k8s.io
供应商的应用程序 pod。 - 为所选 secret 存储删除任何第三方供应商插件。
删除 Container Storage Interface (CSI) 驱动程序和相关清单:
-
点 Administration
CustomResourceDefinitions ClusterCSIDriver。 - 在 Instances 选项卡上,对于 secrets-store.csi.k8s.io,点左侧的下拉菜单,然后点 Delete ClusterCSIDriver。
- 出现提示时,单击 Delete。
-
点 Administration
- 验证 CSI 驱动程序 pod 是否不再运行。
卸载 Secret Store CSI Driver Operator:
注意在卸载 Operator 前,必须先删除 CSI 驱动程序。
-
点 Operators
Installed Operators。 - 在 Installed Operators 页面中,在 Search by name 框中输入 "Secrets Store CSI" 来查找 Operator,然后点击它。
-
在 Installed Operators > Operator 详情页面 的右上角,点 Actions
Uninstall Operator。 当在 Uninstall Operator 窗口中提示时,点 Uninstall 按钮从命名空间中删除 Operator。Operator 在集群中部署的任何应用程序都需要手动清理。
卸载后,Secret Store CSI Driver Operator 不再列在 web 控制台的 Installed Operators 部分。
-
点 Operators