Binding secrets to Knative services

This is the sixth in a collection of articles as I explore serverless software development atop Kubernetes with Google/Pivotal Knative. The full set of articles are:

In the previous articles we’ve deployed a sample application with explicit environment variables as configuration.

knctl deploy \  --service simple-app \
  --image index.docker.io/drnic/knative-simple-app \
  --env SIMPLE_MSG="App container configured with this env var"

Yet Kubernetes has two first class resources for configuration: Secrets, and ConfigMaps. In this article we will look at how we can bind Secrets and ConfigMaps into our Knative services with --env-secret and --env-config-map flags.

This article uses improvements introduced in knctl v0.0.10 by Dmitriy & Dr Max.


Explicit Environment Variables

In the very first Knative blog post Deploying 12-factor apps to Knative we deployed a pre-existing Docker image, with an explicit environment variable to configure the application. For example:

knctl deploy \
  --service simple-app \
  --image index.docker.io/drnic/knative-simple-app \
  --env SIMPLE_MSG="App container configured with this env var"

The knctl deploy command also allows us to construct environment variables for our service using Kubernetes Secrets and ConfigMaps.

Secrets

To experiment, let’s create a Kubernetes secret simple-app-message with a key message.

kubectl create secret generic simple-app-message \
  --from-literal=message="This message came from a Kube Secret"

In our previous articles we explicitly provided --env SIMPLE_MSG="some string" which set the $SIMPLE_MSG environment variable to an explicit value.

This time we want the environment variable to take on the value from the secret simple-app-message/message – the simple-app-message secret’s message key.

We replace --env flag with --env-secret and knctl will construct the appropriate Knative Serving manifest and deploy our service.

knctl deploy \
  --service simple-app \
  --image index.docker.io/drnic/knative-simple-app \
  --env-secret SIMPLE_MSG=simple-app-message/message

Our deployed revision includes the secret baked into it as an environment variable.

$ knctl curl --service simple-app
Running: curl '-sS' '-H' 'Host: simple-app.default.knative.starkandwayne.com' 'http://35.197.73.136:80'
<h1>This message came from a Kube Secret</h1>
Succeeded

ConfigMap

Similarly you can pull in ConfigMap values with --env-config-map instead of --env-secret above.

To create an example configmap:

kubectl create configmap simple-app-configmap \
  --from-literal=message="This message came from a Kube ConfigMap"

Now deploy again with --env-config-map:

knctl deploy \
  --service simple-app \
  --image index.docker.io/drnic/knative-simple-app \
  --env-config-map SIMPLE_MSG=simple-app-configmap/message

Our newly deployed revision includes the configmap baked into it as an environment variable.

$ knctl curl --service simple-app
Running: curl '-sS' '-H' 'Host: simple-app.default.knative.starkandwayne.com' 'http://35.197.73.136:80'
<h1>This message came from a Kube ConfigMap</h1>
Succeeded

Summary

Knative Serving subsystem, and the knctl deploy CLI experience, support the ability for you to bind Kubernetes first-class Secrets and ConfigMap resources into your services.

Meanwhile…

I’ve recently been researching Service Catalog. This allows a Kubernetes user to provision external services — say a database managed by the cloud provider — and bind to them — say to generate a new user and store their credentials in Kubernetes Secrets. With knctl deploy --env-secret we will now be able to combine Knative with Service Catalog. And thus, combine Knative with any externally managed service that offers an Open Service Broker API.

Stay tuned for an explanation of the following commands – provision a free external MySQL database, generate a user and credentials and store it in a secret called db, and deploy your application with $DATABASE_URL pointing to the remote database:

svcat provision db --class cleardb --plan spark
svcat bind db
knctl deploy --env-secret DATABASE_URL=db/uri ...

Spread the word

twitter icon facebook icon linkedin icon