1

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.

Johan
  • 37,479
  • 32
  • 149
  • 237
  • From https://itnext.io/kubernetes-and-secrets-management-in-cloud-858533c20dca "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." Have you tried this? I will give it a try when I get a chance and see if it works as it states. – ameenhere Mar 14 '23 at 10:55
  • Thanks for the hint, but yes, I've tried it, but I don't get it work, which is why I'd like to see a working example. – Johan Mar 14 '23 at 12:16
  • I think I managed to get it to work. Will format an answer soon with an example similar to your deployment.yaml – ameenhere Mar 14 '23 at 15:16

1 Answers1

3

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

  • An initContainer with the secrets-init image is added, it copies the binary secret-init into a shared volume (in this case secrets-init-volume)
  • Your main container uses the shared volume, and uses the binary as the very first command. In this case the path to binary is /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.
  • The serviceAccountName that you specify (in your case my-app) should have the IAM permission to access Secret Manager in GCP
ameenhere
  • 2,203
  • 21
  • 36