Skip to content

Commit 1f4673a

Browse files
authored
Merge pull request #76657 from bergerhoffer/OSDOCS-10136
OSDOCS#10136: Adding docs for secrets store CSI driver operator with …
2 parents c4f75a2 + 110d6d9 commit 1f4673a

File tree

3 files changed

+380
-0
lines changed

3 files changed

+380
-0
lines changed

modules/secrets-store-providers.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ The following secrets store providers are available for use with the {secrets-st
1111
* AWS Secrets Manager
1212
* AWS Systems Manager Parameter Store
1313
* Azure Key Vault
14+
* HashiCorp Vault

modules/secrets-store-vault.adoc

Lines changed: 375 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,375 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * nodes/pods/nodes-pods-secrets-store.adoc
4+
5+
:_mod-docs-content-type: PROCEDURE
6+
[id="secrets-store-vault_{context}"]
7+
= Mounting secrets from HashiCorp Vault
8+
9+
You can use the {secrets-store-operator} to mount secrets from HashiCorp Vault to a CSI volume in {product-title}. To mount secrets from HashiCorp Vault, your cluster must be installed either on AWS with AWS Security Token Service (STS) or on Microsoft Azure.
10+
11+
.Prerequisites
12+
13+
* Your cluster is installed on AWS or Azure.
14+
* You have installed the {secrets-store-operator}. See _Installing the {secrets-store-driver}_ for instructions.
15+
* You have installed Helm.
16+
* You have access to the cluster as a user with the `cluster-admin` role.
17+
18+
.Procedure
19+
20+
. Add the HashiCorp Helm repository by running the following command:
21+
+
22+
[source,terminal]
23+
----
24+
$ helm repo add hashicorp https://helm.releases.hashicorp.com
25+
----
26+
27+
. Update all repositories to ensure that Helm is aware of the latest versions by running the following command:
28+
+
29+
[source,terminal]
30+
----
31+
$ helm repo update
32+
----
33+
34+
. Install the HashiCorp Vault provider:
35+
36+
.. Create a new project for Vault by running the following command:
37+
+
38+
[source,terminal]
39+
----
40+
$ oc new-project vault
41+
----
42+
43+
.. Label the `vault` namespace for pod security admission by running the following command:
44+
+
45+
[source,terminal]
46+
----
47+
$ 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
48+
----
49+
50+
.. Grant privileged access to the `vault` service account by running the following command:
51+
+
52+
[source,terminal]
53+
----
54+
$ oc adm policy add-scc-to-user privileged -z vault -n vault
55+
----
56+
57+
.. Grant privileged access to the `vault-csi-provider` service account by running the following command:
58+
+
59+
[source,terminal]
60+
----
61+
$ oc adm policy add-scc-to-user privileged -z vault-csi-provider -n vault
62+
----
63+
64+
.. Deploy HashiCorp Vault by running the following command:
65+
+
66+
[source,terminal]
67+
----
68+
$ helm install vault hashicorp/vault --namespace=vault \
69+
--set "server.dev.enabled=true" \
70+
--set "injector.enabled=false" \
71+
--set "csi.enabled=true" \
72+
--set "global.openshift=true" \
73+
--set "injector.agentImage.repository=docker.io/hashicorp/vault" \
74+
--set "server.image.repository=docker.io/hashicorp/vault" \
75+
--set "csi.image.repository=docker.io/hashicorp/vault-csi-provider" \
76+
--set "csi.agent.image.repository=docker.io/hashicorp/vault" \
77+
--set "csi.daemonSet.providersDir=/var/run/secrets-store-csi-providers"
78+
----
79+
80+
.. Patch the `vault-csi-driver` daemon set to set the `securityContext` to `privileged` by running the following command:
81+
+
82+
[source,terminal]
83+
----
84+
$ oc patch daemonset -n vault vault-csi-provider --type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/securityContext", "value": {"privileged": true} }]'
85+
----
86+
87+
.. Verify that the `vault-csi-provider` pods have started properly by running the following command:
88+
+
89+
[source,terminal]
90+
----
91+
$ oc get pods -n vault
92+
----
93+
+
94+
.Example output
95+
[source,terminal]
96+
----
97+
NAME READY STATUS RESTARTS AGE
98+
vault-0 1/1 Running 0 24m
99+
vault-csi-provider-87rgw 1/2 Running 0 5s
100+
vault-csi-provider-bd6hp 1/2 Running 0 4s
101+
vault-csi-provider-smlv7 1/2 Running 0 5s
102+
----
103+
104+
. Configure HashiCorp Vault to store the required secrets:
105+
106+
.. Create a secret by running the following command:
107+
+
108+
[source,terminal]
109+
----
110+
$ oc exec vault-0 --namespace=vault -- vault kv put secret/example1 testSecret1=my-secret-value
111+
----
112+
113+
.. Verify that the secret is readable at the path `secret/example1` by running the following command:
114+
+
115+
[source,terminal]
116+
----
117+
$ oc exec vault-0 --namespace=vault -- vault kv get secret/example1
118+
----
119+
+
120+
.Example output
121+
[source,terminal]
122+
----
123+
= Secret Path =
124+
secret/data/example1
125+
126+
======= Metadata =======
127+
Key Value
128+
--- -----
129+
created_time 2024-04-05T07:05:16.713911211Z
130+
custom_metadata <nil>
131+
deletion_time n/a
132+
destroyed false
133+
version 1
134+
135+
=== Data ===
136+
Key Value
137+
--- -----
138+
testSecret1 my-secret-value
139+
----
140+
141+
. Configure Vault to use Kubernetes authentication:
142+
143+
.. Enable the Kubernetes auth method by running the following command:
144+
+
145+
[source,terminal]
146+
----
147+
$ oc exec vault-0 --namespace=vault -- vault auth enable kubernetes
148+
----
149+
+
150+
.Example output
151+
[source,terminal]
152+
----
153+
Success! Enabled kubernetes auth method at: kubernetes/
154+
----
155+
156+
.. Configure the Kubernetes auth method:
157+
158+
... Set the token reviewer as an environment variable by running the following command:
159+
+
160+
[source,terminal]
161+
----
162+
$ TOKEN_REVIEWER_JWT="$(oc exec vault-0 --namespace=vault -- cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
163+
----
164+
... Set the Kubernetes service IP address as an environment variable by running the following command:
165+
+
166+
[source,terminal]
167+
----
168+
$ KUBERNETES_SERVICE_IP="$(oc get svc kubernetes -o go-template="{{ .spec.clusterIP }}")"
169+
----
170+
171+
... Update the Kubernetes auth method by running the following command:
172+
+
173+
[source,terminal]
174+
----
175+
$ oc exec -i vault-0 --namespace=vault -- vault write auth/kubernetes/config \
176+
issuer="https://kubernetes.default.svc.cluster.local" \
177+
token_reviewer_jwt="${TOKEN_REVIEWER_JWT}" \
178+
kubernetes_host="https://${KUBERNETES_SERVICE_IP}:443" \
179+
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
180+
----
181+
+
182+
.Example output
183+
[source,terminal]
184+
----
185+
Success! Data written to: auth/kubernetes/config
186+
----
187+
188+
.. Create a policy for the application by running the following command:
189+
+
190+
[source,terminal]
191+
----
192+
$ oc exec -i vault-0 --namespace=vault -- vault policy write csi -<<EOF
193+
path "secret/data/*" {
194+
capabilities = ["read"]
195+
}
196+
EOF
197+
----
198+
+
199+
.Example output
200+
[source,terminal]
201+
----
202+
Success! Uploaded policy: csi
203+
----
204+
205+
.. Create an authentication role to access the application by running the following command:
206+
+
207+
[source,terminal]
208+
----
209+
$ oc exec -i vault-0 --namespace=vault -- vault write auth/kubernetes/role/csi \
210+
bound_service_account_names=default \
211+
bound_service_account_namespaces=default,test-ns,negative-test-ns,my-namespace \
212+
policies=csi \
213+
ttl=20m
214+
----
215+
+
216+
.Example output
217+
[source,terminal]
218+
----
219+
Success! Data written to: auth/kubernetes/role/csi
220+
----
221+
222+
.. Verify that all of the `vault` pods are running properly by running the following command:
223+
+
224+
[source,terminal]
225+
----
226+
$ oc get pods -n vault
227+
----
228+
+
229+
.Example output
230+
[source,terminal]
231+
----
232+
NAME READY STATUS RESTARTS AGE
233+
vault-0 1/1 Running 0 43m
234+
vault-csi-provider-87rgw 2/2 Running 0 19m
235+
vault-csi-provider-bd6hp 2/2 Running 0 19m
236+
vault-csi-provider-smlv7 2/2 Running 0 19m
237+
----
238+
239+
.. Verify that all of the `secrets-store-csi-driver` pods are running properly by running the following command:
240+
+
241+
[source,terminal]
242+
----
243+
$ oc get pods -n openshift-cluster-csi-drivers | grep -E "secrets"
244+
----
245+
+
246+
.Example output
247+
[source,terminal]
248+
----
249+
secrets-store-csi-driver-node-46d2g 3/3 Running 0 45m
250+
secrets-store-csi-driver-node-d2jjn 3/3 Running 0 45m
251+
secrets-store-csi-driver-node-drmt4 3/3 Running 0 45m
252+
secrets-store-csi-driver-node-j2wlt 3/3 Running 0 45m
253+
secrets-store-csi-driver-node-v9xv4 3/3 Running 0 45m
254+
secrets-store-csi-driver-node-vlz28 3/3 Running 0 45m
255+
secrets-store-csi-driver-operator-84bd699478-fpxrw 1/1 Running 0 47m
256+
----
257+
258+
. Create a secret provider class to define your secrets store provider:
259+
260+
.. Create a YAML file that defines the `SecretProviderClass` object:
261+
+
262+
.Example `secret-provider-class-vault.yaml`
263+
[source,yaml]
264+
----
265+
apiVersion: secrets-store.csi.x-k8s.io/v1
266+
kind: SecretProviderClass
267+
metadata:
268+
name: my-vault-provider <1>
269+
namespace: my-namespace <2>
270+
spec:
271+
provider: vault <3>
272+
parameters: <4>
273+
roleName: "csi"
274+
vaultAddress: "http://vault.vault:8200"
275+
objects: |
276+
- secretPath: "secret/data/example1"
277+
objectName: "testSecret1"
278+
secretKey: "testSecret1
279+
----
280+
<1> Specify the name for the secret provider class.
281+
<2> Specify the namespace for the secret provider class.
282+
<3> Specify the provider as `vault`.
283+
<4> Specify the provider-specific configuration parameters.
284+
285+
.. Create the `SecretProviderClass` object by running the following command:
286+
+
287+
[source,terminal]
288+
----
289+
$ oc create -f secret-provider-class-vault.yaml
290+
----
291+
292+
. Create a deployment to use this secret provider class:
293+
294+
.. Create a YAML file that defines the `Deployment` object:
295+
+
296+
.Example `deployment.yaml`
297+
[source,yaml]
298+
----
299+
apiVersion: apps/v1
300+
kind: Deployment
301+
metadata:
302+
name: busybox-deployment <1>
303+
namespace: my-namespace <2>
304+
labels:
305+
app: busybox
306+
spec:
307+
replicas: 1
308+
selector:
309+
matchLabels:
310+
app: busybox
311+
template:
312+
metadata:
313+
labels:
314+
app: busybox
315+
spec:
316+
terminationGracePeriodSeconds: 0
317+
containers:
318+
- image: registry.k8s.io/e2e-test-images/busybox:1.29-4
319+
name: busybox
320+
imagePullPolicy: IfNotPresent
321+
command:
322+
- "/bin/sleep"
323+
- "10000"
324+
volumeMounts:
325+
- name: secrets-store-inline
326+
mountPath: "/mnt/secrets-store"
327+
readOnly: true
328+
volumes:
329+
- name: secrets-store-inline
330+
csi:
331+
driver: secrets-store.csi.k8s.io
332+
readOnly: true
333+
volumeAttributes:
334+
secretProviderClass: "my-vault-provider" <3>
335+
----
336+
<1> Specify the name for the deployment.
337+
<2> Specify the namespace for the deployment. This must be the same namespace as the secret provider class.
338+
<3> Specify the name of the secret provider class.
339+
340+
.. Create the `Deployment` object by running the following command:
341+
+
342+
[source,terminal]
343+
----
344+
$ oc create -f deployment.yaml
345+
----
346+
347+
.Verification
348+
349+
* Verify that you can access the secrets from your HashiCorp Vault in the pod volume mount:
350+
351+
.. List the secrets in the pod mount by running the following command:
352+
+
353+
[source,terminal]
354+
----
355+
$ oc exec busybox-<hash> -n my-namespace -- ls /mnt/secrets-store/
356+
----
357+
+
358+
.Example output
359+
[source,terminal]
360+
----
361+
testSecret1
362+
----
363+
364+
.. View a secret in the pod mount by running the following command:
365+
+
366+
[source,terminal]
367+
----
368+
$ oc exec busybox-<hash> -n my-namespace -- cat /mnt/secrets-store/testSecret1
369+
----
370+
+
371+
.Example output
372+
[source,terminal]
373+
----
374+
my-secret-value
375+
----

nodes/pods/nodes-pods-secrets-store.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ After installing the {secrets-store-operator}, you can mount secrets from one of
3333
* xref:../../nodes/pods/nodes-pods-secrets-store.adoc#secrets-store-aws_nodes-pods-secrets-store[AWS Secrets Manager]
3434
* xref:../../nodes/pods/nodes-pods-secrets-store.adoc#secrets-store-aws_nodes-pods-secrets-store-parameter-store[AWS Systems Manager Parameter Store]
3535
* xref:../../nodes/pods/nodes-pods-secrets-store.adoc#secrets-store-azure_nodes-pods-secrets-store[Azure Key Vault]
36+
* xref:../../nodes/pods/nodes-pods-secrets-store.adoc#secrets-store-vault_nodes-pods-secrets-store[HashiCorp Vault]
3637

3738
// Mounting secrets from AWS Secrets Manager
3839
:secrets-store-provider: AWS Secrets Manager
@@ -63,6 +64,9 @@ include::modules/secrets-store-aws.adoc[leveloffset=+2]
6364
// Mounting secrets from Azure Key Vault
6465
include::modules/secrets-store-azure.adoc[leveloffset=+2]
6566

67+
// Mounting secrets from HashiCorp Vault
68+
include::modules/secrets-store-vault.adoc[leveloffset=+2]
69+
6670
// Enabling synchronization of mounted content as Kubernetes secrets
6771
include::modules/secrets-store-sync-secrets.adoc[leveloffset=+1]
6872

0 commit comments

Comments
 (0)