Skip to content

Secrets

Objects of type secret are intended to hold sensitive information, such as passwords, OAuth tokens, and ssh keys. Putting this information in a secret is safer and more flexible than putting it verbatim in a pod definition or in a docker image. Secrets decouple sensitive content from the pods. You can mount secrets into containers using a volume plug-in or the system can use secrets to perform actions on behalf of a pod.

Creating a secret from files

Create secret from a secret file

# Create files needed for rest of example.
$ echo -n 'admin' > ./username.txt
$ echo -n '1f2d1e2e67df' > ./password.txt

$ kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
secret "db-user-pass" created

$ kubectl get secrets
NAME                  TYPE                                  DATA      AGE
db-user-pass          Opaque                                2         51s

$ kubectl describe secrets/db-user-pass
Name:            db-user-pass
Namespace:       default
Labels:          <none>
Annotations:     <none>

Type:            Opaque

Data
====
password.txt:    12 bytes
username.txt:    5 bytes

Note

1
Neither **get** nor **describe** shows the contents of the file by default. This is to protect the secret from being exposed accidentally to someone looking or from being stored in a terminal log.

Creating Secret manually from yaml file

You can also create a Secret in a file first, in json or yaml format, and then create that object. The Secret contains two maps: data and stringData

  • The data field is used to store arbitrary data, encoded using base64
  • The stringData field is provided for convenience, and allows you to provide secret data as unencoded strings.

To store two strings in a Secret using the data field, convert them to base64 as follows

echo -n 'admin' | base64
YWRtaW4=
echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm
Write a Secret that looks like this:
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm
Now create the Secret
$ kubectl create -f ./secret.yaml
secret "mysecret" created

To store a secret using string data filed:

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
stringData:
  config.yaml: |-
    apiUrl: "https://my.api.com/api/v1"
    username: {{username}}
    password: {{password}}

Using Secrets

Secrets can be mounted as data volumes or be exposed as environment variables to be used by a container in a pod.

They can also be used by other parts of the system, without being directly exposed to the pod. For example, they can hold credentials that other parts of the system should use to interact with external systems on your behalf.

This is an example of a pod that mounts a secret in a volume:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret

We can also control the paths within the volume where Secret keys are projected. You can use .spec.volumes[].secret.items field to change target path of each key:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      items:
      - key: username
        path: my-group/my-username
What will happen:

username secret is stored under /etc/foo/my-group/my-username file instead of /etc/foo/username.
password secret is not projected

Consuming Secret Values from Volumes

Inside the container that mounts a secret volume, the secret keys appear as files and the secret values are base-64 decoded and stored inside these files. This is the result of commands executed inside the container from the example above:

$ ls /etc/foo/
username
password
$ cat /etc/foo/username
admin
$ cat /etc/foo/password
1f2d1e2e67df

Using Secrets as Environment Variables

To use a secret in an environment variable in a pod:

This is an example of a pod that uses secrets from environment variables:

apiVersion: v1
kind: Pod
metadata:
  name: secret-env-pod
spec:
  containers:
  - name: mycontainer
    image: redis
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: username
      - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: password
  restartPolicy: Never

Consuming Secret Values from Environment Variables

Inside a container that consumes a secret in an environment variables, the secret keys appear as normal environment variables containing the base-64 decoded values of the secret data. This is the result of commands executed inside the container from the example above:

$ echo $SECRET_USERNAME
admin
$ echo $SECRET_PASSWORD
1f2d1e2e67df

Updating Secrets

Whenever you update a secret, Kubernetes will automatically update the values across all the resources that use it — this is one of the other great things about using Kubernetes secrets.

You can use kubectl apply -f updated_secret.yaml like for any other Kubernetes object

Image pull secrets

To create a docker registry secret called myregistrykey:

kubectl create secret docker-registry myregistrykey \
    --docker-server=DOCKER_REGISTRY_SERVER \
    --docker-username=DOCKER_USER \
    --docker-password=DOCKER_PASSWORD \
    --docker-email=DOCKER_EMAIL
secret/myregistrykey created.

To add image secret and update the service account to use it:

kubectl create secret docker-registry image-pull-secret  -n istio-system \
  --docker-server=https://index.docker.io/v1/  \
  --docker-username=phcix \
  --docker-password='YOURPASSWORD'

kubectl patch serviceaccount default \
   -p "{\"imagePullSecrets\": [{\"name\": \"image-pull-secret\"}]}" \
   -n istio-system

To create a imagepull secret called gcr-json-key in python-app namespace using the auth information stored in /root/gce.json file.

kubectl create secret docker-registry  --namespace=python-app gcr-json-key \
          --docker-server=https://gcr.io \
          --docker-username=_json_key \
          --docker-password="$(cat /root/gce.json)" \  
          --docker-email="sa-rsc-gis-k8s-rancheradmin-sb@k8s-sb-001-584254b.iam.gserviceaccount.com"

If for some reason you need multiple items in a single .docker/config.json, then you can create a secret using json or yaml.

Be sure to:

  • set the name of the data item to .dockerconfigjson
  • base64 encode the docker file and paste that string, unbroken as the value for field data[".dockerconfigjson"]
  • set type to kubernetes.io/dockerconfigjson

Example:

apiVersion: v1
kind: Secret
metadata:
  name: myregistrykey
  namespace: awesomeapps
data:
  .dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg==
type: kubernetes.io/dockerconfigjson

Referring to an imagePullSecrets on a Pod

Now, you can create pods which reference that secret by adding an imagePullSecrets section to a pod definition.

apiVersion: v1
kind: Pod
metadata:
  name: foo
  namespace: awesomeapps
spec:
  containers:
    - name: foo
      image: janedoe/awesomeapp:v1
  imagePullSecrets:
    - name: myregistrykey