To consume Berglas secrets from Kubernetes, you can deploy a
MutatingWebhookConfiguration
. This mutation will inspect all pods admitted
into the cluster and adjust their manifest to pull secrets from Berglas.
The webhook must be deployed and accessible by the Kubernetes API server. You can deploy the webhook via knative, Cloud Run, Cloud Functions, Heroku, Cloud Foundry, etc, so long as it offers a TLS endpoint accessible by the Kubernetes API server.
One of the easiest ways to deploy the mutation webhook is using Cloud Functions. To deploy on Cloud Functions:
-
Enable the Cloud Functions API (this only needs to be done once per project):
gcloud services enable --project ${PROJECT_ID} \ cloudfunctions.googleapis.com
-
Set environment variables (replace with your values):
export PROJECT_ID=my-project
-
Ensure you are in the
kubernetes/
directory -
Deploy the mutation webhook:
gcloud functions deploy berglas-secrets-webhook \ --project ${PROJECT_ID} \ --runtime go111 \ --entry-point F \ --trigger-http
-
Extract the Cloud Function URL:
ENDPOINT=$(gcloud functions describe berglas-secrets-webhook --project ${PROJECT_ID} --format 'value(httpsTrigger.url)')
-
Register the webhook with this URL:
sed "s|REPLACE_WITH_YOUR_URL|$ENDPOINT|" deploy/webhook.yaml | kubectl apply -f -
-
(Optional) Verify the webhook is running:
kubectl get mutatingwebhookconfiguration NAME berglas-secrets-webhook
Either the pods or the Kubernetes cluster needs to be able to authenticate to Google Cloud using IAM with Default Application Credentials. See the authentication section of the main README for more details.
On Google Cloud, it is strongly recommended that you have a dedicated service account for the GKE cluster. For example:
-
Export your configuration variables:
PROJECT_ID=berglas-test BUCKET_ID=berglas-test-secrets KMS_KEY=projects/${PROJECT_ID}/locations/global/keyRings/berglas/cryptoKeys/berglas-key
-
Create a service account:
gcloud iam service-accounts create berglas-k8s \ --project ${PROJECT_ID} \ --display-name "Berglas K8S account"
export SA_EMAIL=berglas-k8s@${PROJECT_ID}.iam.gserviceaccount.com
-
Grant the service account the required GKE permissions:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member "serviceAccount:${SA_EMAIL}" \ --role roles/logging.logWriter
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member "serviceAccount:${SA_EMAIL}" \ --role roles/monitoring.metricWriter
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member "serviceAccount:${SA_EMAIL}" \ --role roles/monitoring.viewer
-
Grant Berglas permissions:
gsutil iam ch serviceAccount:${SA_EMAIL}:legacyObjectReader gs://${BUCKET_ID}/api-key
gsutil iam ch serviceAccount:${SA_EMAIL}:legacyObjectReader gs://${BUCKET_ID}/tls-key
gcloud kms keys add-iam-policy-binding ${KMS_KEY} \ --member serviceAccount:${SA_EMAIL} \ --role roles/cloudkms.cryptoKeyDecrypter
-
Create the GKE cluster with the attached service account:
gcloud container clusters create berglas-k8s-test \ --project ${PROJECT_ID} \ --region us-east1 \ --num-nodes 1 \ --machine-type n1-standard-2 \ --service-account ${SA_EMAIL} \ --no-issue-client-certificate \ --no-enable-basic-auth \ --enable-autoupgrade \ --metadata disable-legacy-endpoints=true
After deploying the webhook, test your configuration by deploying a sample application.
-
Update
deploy/sample.yaml
to refer to your secret: -
Deploy it:
kubectl apply -f deploy/sample.yaml
The mutator requires that containers specify a command
in their manifest. If a
container requests Berglas secrets and does not specify a command
, the mutator
will log an error and not mutate the spec.