My k8s namespace contains a Secret
which is created at deployment time (by svcat
), so the values are not known in advance.
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: my-database-credentials
data:
hostname: ...
port: ...
database: ...
username: ...
password: ...
A Deployment
needs to inject these values in a slightly different format:
...
containers:
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: my-database-credentials
key: jdbc:postgresql:<hostname>:<port>/<database> // ??
- name: DATABASE_USERNAME
valueFrom:
secretKeyRef:
name: my-database-credentials
key: username
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: my-database-credentials
key: password
The DATABASE_URL
needs to be composed out of the hostname
, port
, 'database` from the previously defined secret.
Is there any way to do this composition?
To use a Secret in an environment variable in a Pod: Create a Secret (or use an existing one). Multiple Pods can reference the same Secret. Modify your Pod definition in each container that you wish to consume the value of a secret key to add an environment variable for each secret key you wish to consume.
When you create a Secret with kubectl create -f secret. yaml , Kubernetes stores it in etcd. The Secrets are stored in clear in etcd unless you define an encryption provider. When you define the provider, before the Secret is stored in etcd and after the values are submitted to the API, the Secrets are encrypted.
A secret can be used with a pod in three ways: To populate environment variables for containers. As files in a volume mounted on one or more of its containers. By kubelet when pulling images for the pod.
As mentioned, both env and envFrom can be used to share ConfigMap key/value pairs with a container as well. However, in the case of the mariadb-config ConfigMap, your entire file is stored as the value to your key, and the file needs to exist in the container's filesystem for MariaDB to be able to use it.
Kubernetes allows you to use previously defined environment variables as part of subsequent environment variables elsewhere in the configuration. From the Kubernetes API reference docs:
Variable references $(VAR_NAME) are expanded using the previous defined environment variables in the container and any service environment variables.
So, you can first extract the required secret values into environment variables, and then compose the DATABASE_URL
with those variables.
...
containers:
env:
- name: DB_URL_HOSTNAME // part 1
valueFrom:
secretKeyRef:
name: my-database-credentials
key: hostname
- name: DB_URL_PORT // part 2
valueFrom:
secretKeyRef:
name: my-database-credentials
key: port
- name: DB_URL_DBNAME // part 3
valueFrom:
secretKeyRef:
name: my-database-credentials
key: database
- name: DATABASE_URL // combine
value: jdbc:postgresql:$(DB_URL_HOSTNAME):$(DB_URL_PORT)/$(DB_URL_DBNAME)
...
Note the round brackets $(...)
used for variable expansion - it's the Kubernetes dependant variable notation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With