Edit This Page

Distribute Credentials Securely Using Secrets

This page shows how to securely inject sensitive data, such as passwords and encryption keys, into Pods.

Before you begin

You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using Minikube, or you can use one of these Kubernetes playgrounds:

Convert your secret data to a base-64 representation

Suppose you want to have two pieces of secret data: a username my-app and a password 39528$vdg7Jb. First, use a base64 encoding tool to convert your username and password to a base64 representation. Here's an example using the commonly available base64 program:

echo -n 'my-app' | base64
echo -n '39528$vdg7Jb' | base64

The output shows that the base-64 representation of your username is bXktYXBw, and the base-64 representation of your password is Mzk1MjgkdmRnN0pi.

Caution: Use a local tool trusted by your OS to decrease the security risks of external tools.

Create a Secret

Here is a configuration file you can use to create a Secret that holds your username and password:

pods/inject/secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: test-secret
data:
  username: bXktYXBw
  password: Mzk1MjgkdmRnN0pi
  1. Create the Secret

    kubectl apply -f https://k8s.io/examples/pods/inject/secret.yaml
    
  2. View information about the Secret:

    kubectl get secret test-secret
    

    Output:

    NAME          TYPE      DATA      AGE
    test-secret   Opaque    2         1m
    
  3. View more detailed information about the Secret:

    kubectl describe secret test-secret
    

    Output:

    Name:       test-secret
    Namespace:  default
    Labels:     <none>
    Annotations:    <none>
    
    Type:   Opaque
    
    Data
    ====
    password:   13 bytes
    username:   7 bytes
    

Create a Secret directly with kubectl

If you want to skip the Base64 encoding step, you can create the same Secret using the kubectl create secret command. For example:

kubectl create secret generic test-secret --from-literal='username=my-app' --from-literal='password=39528$vdg7Jb'

This is more convenient. The detailed approach shown earlier runs through each step explicitly to demonstrate what is happening.

Create a Pod that has access to the secret data through a Volume

Here is a configuration file you can use to create a Pod:

pods/inject/secret-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: secret-test-pod
spec:
  containers:
    - name: test-container
      image: nginx
      volumeMounts:
        # name must match the volume name below
        - name: secret-volume
          mountPath: /etc/secret-volume
  # The secret data is exposed to Containers in the Pod through a Volume.
  volumes:
    - name: secret-volume
      secret:
        secretName: test-secret
  1. Create the Pod:

    kubectl apply -f https://k8s.io/examples/pods/inject/secret-pod.yaml
    
  2. Verify that your Pod is running:

    kubectl get pod secret-test-pod
    

    Output:

    NAME              READY     STATUS    RESTARTS   AGE
    secret-test-pod   1/1       Running   0          42m
    
  3. Get a shell into the Container that is running in your Pod:

    kubectl exec -i -t secret-test-pod -- /bin/bash
    
  4. The secret data is exposed to the Container through a Volume mounted under /etc/secret-volume.

    In your shell, list the files in the /etc/secret-volume directory:

    # Run this in the shell inside the container
    ls /etc/secret-volume
    

    The output shows two files, one for each piece of secret data:

    password username
    
  5. In your shell, display the contents of the username and password files:

    # Run this in the shell inside the container
    echo "$( cat /etc/secret-volume/username )"
    echo "$( cat /etc/secret-volume/password )"
    

    The output is your username and password:

    my-app
    39528$vdg7Jb
    

Define container environment variables using Secret data

Define a container environment variable with data from a single Secret

  • Define an environment variable as a key-value pair in a Secret:

    kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
    
  • Assign the backend-username value defined in the Secret to the SECRET_USERNAME environment variable in the Pod specification.

    pods/inject/pod-single-secret-env-variable.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: env-single-secret
    spec:
      containers:
      - name: envars-test-container
        image: nginx
        env:
        - name: SECRET_USERNAME
          valueFrom:
            secretKeyRef:
              name: backend-user
              key: backend-username
    
  • Create the Pod:

    kubectl create -f https://k8s.io/examples/pods/inject/pod-single-secret-env-variable.yaml
    
  • In your shell, display the content of SECRET_USERNAME container environment variable

    kubectl exec -i -t env-single-secret -- /bin/sh -c 'echo $SECRET_USERNAME'
    

    The output is

    backend-admin
    

Define container environment variables with data from multiple Secrets

  • As with the previous example, create the Secrets first.

    kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
    kubectl create secret generic db-user --from-literal=db-username='db-admin'
    
  • Define the environment variables in the Pod specification.

    pods/inject/pod-multiple-secret-env-variable.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: envvars-multiple-secrets
    spec:
      containers:
      - name: envars-test-container
        image: nginx
        env:
        - name: BACKEND_USERNAME
          valueFrom:
            secretKeyRef:
              name: backend-user
              key: backend-username
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: db-user
              key: db-username
    
  • Create the Pod:

    kubectl create -f https://k8s.io/examples/pods/inject/pod-multiple-secret-env-variable.yaml
    
  • In your shell, display the container environment variables

    kubectl exec -i -t envvars-multiple-secrets -- /bin/sh -c 'env | grep _USERNAME'
    

    The output is

    DB_USERNAME=db-admin
    BACKEND_USERNAME=backend-admin
    

Configure all key-value pairs in a Secret as container environment variables

Note: This functionality is available in Kubernetes v1.6 and later.
  • Create a Secret containing multiple key-value pairs

    kubectl create secret generic test-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb'
    
  • Use envFrom to define all of the Secret’s data as container environment variables. The key from the Secret becomes the environment variable name in the Pod.

    pods/inject/pod-secret-envFrom.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: envfrom-secret
    spec:
      containers:
      - name: envars-test-container
        image: nginx
        envFrom:
        - secretRef:
            name: test-secret
    
  • Create the Pod:

    kubectl create -f https://k8s.io/examples/pods/inject/pod-secret-envFrom.yaml
    
  • In your shell, display username and password container environment variables

    kubectl exec -i -t envfrom-secret -- /bin/sh -c 'echo "username: $username\npassword: $password\n"'
    

    The output is

    username: my-app
    password: 39528$vdg7Jb
    

References

What's next