Distribute Credentials Securely Using Secrets

    You need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. It is recommended to run this tutorial on a cluster with at least two nodes that are not acting as control plane hosts. If you do not already have a cluster, you can create one by using minikube or you can use one of these Kubernetes playgrounds:

    Suppose you want to have two pieces of secret data: a username 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:

    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

    1. apiVersion: v1
    2. kind: Secret
    3. metadata:
    4. name: test-secret
    5. data:
    6. username: bXktYXBw
    7. password: Mzk1MjgkdmRnN0pi
    1. Create the Secret

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

      1. kubectl get secret test-secret

      Output:

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

      1. kubectl describe secret test-secret

      Output:

      1. Name: test-secret
      2. Namespace: default
      3. Labels: <none>
      4. Annotations: <none>
      5. Type: Opaque
      6. Data
      7. ====
      8. password: 13 bytes
      9. username: 7 bytes

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

    1. 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.

    Distribute Credentials Securely Using Secrets - 图2

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: secret-test-pod
    5. spec:
    6. containers:
    7. - name: test-container
    8. image: nginx
    9. # name must match the volume name below
    10. - name: secret-volume
    11. mountPath: /etc/secret-volume
    12. volumes:
    13. - name: secret-volume
    14. secret:
    15. secretName: test-secret
    1. Create the Pod:

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

      Output:

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

      1. 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:

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

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

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

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

      The output is your username and password:

      1. my-app
      2. 39528$vdg7Jb

    Define container environment variables using Secret data

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

      1. 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.

      1. apiVersion: v1
      2. kind: Pod
      3. metadata:
      4. name: env-single-secret
      5. spec:
      6. containers:
      7. - name: envars-test-container
      8. image: nginx
      9. env:
      10. - name: SECRET_USERNAME
      11. valueFrom:
      12. secretKeyRef:
      13. name: backend-user
      14. key: backend-username
      1. 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

      The output is

      1. backend-admin
    • As with the previous example, create the Secrets first.

    • Define the environment variables in the Pod specification.

      pods/inject/pod-multiple-secret-env-variable.yaml Distribute Credentials Securely Using Secrets - 图4

      1. apiVersion: v1
      2. kind: Pod
      3. metadata:
      4. name: envvars-multiple-secrets
      5. spec:
      6. containers:
      7. - name: envars-test-container
      8. image: nginx
      9. env:
      10. - name: BACKEND_USERNAME
      11. valueFrom:
      12. secretKeyRef:
      13. name: backend-user
      14. key: backend-username
      15. - name: DB_USERNAME
      16. valueFrom:
      17. secretKeyRef:
      18. name: db-user
      19. key: db-username
    • Create the Pod:

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

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

      The output is

      1. DB_USERNAME=db-admin
      2. BACKEND_USERNAME=backend-admin

    Note: This functionality is available in Kubernetes v1.6 and later.

    • Create a Secret containing multiple key-value pairs

      1. 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.

      1. apiVersion: v1
      2. kind: Pod
      3. metadata:
      4. name: envfrom-secret
      5. spec:
      6. containers:
      7. - name: envars-test-container
      8. image: nginx
      9. envFrom:
      10. - secretRef:
      11. name: test-secret
    • Create the Pod:

      1. kubectl create -f https://k8s.io/examples/pods/inject/pod-secret-envFrom.yaml
    • The output is

      1. username: my-app

    What’s next