1
0
mirror of https://github.com/openshift/openshift-docs.git synced 2026-02-07 00:48:01 +01:00
Files
openshift-docs/modules/secrets-store-vault.adoc
2025-03-06 14:39:24 +00:00

385 lines
11 KiB
Plaintext

// Module included in the following assemblies:
//
// * nodes/pods/nodes-pods-secrets-store.adoc
:_mod-docs-content-type: PROCEDURE
[id="secrets-store-vault_{context}"]
= Mounting secrets from HashiCorp Vault
You can use the {secrets-store-operator} to mount secrets from HashiCorp Vault to a Container Storage Interface (CSI) volume in {product-title}.
[IMPORTANT]
====
Mounting secrets from HashiCorp Vault by using the {secrets-store-operator} has been tested with the following cloud providers:
* Amazon Web Services (AWS)
* Microsoft Azure
Other cloud providers might work, but have not been tested yet. Additional cloud providers might be tested in the future.
====
.Prerequisites
* You installed the {secrets-store-operator}. See _Installing the {secrets-store-driver}_ for instructions.
* You installed Helm.
* You have access to the cluster as a user with the `cluster-admin` role.
.Procedure
. Add the HashiCorp Helm repository by running the following command:
+
[source,terminal]
----
$ helm repo add hashicorp https://helm.releases.hashicorp.com
----
. Update all repositories to ensure that Helm is aware of the latest versions by running the following command:
+
[source,terminal]
----
$ helm repo update
----
. Install the HashiCorp Vault provider:
.. Create a new project for Vault by running the following command:
+
[source,terminal]
----
$ oc new-project vault
----
.. Label the `vault` namespace for pod security admission by running the following command:
+
[source,terminal]
----
$ 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
----
.. Grant privileged access to the `vault` service account by running the following command:
+
[source,terminal]
----
$ oc adm policy add-scc-to-user privileged -z vault -n vault
----
.. Grant privileged access to the `vault-csi-provider` service account by running the following command:
+
[source,terminal]
----
$ oc adm policy add-scc-to-user privileged -z vault-csi-provider -n vault
----
.. Deploy HashiCorp Vault by running the following command:
+
[source,terminal]
----
$ 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"
----
.. Patch the `vault-csi-driver` daemon set to set the `securityContext` to `privileged` by running the following command:
+
[source,terminal]
----
$ oc patch daemonset -n vault vault-csi-provider --type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/securityContext", "value": {"privileged": true} }]'
----
.. Verify that the `vault-csi-provider` pods have started properly by running the following command:
+
[source,terminal]
----
$ oc get pods -n vault
----
+
.Example output
[source,terminal]
----
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
----
. Configure HashiCorp Vault to store the required secrets:
.. Create a secret by running the following command:
+
[source,terminal]
----
$ oc exec vault-0 --namespace=vault -- vault kv put secret/example1 testSecret1=my-secret-value
----
.. Verify that the secret is readable at the path `secret/example1` by running the following command:
+
[source,terminal]
----
$ oc exec vault-0 --namespace=vault -- vault kv get secret/example1
----
+
.Example output
[source,terminal]
----
= 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
----
. Configure Vault to use Kubernetes authentication:
.. Enable the Kubernetes auth method by running the following command:
+
[source,terminal]
----
$ oc exec vault-0 --namespace=vault -- vault auth enable kubernetes
----
+
.Example output
[source,terminal]
----
Success! Enabled kubernetes auth method at: kubernetes/
----
.. Configure the Kubernetes auth method:
... Set the token reviewer as an environment variable by running the following command:
+
[source,terminal]
----
$ TOKEN_REVIEWER_JWT="$(oc exec vault-0 --namespace=vault -- cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
----
... Set the Kubernetes service IP address as an environment variable by running the following command:
+
[source,terminal]
----
$ KUBERNETES_SERVICE_IP="$(oc get svc kubernetes --namespace=default -o go-template="{{ .spec.clusterIP }}")"
----
... Update the Kubernetes auth method by running the following command:
+
[source,terminal]
----
$ 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
----
+
.Example output
[source,terminal]
----
Success! Data written to: auth/kubernetes/config
----
.. Create a policy for the application by running the following command:
+
[source,terminal]
----
$ oc exec -i vault-0 --namespace=vault -- vault policy write csi -<<EOF
path "secret/data/*" {
capabilities = ["read"]
}
EOF
----
+
.Example output
[source,terminal]
----
Success! Uploaded policy: csi
----
.. Create an authentication role to access the application by running the following command:
+
[source,terminal]
----
$ 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
----
+
.Example output
[source,terminal]
----
Success! Data written to: auth/kubernetes/role/csi
----
.. Verify that all of the `vault` pods are running properly by running the following command:
+
[source,terminal]
----
$ oc get pods -n vault
----
+
.Example output
[source,terminal]
----
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
----
.. Verify that all of the `secrets-store-csi-driver` pods are running properly by running the following command:
+
[source,terminal]
----
$ oc get pods -n openshift-cluster-csi-drivers | grep -E "secrets"
----
+
.Example output
[source,terminal]
----
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
----
. Create a secret provider class to define your secrets store provider:
.. Create a YAML file that defines the `SecretProviderClass` object:
+
.Example `secret-provider-class-vault.yaml`
[source,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> Specify the name for the secret provider class.
<2> Specify the namespace for the secret provider class.
<3> Specify the provider as `vault`.
<4> Specify the provider-specific configuration parameters.
.. Create the `SecretProviderClass` object by running the following command:
+
[source,terminal]
----
$ oc create -f secret-provider-class-vault.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: 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> 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.
.. 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 your HashiCorp Vault in the pod volume mount:
.. List the secrets in the pod mount by running the following command:
+
[source,terminal]
----
$ oc exec busybox-deployment-<hash> -n my-namespace -- ls /mnt/secrets-store/
----
+
.Example output
[source,terminal]
----
testSecret1
----
.. View a secret in the pod mount by running the following command:
+
[source,terminal]
----
$ oc exec busybox-deployment-<hash> -n my-namespace -- cat /mnt/secrets-store/testSecret1
----
+
.Example output
[source,terminal]
----
my-secret-value
----