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.yamlapiVersion: 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.yamlapiVersion: 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.yamlapiVersion: 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.yamlapiVersion: 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.yamlapiVersion: 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.yamlapiVersion: 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.yamlapiVersion: 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”部分中。