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
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>
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.