This is similar to questions that have been asked before (for example How to inject secrets from Google Secret Manager into K8s pod? and Loading secrets as ENV from init container), but I'm looking for an actual example of a deployment.yaml
file.
Let's say I have this Kubernetes yaml file:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
name: my-app
spec:
selector:
matchLabels:
name: "my-app"
template:
metadata:
labels:
name: "my-app"
version: "1.0.0"
spec:
serviceAccountName: my-app
containers:
- name: "my-app"
env:
- name: DB_USER
value: postgres
- name: DB_PASS
value: password
- name: DB_NAME
value: postgres
image: "my-app:1.0.0"
...
We have stored the "DB_USER" and "DB_PASS" in Google Secret Manager and are looking for a way to pass these secrets to "my-app" as environment variables. I've found the ghcr.io/doitintl/secrets-init:0.4.7 image which seems very promising, but I cannot seem to find any example of how to actually use it with Google Cloud Secret Manager in Kubernetes. What I'm looking for is how to modify the example above to load the secrets "DB_USER" and "DB_PASS" from Goolge Secret Manager and pass them as environment variables.
So I managed to get it to work using ideas from https://itnext.io/kubernetes-and-secrets-management-in-cloud-858533c20dca The main hint being
"In order to use secrets-init with Kubernetes object (Pod/Deployment/Job/etc) without modifying Docker image, consider injecting secrets-init into a target Pod through initContainer. Copy secrets-init binary from init container to a common shared volume and change Pod command to run secrets-init as a first command."
Your deployment.yaml would look like this
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
name: my-app
spec:
selector:
matchLabels:
name: "my-app"
template:
metadata:
labels:
name: "my-app"
version: "1.0.0"
spec:
serviceAccountName: my-app
volumes:
- name: secrets-init-volume
emptyDir: { }
initContainers:
- name: secrets-init
image: doitintl/secrets-init:0.3.6
command:
- sh
args:
- -c
- "cp /usr/local/bin/secrets-init /secrets-init/bin/"
volumeMounts:
- mountPath: /secrets-init/bin
name: secrets-init-volume
containers:
- name: "my-app"
env:
- name: DB_USER
value: postgres
- name: DB_PASS
value: gcp:secretmanager:projects/PROJECT_ID/secrets/SECRET_NAME
- name: DB_NAME
value: postgres
image: "my-app:1.0.0"
command:
- "/secrets-init/bin/secrets-init"
args:
- "--provider=google"
- YOUR_ACTUAL_STARTUP_SCRIPT_FOR_YOUR_IMAGE
Main Points
secret-init
into a shared volume (in this case secrets-init-volume
)/secrets/init/secrets-init
which becomes the entrypoint command"--provider=google"
has to be passed as the first argument to secrets-init command as aws is the default provider.my-app
) should have the IAM permission to access Secret Manager in GCP