This repository has been archived by the owner on Aug 4, 2021. It is now read-only.
forked from dashlabsai-archived/doppler-k8s-controller
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
More docs improvements and added deploy-example script
- Loading branch information
1 parent
47d83b7
commit 5f06083
Showing
12 changed files
with
136 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,119 +1,138 @@ | ||
# Doppler Kubernetes Controller (experimental) | ||
|
||
The Doppler Kubernetes controller automatically syncs secret changes from Doppler to Kubernetes secrets with the ability to reload deployments on secret change. | ||
Automatically sync secrets from Doppler to Kubernetes with auto-reload of Deployments when secrets change. | ||
|
||
## Installation | ||
![Doppler Kubernetes Controller Diagram](https://user-images.githubusercontent.com/133014/119946348-e2465280-bfd9-11eb-8d72-34afebbb538c.png) | ||
|
||
## Step 1. Deploying the Doppler Controller | ||
|
||
Deploy the controller by running: | ||
|
||
```bash | ||
kubectl apply -f doppler-crd-controller.yml | ||
kubectl rollout status -w deployment/doppler-controller --namespace doppler-controller | ||
``` | ||
|
||
## Step 1. Creating the DopplerSecret Resoure | ||
## Step 2. Creating a DopplerSecret | ||
|
||
The first step is to create a custom `DopplerSecret` resource, consisting of a name and a Doppler Service Token. | ||
|
||
The first step is to create a custom `DopplerSecret` resource that will be used by the controller to create a corresponding Kubernetes secret. The Kubernetes secret created contains a map of key value pairs. | ||
Upon `DopplerSecret` creation, the controller creates an associated Kubernetes secret, populating it with the secrets fetched from the Doppler API in Key-Value format. | ||
|
||
Save the following to `doppler-secret.yml`: | ||
To follow along with an example, update the code below with a real Service Token and save as `doppler-secret.yml`: | ||
|
||
```yaml | ||
apiVersion: 'doppler.com/v1' | ||
kind: DopplerSecret | ||
apiVersion: doppler.com/v1 | ||
kind: DopplerSecret | ||
metadata: | ||
name: doppler-secret | ||
name: dopplersecret-test # DopplerSecret resource name | ||
spec: | ||
serviceToken: 'dp.st.dev.Ix5TqVXsdOHq4FByFQbMadT3rotEHVZQ7v04NSbWT1I' # Doppler Service Token for config to sync | ||
secretName: app-secret # Name of Kubernetes Secret controller will create | ||
serviceToken: dp.st.dev.XXXX # Change to your Doppler Service Token | ||
secretName: doppler-test-secret # Kubernetes Secret name | ||
``` | ||
Create an example resource: | ||
Then create the `DopplerSecret`: | ||
|
||
```sh | ||
kubectl apply -f doppler-secret.yml | ||
``` | ||
|
||
Check that the Kubenertes secret has been created by the controller: | ||
Check that the associated Kubernetes secret has been created: | ||
|
||
```sh | ||
# List all Kubernetes secrets created by the Doppler controller | ||
kubectl describe secrets --selector=dopplerSecret=true | ||
# Or to view secret values | ||
./bin/get-secret.sh doppler-test-secret | ||
``` | ||
|
||
## Step 2. Configuring a Deployment | ||
The controller continuously watches for secret updates from Doppler and when detected, automatically and instantly updates the associated secret. | ||
|
||
As the controller creates a Kuberentes secret containing your secrets from Doppler, simply use the value for `secretName` used in the `DopplerSecret` resource. | ||
Next, we'll cover how to configure a deployment to use the Kubernetes secret and enable auto-reloading for Deployments. | ||
|
||
If you'd like to enable the auto-reload functionality, then just add a single annotation to your deployment. | ||
## Step 3. Configuring a Deployment | ||
|
||
To use the secret created by the Controller, we'll use the `envFrom` field to populate a container's environment variables using the secrets's Key-Value pairs: | ||
|
||
```yaml | ||
envFrom: | ||
- secretRef: | ||
name: mysecret # Matches the DopplerSecret name | ||
``` | ||
|
||
Adding automatic and instant reloading of a deployment requires just a single annotation on the Deployment: | ||
|
||
```yaml | ||
annotations: | ||
dopplersecrets.doppler.com/reload: 'true' | ||
``` | ||
|
||
To test using the example `DopplerSecret` from above, save the following to `doppler-deployment.yml`: | ||
Let's look at a complete example that uses previously created `DopplerSecret`. Save the below as `doppler-deployment.yml`: | ||
|
||
```yaml | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
metadata: | ||
name: doppler-secrets | ||
name: doppler-test-deployment | ||
annotations: | ||
dopplersecrets.doppler.com/reload: 'true' # Add for auto-reloads | ||
dopplersecrets.doppler.com/reload: 'true' | ||
spec: | ||
replicas: 1 | ||
replicas: 2 | ||
selector: | ||
matchLabels: | ||
app: doppler-secrets | ||
app: doppler-test | ||
template: | ||
metadata: | ||
labels: | ||
app: doppler-secrets | ||
app: doppler-test | ||
spec: | ||
containers: | ||
- name: doppler-secrets | ||
- name: doppler-test | ||
image: alpine | ||
command: ['/bin/sh', '-c', 'apk add --no-cache tini > /dev/null 2>&1 && printenv | grep -v KUBERNETES_ && tini -s tail -f /dev/null'] # Test by printing env var names | ||
envFrom: # Only envFrom is currently supported for auto-reloads | ||
command: ['/bin/sh', '-c', 'apk add --no-cache tini > /dev/null 2>&1 && printenv | grep -v KUBERNETES_ && tini -s tail -f /dev/null'] # Test by printing env var names | ||
imagePullPolicy: Always | ||
envFrom: | ||
- secretRef: | ||
name: app-secret # Should match DopplerSecret.spec.secretName | ||
name: doppler-test-secret # Should match DopplerSecret.spec.secretName | ||
resources: | ||
requests: | ||
memory: '250Mi' | ||
cpu: '250m' | ||
limits: | ||
memory: '500Mi' | ||
cpu: '500m' | ||
``` | ||
|
||
Create the deployment: | ||
|
||
```sh | ||
kubectl apply -f doppler-deployment.yml | ||
kubectl rollout status -w deployment/doppler-test-deployment | ||
``` | ||
|
||
Once the Deployment has completed, you can view the output of environment variables inside the example container by running: | ||
Once the Deployment has completed, you can view the logs of the test container, which lists the environment variables (minus those with the `KUBERNETES_` prefix): | ||
|
||
```sh | ||
kubectl logs -lapp=doppler-secrets | ||
kubectl logs -lapp=doppler-test | ||
``` | ||
|
||
# Debugging and Troubleshooting | ||
|
||
> NOTE: The `watch` binary is used by the below commands and can be installed on macOS using homebrew with `brew install watch`. | ||
|
||
This repo contains a couple of handy scripts that give greater visibility into the secret and deployment updating process. | ||
|
||
To watch a Doppler owned secret for changes: | ||
To watch a Doppler owned secret for updates: | ||
|
||
```sh | ||
# Replace `app-secrets` with the name of your Doppler created secret name | ||
watch ./bin/get-secret.sh app-secrets | ||
# Replace `doppler-test-secret` with your secret name | ||
./bin/get-secret.sh doppler-test-secret | ||
``` | ||
|
||
To watch the logs of a running Pod: | ||
|
||
```sh | ||
# Replace `app=doppler-secrets` with your deployment label selector | ||
watch ./bin/pod-logs.sh app=doppler-secrets | ||
``` | ||
|
||
## Cleaning up example resources | ||
|
||
To clean up the example resources, run: | ||
|
||
```sh | ||
kubectl delete deployments/doppler-secrets | ||
kubectl delete dopplersecrets.doppler.com/doppler-secret | ||
kubectl delete secrets/app-secret | ||
``` | ||
|
||
To remove the controller and associated resources, run: | ||
|
||
```sh | ||
kubectl delete -f doppler-crd-controller.yml | ||
# Replace `app=doppler-test` with your deployment label selector | ||
watch ./bin/pod-logs.sh app=doppler-test | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#! /usr/bin/env bash | ||
|
||
kubectl delete -f example/deployment.yml | ||
kubectl delete -f example/doppler-secret.yml | ||
kubectl delete secrets/doppler-test-secret | ||
doppler projects delete -y k8s-controller |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,40 @@ | ||
#!/usr/bin/env bash | ||
|
||
set -e | ||
|
||
# NOTE: The `envsubst` binary is required and can be installed in macOS by running `brew install gettext` | ||
|
||
doppler setup | ||
export DOPPLER_TOKEN=$(doppler configs tokens create koppler-k8s-controller-demo --plain) | ||
kubectl apply -f <(SERVICE_TOKEN="$DOPPLER_TOKEN" envsubst < example/dopplersecret.yml) | ||
echo -e '\n[info]: check controller has been deployed\n' | ||
kubectl apply -f doppler-crd-controller.yml | ||
kubectl rollout status -w deployment/doppler-controller --namespace doppler-controller | ||
sleep 3 | ||
|
||
echo -e '\n[info]: create example Doppler project\n' | ||
doppler projects create k8s-controller | ||
doppler setup --project k8s-controller --config dev | ||
doppler secrets set API_KEY=123 | ||
doppler secrets set AUTH_TOKEN=abc | ||
sleep 3 | ||
|
||
echo -e '\n[info]: generate Doppler service token\n' | ||
export DOPPLER_TOKEN=$(doppler configs tokens create doppler-k8s --plain) | ||
sleep 5 | ||
|
||
echo -e '\n[info]: create DopplerSecret from example/doppler-secret.yml\n' | ||
kubectl apply -f <(SERVICE_TOKEN="$DOPPLER_TOKEN" envsubst < example/doppler-secret.yml) | ||
sleep 2 | ||
|
||
echo -e '\n[info]: confirm associated Kubernetes secret created' | ||
sleep 4 | ||
./bin/get-secret.sh doppler-test-secret | ||
|
||
echo -e '\n[info]: create Deployment from example/deployment.yml\n' | ||
kubectl apply -f example/deployment.yml | ||
kubectl rollout status -w deployment/doppler-test-deployment | ||
sleep 3 | ||
|
||
echo -e '\n[info]: confirm container environment variables set from secret' | ||
./bin/pod-logs.sh app=doppler-test | ||
sleep 1 | ||
|
||
echo -e '\n[info]: done!\n' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
#!/usr/bin/env bash | ||
|
||
echo -e "\n### $1 ###\n" | ||
|
||
kubectl get secret $1 -o go-template='{{range $k,$v := .data}}{{$k}}={{$v|base64decode}}{{"\n"}}{{end}}' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
#!/usr/bin/env bash | ||
|
||
POD_NAME=$(kubectl get pods --field-selector=status.phase=Running -l $1 -o jsonpath={.items[0].metadata.name}) | ||
kubectl logs $POD_NAME | ||
echo -e "\n### $POD_NAME ###\n" | ||
kubectl logs $(kubectl get pods --field-selector=status.phase=Running -l $1 -o jsonpath={.items[0].metadata.name}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/usr/bin/env bash | ||
|
||
kubectl logs deployments/doppler-controller --namespace doppler-controller --follow --tail 20 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
apiVersion: 'doppler.com/v1' | ||
kind: DopplerSecret | ||
metadata: | ||
name: dopplersecret-test # DopplerSecret resource name | ||
spec: | ||
serviceToken: '$DOPPLER_TOKEN' # Change to your Doppler Service Token | ||
secretName: doppler-test-secret # Kubernetes Secret name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,31 @@ | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
metadata: | ||
name: doppler-secrets | ||
name: doppler-test-deployment | ||
annotations: | ||
dopplersecrets.doppler.com/reload: 'true' | ||
spec: | ||
replicas: 2 | ||
selector: | ||
matchLabels: | ||
app: doppler-secrets | ||
app: doppler-test | ||
template: | ||
metadata: | ||
labels: | ||
app: doppler-secrets | ||
app: doppler-test | ||
spec: | ||
containers: | ||
- name: doppler-secrets | ||
- name: doppler-test | ||
image: alpine | ||
command: ['/bin/sh', '-c', 'apk add --no-cache tini > /dev/null 2>&1 && printenv | grep -v KUBERNETES_ && tini -s tail -f /dev/null'] # Test by printing env var names | ||
imagePullPolicy: Always | ||
envFrom: | ||
- secretRef: | ||
name: app-secret # Should match DopplerSecret.spec.secretName | ||
name: doppler-test-secret # Should match DopplerSecret.spec.secretName | ||
resources: | ||
requests: | ||
memory: '250Mi' | ||
cpu: '250m' | ||
limits: | ||
memory: '500Mi' | ||
cpu: '500m' | ||
terminationGracePeriodSeconds: 0 # Testing purposes speed up the redepolyment process |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
apiVersion: doppler.com/v1 | ||
kind: DopplerSecret | ||
metadata: | ||
name: dopplersecret-test | ||
spec: | ||
serviceToken: $DOPPLER_TOKEN # Change to your Doppler Service Token | ||
secretName: doppler-test-secret # Kubernetes Secret name |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters