apiVersion: operator.openshift.io/v1
kind: ClusterCSIDriver
metadata:
name: secrets-store.csi.k8s.io
spec:
managementState: Managed
某些应用程序需要敏感信息,例如密码和用户名,您不希望开发人员拥有这些信息。
作为使用 Kubernetes Secret
对象提供敏感信息的替代方法,您可以使用外部 Secrets Store 来存储敏感信息。您可以使用 Secrets Store CSI 驱动程序运算符与外部 Secrets Store 集成并将机密内容作为 Pod 卷挂载。
Secrets Store CSI 驱动程序运算符仅为技术预览功能。技术预览功能不受 Red Hat 生产服务级别协议 (SLA) 的支持,并且可能功能不完整。Red Hat 不建议在生产环境中使用它们。这些功能可让您抢先体验即将推出的产品功能,从而能够在开发过程中测试功能并提供反馈。 有关 Red Hat 技术预览功能的支持范围的更多信息,请参阅 技术预览功能支持范围。 |
Kubernetes 机密使用 Base64 编码存储。etcd 为这些机密提供静态加密,但是当检索机密时,它们会被解密并提供给用户。如果未在您的集群上正确配置基于角色的访问控制,则任何具有 API 或 etcd 访问权限的人都可以检索或修改机密。此外,任何有权在命名空间中创建 Pod 的人都可以使用该访问权限来读取该命名空间中的任何机密。
为了安全地存储和管理您的机密,您可以配置 OpenShift Container Platform Secrets Store 容器存储接口 (CSI) 驱动程序运算符,以便使用提供程序插件从外部机密管理系统(例如 Azure Key Vault)挂载机密。然后,应用程序可以使用该机密,但在应用程序 Pod 被销毁后,该机密不会持久存在于系统中。
Secrets Store CSI 驱动程序操作符secrets-store.csi.k8s.io
使OpenShift Container Platform能够将存储在企业级外部密钥存储中的多个密钥、证书和秘密作为卷挂载到Pod中。Secrets Store CSI 驱动程序操作符使用gRPC与提供程序通信,从指定的外部密钥存储中获取挂载内容。卷挂载后,其中的数据会挂载到容器的文件系统中。密钥存储卷是内联挂载的。
访问OpenShift Container Platform Web 控制台。
集群的管理员访问权限。
要安装 Secrets Store CSI 驱动程序:
安装 Secrets Store CSI 驱动程序操作符
登录到Web控制台。
点击**操作符** → **OperatorHub**。
在筛选框中输入“Secrets Store CSI”来查找 Secrets Store CSI 驱动程序操作符。
点击**Secrets Store CSI Driver Operator**按钮。
在**Secrets Store CSI Driver Operator**页面上,点击**安装**。
在**安装操作符**页面上,确保:
已选择**集群上的所有命名空间(默认)**。
**已安装命名空间**设置为**openshift-cluster-csi-drivers**。
点击**安装**。
安装完成后,Secrets Store CSI 驱动程序操作符将列在Web控制台的**已安装操作符**部分。
为驱动程序(secrets-store.csi.k8s.io
)创建ClusterCSIDriver
实例
点击**管理** → **自定义资源定义** → **ClusterCSIDriver**。
在**实例**选项卡上,点击**创建 ClusterCSIDriver**。
使用以下YAML文件
apiVersion: operator.openshift.io/v1
kind: ClusterCSIDriver
metadata:
name: secrets-store.csi.k8s.io
spec:
managementState: Managed
点击**创建**。
安装 Secrets Store CSI 驱动程序操作符后,您可以将密钥从以下外部密钥存储之一挂载到CSI卷:
您可以使用 Secrets Store CSI 驱动程序操作符将密钥从AWS Secrets Manager挂载到OpenShift Container Platform中的容器存储接口(CSI)卷。要从AWS Secrets Manager挂载密钥,您的集群必须安装在AWS上并使用AWS安全令牌服务(STS)。
您的集群安装在AWS上并使用AWS安全令牌服务(STS)。
您已安装 Secrets Store CSI 驱动程序操作符。有关说明,请参见*安装 Secrets Store CSI 驱动程序*。
您已配置AWS Secrets Manager以存储所需的密钥。
您已提取并准备了ccoctl
二进制文件。
您已安装jq
CLI工具。
您可以作为具有cluster-admin
角色的用户访问集群。
安装AWS Secrets Manager提供程序
创建一个包含以下提供程序资源配置的YAML文件
Secrets 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密钥对象
创建一个目录来包含凭据请求,方法是运行以下命令
$ 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>"
创建一个密钥提供程序类来定义您的密钥存储提供程序
创建一个定义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"
1 | 指定密钥提供程序类的名称。 |
2 | 指定密钥提供程序类的命名空间。 |
3 | 将提供程序指定为aws 。 |
4 | 指定特定于提供程序的配置参数。 |
通过运行以下命令创建SecretProviderClass
对象
$ oc create -f secret-provider-class-aws.yaml
创建一个使用此密钥提供程序类的部署
创建一个定义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)
1 | 指定部署的名称。 |
2 | 指定部署的命名空间。这必须与密钥提供程序类的命名空间相同。 |
3 | 指定密钥提供程序类的名称。 |
通过运行以下命令创建Deployment
对象
$ oc create -f deployment.yaml
验证您可以访问Pod卷装载中的AWS Secrets Manager中的密钥
通过运行以下命令列出Pod装载中的密钥
$ oc exec my-aws-deployment-<hash> -n my-namespace -- ls /mnt/secrets-store/
testSecret
通过运行以下命令查看Pod装载中的密钥
$ oc exec my-aws-deployment-<hash> -n my-namespace -- cat /mnt/secrets-store/testSecret
<secret_value>
您可以使用 Secrets Store CSI 驱动程序操作符将密钥从AWS Systems Manager参数存储挂载到OpenShift Container Platform中的容器存储接口(CSI)卷。要从AWS Systems Manager参数存储挂载密钥,您的集群必须安装在AWS上并使用AWS安全令牌服务(STS)。
您的集群安装在AWS上并使用AWS安全令牌服务(STS)。
您已安装 Secrets Store CSI 驱动程序操作符。有关说明,请参见*安装 Secrets Store CSI 驱动程序*。
您已配置AWS Systems Manager参数存储以存储所需的密钥。
您已提取并准备了ccoctl
二进制文件。
您已安装jq
CLI工具。
您可以作为具有cluster-admin
角色的用户访问集群。
安装AWS Systems Manager参数存储提供程序
创建一个包含以下提供程序资源配置的YAML文件
Secrets Store CSI 驱动程序的AWS Systems 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密钥对象
创建一个目录来包含凭据请求,方法是运行以下命令
$ 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>"
创建一个密钥提供程序类来定义您的密钥存储提供程序
创建一个定义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"
1 | 指定密钥提供程序类的名称。 |
2 | 指定密钥提供程序类的命名空间。 |
3 | 将提供程序指定为aws 。 |
4 | 指定特定于提供程序的配置参数。 |
通过运行以下命令创建SecretProviderClass
对象
$ oc create -f secret-provider-class-aws.yaml
创建一个使用此密钥提供程序类的部署
创建一个定义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)
1 | 指定部署的名称。 |
2 | 指定部署的命名空间。这必须与密钥提供程序类的命名空间相同。 |
3 | 指定密钥提供程序类的名称。 |
通过运行以下命令创建Deployment
对象
$ oc create -f deployment.yaml
验证您可以访问Pod卷装载中的AWS Systems Manager参数存储中的密钥
通过运行以下命令列出Pod装载中的密钥
$ oc exec my-aws-deployment-<hash> -n my-namespace -- ls /mnt/secrets-store/
testParameter
通过运行以下命令查看Pod装载中的密钥
$ oc exec my-aws-deployment-<hash> -n my-namespace -- cat /mnt/secrets-store/testSecret
<secret_value>
您可以使用 Secrets Store CSI Driver Operator 将 Azure Key Vault 中的密钥挂载到 OpenShift Container Platform 中的容器存储接口 (CSI) 卷。要挂载 Azure Key Vault 中的密钥,您的集群必须安装在 Microsoft Azure 上。
您的集群安装在 Azure 上。
您已安装 Secrets Store CSI 驱动程序操作符。有关说明,请参见*安装 Secrets Store CSI 驱动程序*。
您已配置 Azure Key Vault 来存储所需的密钥。
您已安装 Azure CLI(az
)。
您可以作为具有cluster-admin
角色的用户访问集群。
安装 Azure Key Vault 提供程序
创建一个包含以下提供程序资源配置的YAML文件
Secrets Store CSI Driver 的 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
创建一个服务主体来访问密钥保管库
通过运行以下命令将服务主体客户端密钥设置为环境变量
$ 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)"
通过运行以下命令创建一个包含服务主体客户端密钥和 ID 的通用密钥
$ 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
密钥
$ oc -n my-namespace label secret secrets-store-creds secrets-store.csi.k8s.io/used=true
创建一个密钥提供程序类来定义您的密钥存储提供程序
创建一个定义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"
1 | 指定密钥提供程序类的名称。 |
2 | 指定密钥提供程序类的命名空间。 |
3 | 将提供程序指定为 azure 。 |
4 | 指定特定于提供程序的配置参数。 |
通过运行以下命令创建SecretProviderClass
对象
$ oc create -f secret-provider-class-azure.yaml
创建一个使用此密钥提供程序类的部署
创建一个定义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)
1 | 指定部署的名称。 |
2 | 指定部署的命名空间。这必须与密钥提供程序类的命名空间相同。 |
3 | 指定密钥提供程序类的名称。 |
4 | 指定包含访问 Azure Key Vault 的服务主体凭据的 Kubernetes 密钥的名称。 |
通过运行以下命令创建Deployment
对象
$ oc create -f deployment.yaml
验证您能否在 Pod 卷挂载中访问 Azure Key Vault 中的密钥
通过运行以下命令列出Pod装载中的密钥
$ oc exec my-azure-deployment-<hash> -n my-namespace -- ls /mnt/secrets-store/
secret1
通过运行以下命令查看Pod装载中的密钥
$ oc exec my-azure-deployment-<hash> -n my-namespace -- cat /mnt/secrets-store/secret1
my-secret-value
您可以使用 Secrets Store CSI Driver Operator 将 Google Secret Manager 中的密钥挂载到 OpenShift Container Platform 中的容器存储接口 (CSI) 卷。要挂载 Google Secret Manager 中的密钥,您的集群必须安装在 Google Cloud Platform (GCP) 上。
您已安装 Secrets Store CSI 驱动程序操作符。有关说明,请参见*安装 Secrets Store CSI 驱动程序*。
您已配置 Google Secret Manager 来存储所需的密钥。
您已从您的 Google Cloud 服务帐户创建了一个名为 key.json
的服务帐户密钥。
您可以作为具有cluster-admin
角色的用户访问集群。
安装 Google Secret Manager 提供程序
创建一个包含以下提供程序资源配置的YAML文件
gcp-provider.yaml
文件示例apiVersion: v1
kind: ServiceAccount
metadata:
name: csi-secrets-store-provider-gcp
namespace: openshift-cluster-csi-drivers
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: csi-secrets-store-provider-gcp-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: csi-secrets-store-provider-gcp-role
subjects:
- kind: ServiceAccount
name: csi-secrets-store-provider-gcp
namespace: openshift-cluster-csi-drivers
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: csi-secrets-store-provider-gcp-role
rules:
- apiGroups:
- ""
resources:
- serviceaccounts/token
verbs:
- create
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- get
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: csi-secrets-store-provider-gcp
namespace: openshift-cluster-csi-drivers
labels:
app: csi-secrets-store-provider-gcp
spec:
updateStrategy:
type: RollingUpdate
selector:
matchLabels:
app: csi-secrets-store-provider-gcp
template:
metadata:
labels:
app: csi-secrets-store-provider-gcp
spec:
serviceAccountName: csi-secrets-store-provider-gcp
initContainers:
- name: chown-provider-mount
image: busybox
command:
- chown
- "1000:1000"
- /etc/kubernetes/secrets-store-csi-providers
volumeMounts:
- mountPath: "/etc/kubernetes/secrets-store-csi-providers"
name: providervol
securityContext:
privileged: true
hostNetwork: false
hostPID: false
hostIPC: false
containers:
- name: provider
image: us-docker.pkg.dev/secretmanager-csi/secrets-store-csi-driver-provider-gcp/plugin@sha256:a493a78bbb4ebce5f5de15acdccc6f4d19486eae9aa4fa529bb60ac112dd6650
securityContext:
privileged: true
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 50m
memory: 100Mi
limits:
cpu: 50m
memory: 100Mi
env:
- name: TARGET_DIR
value: "/etc/kubernetes/secrets-store-csi-providers"
volumeMounts:
- mountPath: "/etc/kubernetes/secrets-store-csi-providers"
name: providervol
mountPropagation: None
readOnly: false
livenessProbe:
failureThreshold: 3
httpGet:
path: /live
port: 8095
initialDelaySeconds: 5
timeoutSeconds: 10
periodSeconds: 30
volumes:
- name: providervol
hostPath:
path: /etc/kubernetes/secrets-store-csi-providers
tolerations:
- key: kubernetes.io/arch
operator: Equal
value: amd64
effect: NoSchedule
nodeSelector:
kubernetes.io/os: linux
通过运行以下命令授予 csi-secrets-store-provider-gcp
服务帐户特权访问权限
$ oc adm policy add-scc-to-user privileged -z csi-secrets-store-provider-gcp -n openshift-cluster-csi-drivers
通过运行以下命令创建提供程序资源
$ oc apply -f gcp-provider.yaml
授予读取 Google Secret Manager 密钥的权限
通过运行以下命令创建一个新项目
$ oc new-project my-namespace
通过运行以下命令为 pod 安全准入标记 my-namespace
命名空间
$ oc label ns my-namespace 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
为 Pod 部署创建服务帐户
$ oc create serviceaccount my-service-account --namespace=my-namespace
通过运行以下命令从 key.json
文件创建一个通用密钥
$ oc create secret generic secrets-store-creds -n my-namespace --from-file=key.json (1)
1 | 您是从 Google Secret Manager 创建了此 key.json 文件。 |
应用 secrets-store.csi.k8s.io/used=true
标签以允许提供程序找到此 nodePublishSecretRef
密钥
$ oc -n my-namespace label secret secrets-store-creds secrets-store.csi.k8s.io/used=true
创建一个密钥提供程序类来定义您的密钥存储提供程序
创建一个定义SecretProviderClass
对象的YAML文件
secret-provider-class-gcp.yaml
示例apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: my-gcp-provider (1)
namespace: my-namespace (2)
spec:
provider: gcp (3)
parameters: (4)
secrets: |
- resourceName: "projects/my-project/secrets/testsecret1/versions/1"
path: "testsecret1.txt"
1 | 指定密钥提供程序类的名称。 |
2 | 指定密钥提供程序类的命名空间。 |
3 | 将提供程序指定为 gcp 。 |
4 | 指定特定于提供程序的配置参数。 |
通过运行以下命令创建SecretProviderClass
对象
$ oc create -f secret-provider-class-gcp.yaml
创建一个使用此密钥提供程序类的部署
创建一个定义Deployment
对象的YAML文件
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-gcp-deployment (1)
namespace: my-namespace (2)
spec:
replicas: 1
selector:
matchLabels:
app: my-storage
template:
metadata:
labels:
app: my-storage
spec:
serviceAccountName: my-service-account (3)
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-gcp-provider" (4)
nodePublishSecretRef:
name: secrets-store-creds (5)
1 | 指定部署的名称。 |
2 | 指定部署的命名空间。这必须与密钥提供程序类的命名空间相同。 |
3 | 指定您创建的服务帐户。 |
4 | 指定密钥提供程序类的名称。 |
5 | 指定包含访问 Google Secret Manager 的服务主体凭据的 Kubernetes 密钥的名称。 |
通过运行以下命令创建Deployment
对象
$ oc create -f deployment.yaml
验证您能否在 Pod 卷挂载中访问 Google Secret Manager 中的密钥
通过运行以下命令列出Pod装载中的密钥
$ oc exec my-gcp-deployment-<hash> -n my-namespace -- ls /mnt/secrets-store/
testsecret1
通过运行以下命令查看Pod装载中的密钥
$ oc exec my-gcp-deployment-<hash> -n my-namespace -- cat /mnt/secrets-store/testsecret1
<secret_value>
您可以使用 Secrets Store CSI Driver Operator 将 HashiCorp Vault 中的密钥挂载到 OpenShift Container Platform 中的容器存储接口 (CSI) 卷。
使用 Secrets Store CSI Driver Operator 从 HashiCorp Vault 挂载密钥已在以下云提供商上进行了测试
其他云提供商可能有效,但尚未经过测试。未来可能会测试其他云提供商。 |
您已安装 Secrets Store CSI 驱动程序操作符。有关说明,请参见*安装 Secrets 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
通过运行以下命令为 vault
命名空间标记 pod 安全准入
$ 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
daemonset 以将 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 以存储所需的密钥
通过运行以下命令创建一个密钥
$ 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 身份验证方法
$ oc exec vault-0 --namespace=vault -- vault auth enable kubernetes
Success! Enabled kubernetes auth method at: kubernetes/
配置 Kubernetes 身份验证方法
通过运行以下命令将令牌查看器设置为环境变量
$ 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 身份验证方法
$ 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
创建一个密钥提供程序类来定义您的密钥存储提供程序
创建一个定义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
1 | 指定密钥提供程序类的名称。 |
2 | 指定密钥提供程序类的命名空间。 |
3 | 将提供程序指定为 vault 。 |
4 | 指定特定于提供程序的配置参数。 |
通过运行以下命令创建SecretProviderClass
对象
$ oc create -f secret-provider-class-vault.yaml
创建一个使用此密钥提供程序类的部署
创建一个定义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)
1 | 指定部署的名称。 |
2 | 指定部署的命名空间。这必须与密钥提供程序类的命名空间相同。 |
3 | 指定密钥提供程序类的名称。 |
通过运行以下命令创建Deployment
对象
$ oc create -f deployment.yaml
验证您能否在 Pod 卷挂载中访问 HashiCorp Vault 中的密钥
通过运行以下命令列出Pod装载中的密钥
$ oc exec busybox-deployment-<hash> -n my-namespace -- ls /mnt/secrets-store/
testSecret1
通过运行以下命令查看Pod装载中的密钥
$ oc exec busybox-deployment-<hash> -n my-namespace -- cat /mnt/secrets-store/testSecret1
my-secret-value
您可以启用同步以从挂载卷上的内容创建 Kubernetes 密钥。您可能想要启用同步的一个示例是使用部署中的环境变量来引用 Kubernetes 密钥。
如果您不想将密钥存储在 OpenShift Container Platform 集群和 etcd 中,请不要启用同步。仅当您需要时才启用此功能,例如当您想要使用环境变量来引用密钥时。 |
如果您启用同步,则在您启动挂载密钥的 Pod 后,挂载卷中的密钥将同步为 Kubernetes 密钥。
当挂载内容的所有 Pod 都被删除时,同步的 Kubernetes 密钥将被删除。
您已安装 Secrets Store CSI Driver Operator。
您已安装密钥存储提供程序。
您已创建密钥提供程序类。
您可以作为具有cluster-admin
角色的用户访问集群。
通过运行以下命令编辑 SecretProviderClass
资源
$ oc edit secretproviderclass my-azure-provider (1)
1 | 将 my-azure-provider 替换为您的密钥提供程序类的名称。 |
添加 secretsObjects
部分,其中包含同步的 Kubernetes 密钥的配置
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"
1 | 指定同步 Kubernetes 密钥的配置。 |
2 | 指定要创建的 Kubernetes Secret 对象的名称。 |
3 | 指定要创建的 Kubernetes Secret 对象的类型。例如,Opaque 或 kubernetes.io/tls 。 |
4 | 指定要同步的挂载内容的对象名称或别名。 |
5 | 指定要使用其填充 Kubernetes 密钥的指定 objectName 的数据字段。 |
保存文件以应用更改。
您可以查看 Pod 卷挂载中密钥的详细信息,包括版本。
Secrets Store CSI Driver Operator 在与 Pod 相同的命名空间中创建一个SecretProviderClassPodStatus
资源。您可以查看此资源以查看详细信息,包括 Pod 卷挂载中密钥的版本。
您已安装 Secrets Store CSI Driver Operator。
您已安装密钥存储提供程序。
您已创建密钥提供程序类。
您已部署了一个 Pod,该 Pod 挂载了来自 Secrets Store CSI Driver Operator 的卷。
您可以作为具有cluster-admin
角色的用户访问集群。
运行以下命令查看 Pod 卷挂载中密钥的详细信息
$ oc get secretproviderclasspodstatus <secret_provider_class_pod_status_name> -o yaml (1)
1 | 密钥提供程序类 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
访问OpenShift Container Platform Web 控制台。
集群的管理员访问权限。
要卸载 Secrets Store CSI Driver Operator:
停止所有使用secrets-store.csi.k8s.io
提供程序的应用程序 Pod。
删除您选择的密钥存储的任何第三方提供程序插件。
删除容器存储接口 (CSI) 驱动程序和相关的清单文件
点击**管理** → **自定义资源定义** → **ClusterCSIDriver**。
在“实例”选项卡上,对于secrets-store.csi.k8s.io,在最左侧单击下拉菜单,然后单击“删除 ClusterCSIDriver”。
出现提示时,单击“删除”。
验证 CSI 驱动程序 Pod 是否不再运行。
卸载 Secrets Store CSI Driver Operator
在卸载 Operator 之前,必须先删除 CSI 驱动程序。 |
单击“Operators”→“已安装的 Operators”。
在“已安装的 Operators”页面上,滚动或在“按名称搜索”框中键入“Secrets Store CSI”以查找 Operator,然后单击它。
在“已安装的 Operators”>“Operator 详情”页面的右上方,单击“操作”→“卸载 Operator”。
在“卸载 Operator”窗口中出现提示时,单击“卸载”按钮以从命名空间中删除 Operator。Operator 在集群上部署的任何应用程序都需要手动清理。
卸载后,Secrets Store CSI Driver Operator 将不再列在 Web 控制台的“已安装的 Operators”部分中。