1
0
mirror of https://github.com/openshift/openshift-docs.git synced 2026-02-05 12:46:18 +01:00
Files
openshift-docs/modules/secrets-store-azure.adoc
2025-11-14 07:40:30 +00:00

311 lines
9.0 KiB
Plaintext

// Module included in the following assemblies:
//
// * nodes/pods/nodes-pods-secrets-store.adoc
:_mod-docs-content-type: PROCEDURE
[id="secrets-store-azure_{context}"]
= Mounting secrets from {azure-short} Key Vault
You can use the {secrets-store-operator} to mount secrets from {azure-first} Key Vault to a Container Storage Interface (CSI) volume in {product-title}. To mount secrets from {azure-short} Key Vault.
.Prerequisites
* Your have installed a cluster on {azure-short}.
* You have access to the cluster as a user with the `cluster-admin` role.
* You have installed the {azure-short} CLI (`az`).
* You have installed the {secrets-store-operator}. See "Installing the {secrets-store-driver}" for instructions.
* You have configured {azure-short} Key Vault to store the required secrets.
.Procedure
. Install the {azure-short} Key Vault provider:
.. Create a YAML file named `azure-provider.yaml` that defines the `ServiceAccount` resource configuration. See the following example configuration:
+
[IMPORTANT]
====
The {azure-short} Key Vault provider for the {secrets-store-driver} is an upstream provider.
This configuration is modified from the configuration provided in the upstream link:https://azure.github.io/secrets-store-csi-driver-provider-azure/docs/getting-started/installation/[{azure-short} documentation] so that it works properly with {product-title}. Changes to this configuration might impact functionality.
====
+
.Example `azure-provider.yaml` file
[source,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
----
.. Grant privileged access to the `csi-secrets-store-provider-azure` service account by running the following command:
+
[source,terminal]
----
$ oc adm policy add-scc-to-user privileged -z csi-secrets-store-provider-azure -n openshift-cluster-csi-drivers
----
.. Create the provider resources by running the following command:
+
[source,terminal]
----
$ oc apply -f azure-provider.yaml
----
. Create a service principal to access the key vault:
.. Set the service principal client secret as an environment variable by running the following command:
+
[source,terminal]
----
$ SERVICE_PRINCIPAL_CLIENT_SECRET="$(az ad sp create-for-rbac --name https://$KEYVAULT_NAME --query 'password' -otsv)"
----
.. Set the service principal client ID as an environment variable by running the following command:
+
[source,terminal]
----
$ SERVICE_PRINCIPAL_CLIENT_ID="$(az ad sp list --display-name https://$KEYVAULT_NAME --query '[0].appId' -otsv)"
----
.. Create a generic secret with the service principal client secret and ID by running the following command:
+
[source,terminal]
----
$ oc create secret generic secrets-store-creds -n my-namespace --from-literal clientid=${SERVICE_PRINCIPAL_CLIENT_ID} --from-literal clientsecret=${SERVICE_PRINCIPAL_CLIENT_SECRET}
----
.. Apply the `secrets-store.csi.k8s.io/used=true` label to allow the provider to find this `nodePublishSecretRef` secret:
+
[source,terminal]
----
$ oc -n my-namespace label secret secrets-store-creds secrets-store.csi.k8s.io/used=true
----
. Create a secret provider class to define your secrets store provider:
.. Create a YAML file that defines the `SecretProviderClass` object:
+
.Example `secret-provider-class-azure.yaml`
[source,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> Specify the name for the secret provider class.
<2> Specify the namespace for the secret provider class.
<3> Specify the provider as `azure`.
<4> Specify the provider-specific configuration parameters.
.. Create the `SecretProviderClass` object by running the following command:
+
[source,terminal]
----
$ oc create -f secret-provider-class-azure.yaml
----
. Create a deployment to use this secret provider class:
.. Create a YAML file that defines the `Deployment` object:
+
.Example `deployment.yaml`
[source,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> Specify the name for the deployment.
<2> Specify the namespace for the deployment. This must be the same namespace as the secret provider class.
<3> Specify the name of the secret provider class.
<4> Specify the name of the Kubernetes secret that contains the service principal credentials to access {azure-short} Key Vault.
.. Create the `Deployment` object by running the following command:
+
[source,terminal]
----
$ oc create -f deployment.yaml
----
.Verification
* Verify that you can access the secrets from {azure-short} Key Vault in the pod volume mount:
.. List the secrets in the pod mount by running the following command:
+
[source,terminal]
----
$ oc exec my-azure-deployment-<hash> -n my-namespace -- ls /mnt/secrets-store/
----
+
.Example output
[source,terminal]
----
secret1
----
.. View a secret in the pod mount by running the following command:
+
[source,terminal]
----
$ oc exec my-azure-deployment-<hash> -n my-namespace -- cat /mnt/secrets-store/secret1
----
+
.Example output
[source,terminal]
----
my-secret-value
----