Post

Kubernetes Environment Variables and Secrets - The Basics Explained

Understand how Kubernetes environment variables and Secrets work together to securely manage configuration and sensitive data in your containers.

In Kubernetes, container environments (or container environment variables) refer to key-value pairs that we define and inject into containers running in Pods. These environment variables:

  • Are available inside the container just like any other Linux environment variable.
  • Can be used to configure the containerized application (e.g. database URLs, credentials, feature flags).
  • Can be hardcoded, passed from ConfigMaps/Secrets, or injected dynamically (e.g. Pod name, namespace).

Hardcoded Environment Variable

In a Pod definition (or Deployment), we can specify environment variables under the container[].env field:

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Pod
metadata:
    name: env-demo
spec:
    containers: 
        - name: myapp
          image: ngnix
          env:
            - name: MY_ENV_VAR
              value: "hello-k8"

Inside the container, the app can read MY_ENV_VAR=hello-k8.

Source From a ConfigMap

1
2
3
4
5
6
7
apiVersion: v1
kind: ConfigMap
metadata:
    name: app-config
data:
    APP_MODE: "production"
    LOG_LEVEL: debug

Use it in a Pod:

1
2
3
4
5
6
containers:
    - name: app
      image: myapp
      envFrom:
        - configMapRef:
            name: app-config

All key-value pairs in the ConfigMap become environment variables in the container.

Source From A Secret

1
2
3
4
5
6
7
apiVersion: v1
kind: Secret
metadata:
    name: app-secret
type: Opaque
data:
    DB_PASSWORD: c2VJcmv0gOGfzcw= # base64 of 'secretpass'

Inject into container:

1
2
3
4
5
6
7
8
9
containers:
    - name: app
      image: myapp
      env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
                name: app-secret
                value: DB_PASSWORD

Secrets are namespace scoped and needs to be created before usage or deployment of resources.

How To Apply Secrets

Kubernetes Secrets must be base64-encoded when written as YAML.

1
2
3
4
5
6
7
8
apiVersion: v1
kind: Secret
metadata:
    name: app-secret
type: Opaque
data:
    DB_USERNAME: YWRTaW4=           # 'admin'
    DB_PASSWORD: c2VJcmv0gOGfzcw=   # 'secretpass'

Apply it:

1
kubectl apply -f my-secret.yaml

We can create secrets from CLI without worrying about encoding:

1
2
3
kubectl create secret generic my-secret \
    --from-literal=DB_USERNAME=admin \
    --from-literal=DB_PASSWORD=secretpass

User secret values as environment variables in Pod:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: v1
kind: Pod
metadata:
    name: app-with-secrets
spec:
    containers:
        - name: app
          image: myapp
          env:
            - name: DB_PASSWORD
              valueFrom:
                    secretKeyRef:
                        name: my-secret
                        value: DB_PASSWORD
            - name: DB_USERNAME
              valueFrom: 
                    secretKeyRef:
                        name: my-secret
                        key: DB_USERNAME

Applying Secrets To Specific Namespace

To apply Kubernetes Secrets to a specific namespace, we must ensure the Secret is created in that namespace because Secrets are namespace-scoped.

1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: Secret
metadata:
    name: app-secret
    namespace: my-namespace
type: Opaque
data:
    DB_PASSWORD: c2VJcmv0gOGfzcw= # base64 of 'secretpass'

Then apply it with:

1
kubectl apply -f my-secret.yaml

Another way is to create a Secret via kubectl in a specific namespace:

1
2
3
kubectl create secret generic my-secret \
--from-literal=DB_PASSWORD=secretpass \
--namespace=my-namespace

To verify if it’s in the right namespace:

1
kubectl get secret -n my-namespace

Applying Secrets To Specific Namespace In The Azure Portal

  • Connect kubectl to the AKS cluster (Azure Cloud Shell)
    1
    
    az aks get-credentials --resource-group myresgroup --name myaksclustername
    

Make sure your YAML file includes the correct namespace:

1
2
3
metadata:
    name: my-secret
    namespace: default # or your target namespace

If secrets.yaml file is on your local machine, but we are working inside Azure Cloud Shell, we must first upload it.

  • Open Azure Cloud Shell in the Portal
  • Click the Upload/Download button
  • Click Upload and select the secrets file
  • Then run kubctl apply -f secrets.yaml
This post is licensed under CC BY 4.0 by the author.