Using ENVs for values in Kubernets manifest file

6/7/2019

I'm laying the foundation for a new project where we will have an application running on Google Kubernetes Engine with multiple environments (development, staging, production). Each environment is its own GC Project.

I'm writing some manifest files and I'd like to abstract out any environment specific values so it can be re-used depending what environment (project) were updating/deploying to.

I have created values in Kubernetes Secrets, and turning those into ENV's is straight forward (see DATABASE_URL). However, if I wanted to use a variable for the value of the container image: gcr.io/my-app-production-123:latest, how would I pass in the value from a secret?

Is this the correct approach to abstracting environment specific values from manifest files? Thank you!

apiVersion: batch/v1
kind: Job
metadata:
  name: db-migrate
spec:
  completions: 1
  template:
    metadata:
      name: db-migrate
    spec:
      restartPolicy: Never
      containers:
      - name: db-migrate
        # how can I reference secret/env for the value of image:?
        image: gcr.io/my-app-production-242920:latest
        args: ["bundle", "exec", "rake", "db:create", "db:migrate"]
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: app-secrets
              key: DATABASE_URL
-- theartofbeing
google-kubernetes-engine
kubernetes

2 Answers

6/7/2019

You can mount your secret inside the container and use it, documentation.

Example:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: db-migrate
    image: gcr.io/my-app-production-242920:latest
    args: ["bundle", "exec", "rake", "db:create", "db:migrate"]
    volumeMounts:
    - name: <these_names_are_same>
      mountPath: "/container/where/to/mount"
      readOnly: true
  volumes:
  - name: <these_names_are_same>
    secret:
      secretName: <your deployed secret name>
-- Vishrant
Source: StackOverflow

6/8/2019

You probably need to use a higher-level tool to inject variables like this. The one I'm familiar with is Helm but there are other tools that let you inject parameters into the YAML files as well.

You can't use secrets the way you're describing. The only things you can do with secrets (or config maps, they're very similar) are to mount them as files or use them to set environment variables. You can, to a limited extent, use environment variables to define other parts of the config; but if you look at the API reference for containers the places where the $(VARIABLE) syntax is allowed are specifically called out, and it is only allowed for args:, command:, and env:.

In Helm you can use Go's templating syntax in your YAML files, and so could write

image: gcr.io/my-app-production:{{ .Values.tag }}

and then deploy the service with something like

helm install ./my-app --set tag=242920

but I'm pretty sure there's not a way to parameterize pods (or deployments or statefulsets or ...) in plain unadorned Kubernetes.

-- David Maze
Source: StackOverflow