Examples
Syncing Docker Registry Credentials to Kubernetes
If a Pod being defined in Kubernetes has an image in a private registry, you'll need to specify the imagePullSecrets
attribute on the definition or Kubernetes won't know where to fetch the image from or what credentials to use. This guide walks through how to set this up so your credentials are stored in Doppler and synced to Kubernetes through our operator.
For the purpose of this example, we'll be assuming you're using AWS ECR. If you're using another registry, be sure to adjust the example values accordingly.
1. Create memcached repository
In this example we'll be using the public memcached
image. You would simply replace this image with your own and otherwise follow the same process in production. Note that if you already have a repository named memcached
in your registry you can namespace it or alter the name. Just be sure to make those adjustments wherever the image is referenced.
-
Create the repository:
aws ecr create-repository --repository-name memcached
-
Pull the public image:
docker pull memcached
-
Tag the image:
docker memcached:latest YOUR_REGISTRY_ID.dkr.ecr.YOUR_AWS_REGION.amazonaws.com/memcached:latest
-
Push the image to your registry:
docker push YOUR_REGISTRY_ID.dkr.ecr.YOUR_AWS_REGION.amazonaws.com/memcached:latest
2. Create secrets in Doppler
Create the following secrets in the Doppler project of your choice.
-
DOCKER_USERNAME
For AWS ECR, this should be
AWS
. If you're using another registry, be sure to set it to the appropriate value. -
DOCKER_PASSWORD
You can obtain a valid token to use here by running
aws ecr get-login-password --region YOUR_AWS_REGION
. The value you get will be base64-encoded and should be stored in Doppler as such. Keep in mind that these tokens expire after 12 hours, so it needs to be updated on a schedule to ensure your credentials stay valid (e.g., use a GitHub Actions cronjob to update the secret in Doppler every 6-10 hours). -
DOCKER_AUTH
This secret should be the base64-encoded value of
${DOCKER_USERNAME}:${DOCKER_PASSWORD}
. You can obtain this by runningecho -n "${DOCKER_USERNAME}:${DOCKER_PASSWORD}" | base64
(make sure those environment variables are either set correctly when running this or that you've replaced those with the static values when running this). -
DOCKER_HOST
The host of your registry. For AWS ECR, it will look something like this:
YOUR_REGISTRY_ID.dkr.ecr.YOUR_AWS_REGION.amazonaws.com
. -
DOCKER_IMAGE
The fully qualified image name (with tag). This should look something like this:
${DOCKER_HOST}/memcached:latest
. -
DOCKER_CONFIG_JSON
This is the actual JSON that will get populated in the kubernetes secret that's storing the dockerconfigjson. It should look like this:
{ "auths": { "${DOCKER_HOST}": { "username": "${DOCKER_USERNAME}", "password": "${DOCKER_PASSWORD}", "auth": "${DOCKER_AUTH}" } } }
3. Install and setup the operator
If you haven't already, follow our instructions for installing the operator.
Make sure you have a kubernetes secret created containing a Doppler token. This guide expects it to be called doppler-token-secret
. For testing purposes, you can use your local Doppler CLI token:
kubectl create secret generic doppler-token-secret \
--namespace doppler-operator-system \
--from-literal=serviceToken=$(doppler configure get token --plain)
4. Create DopplerSecret resource to sync secrets
Now, create a new DopplerSecret
resource to get your secrets syncing (be sure to replace YOUR_DOPPLER_PROJECT
and YOUR_DOPPLER_CONFIG
with the project and config you're using here):
apiVersion: secrets.doppler.com/v1alpha1
kind: DopplerSecret
metadata:
name: memcached-docker-registry
namespace: doppler-operator-system
spec:
tokenSecret:
name: doppler-token-secret
namespace: doppler-operator-system
project: YOUR_DOPPLER_PROJECT
config: YOUR_DOPPLER_CONFIG
managedSecret:
name: memcached-docker-registry
namespace: default
type: kubernetes.io/dockerconfigjson
secrets:
- DOCKER_CONFIG_JSON
processors:
DOCKER_CONFIG_JSON:
asName: .dockerconfigjson
type: plain
This will create a new DopplerSecret
resource called memcached-docker-registry
in the doppler-operator-system
namespace. It will then create a kubernetes secret called memcached-docker-registry
in the default
namespace with the type kubernetes.io/dockerconfigjson
. The secrets
attribute allows you to specify a subset of secrets you want to sync from Doppler. If specified, only the those secrets and the DOPPLER_*
managed secrets will be synced over. We then use the processors
attribute to ensure the DOCKER_CONFIG_JSON
secret is renamed to .dockerconfigjson
. The kubernetes.io/dockerconfigjson
secret type is handled specially too and will not include the DOPPLER_*
secrets like it would with other types.
Note that once you create this resource, it may take up to a minute before the kubernetes secret is synced to. Be sure it exists and has the expected value before proceeding. You can try fetching the secret using this command:
kubectl describe secret memcached-docker-registry
Once it exists, you should see something similar to the following:
Name: memcached-docker-registry
Namespace: default
Labels: secrets.doppler.com/subtype=dopplerSecret
.
.
.
Type: kubernetes.io/dockerconfigjson
Data
====
.dockerconfigjson: 4156 bytes
5. Create Pod resource that uses private registry
Now, it's time to create a new Pod that uses the registry credentials secret we just synced over. We'll use secret injection templates to inject the DOCKER_IMAGE
secret into the resource definition.
apiVersion: v1
kind: Pod
metadata:
name: memcached
namespace: default
spec:
containers:
- name: memcached
image: {{.DOCKER_IMAGE}}
imagePullSecrets:
- name: memcached-docker-registry
To apply this run:
kubectl apply -f <(doppler secrets substitute -p YOUR_DOPPLER_PROJECT -c YOUR_DOPPLER_CONFIG pod.yml)
6. Keeping the DOCKER_PASSWORD from expiring
The aws ecr get-login-password
command returns a token that's valid for 12 hours. This obviously won't work inside your kubernetes cluster. To keep this up-to-date, you need to run a task in a cron-like environment that allows you to run scheduled jobs. Inside that job, you need to execute the following command (make sure DOCKER_USERNAME
is passed in via the environment along with your AWS and Doppler credentials):
new_password=$(aws ecr get-login-password --region YOUR_AWS_REGION)
new_auth=$(echo -n "$DOCKER_USERNAME:$new_password" | base64)
doppler secrets set -p YOUR_DOPPLER_PROJECT -c YOUR_DOPPLER_CONFIG DOCKER_PASSWORD=$new_password DOCKER_AUTH=$new_auth
This task should run at least once every 12 hours (and realistically, you'll probably want it to run every 10 hours or so to ensure the token doesn't expire before it's updated). When you update the secrets in Doppler, they'll automatically get synced to your kubernetes cluster.
Updated 21 days ago