Add Envkey to a Docker app in Kubernetes, without rebuilding the image

Dan Maas
2 min readAug 23, 2018

I’m a big fan of using Envkey to manage parameters and credentials across different services like AWS, GCP, Docker, and Kubernetes.

One minor drawback of Envkey is that the normal methods of integrating it require you to modify either your app code, to invoke the language-appropriate envkey library, or your Dockerfile, to download and run the envkey-source binary.

This makes it difficult to use community-maintained Docker images. If you want to use Envkey, you have to fork your own version of the Dockerfile, modify it to inject Envkey, then rebuild and host the modified image yourself.

On Kubernetes, however, I discovered a neat method to integrate Envkey with any unmodified Docker image. Kubernetes provides an initContainers feature that runs a separate container attached to your pod as it starts up. We can specify an initContainer that downloads Envkey and saves the environment variables in a place where the main container can pick them up.

The Deployment specification with Envkey looks like this:

spec:
# create a volume to share between
# envkey and the main container
volumes:
- name: envkey
emptyDir: {}
initContainers:
# here is the Envkey container
- name: envkey
image: appropriate/curl
command:
- "sh"
- "-c"
# use curl to download, install, and run envkey
- "curl -s \
https://raw.githubusercontent.com/envkey/envkey-source/master/install.sh \
| /bin/sh && envkey-source > /envkey/export-env && chmod -R 777 /envkey"
# at this point, the variables will be in a file called
# /envkey/export-env
# chmod/chown may be necessary depending on the user
# account under which the main container runs.
volumeMounts:
- name: envkey
mountPath: "/envkey"
env:
# use a Kubernetes secret to hold the ENVKEY itself
- name: ENVKEY
valueFrom:
secretKeyRef:
key: ENVKEY
name: my-envkey
containers:
- name: my-main-container
image: my-docker-image
volumeMounts:
- name: envkey
mountPath: "/envkey"
command:
- "sh"
- "-c"
# note: you have to override the standard container
# command here, to load the envkey variables first.
# Check the Dockerfile for the appropriate CMD.
- ". /envkey/export-env && \
my-docker-image-entrypoint"

A couple of notes:

  • We have to load the Envkey variables into the main container’s process environment before invoking the standard entry point. This means we have to peek at the Dockerfile that was used to build the container so that we can duplicate the same command. (there does not seem to be a way to over-ride just part of the entry point).
  • This also requires that /bin/sh is available in the Docker container. Most public images do have this.
  • The environment variables won’t be updated while the container is running. This shouldn’t be an issue if you are following an immutable-infrastructure philosophy.
  • You need a way to carry the ENVKEY itself into the init container’s environment. A Kubernetes secret is a great way to do this.

--

--