• Home
  • LLMs
  • Python
  • Docker
  • Kubernetes
  • Java
  • Maven
  • All
  • About
Kubernetes | Kubernetes Secrets (secrets)
  1. Notes
  2. Kubernetes Secrets (secrets)
  3. Creating Secrets using kubectl
    --from-literal
    --from-file: from file without a key, from file with a key, from a directory
    --from-env-file
  4. Creating Secrets using manifest YAML file
  5. Edit Secrets
  6. Using Secrets: Environment variables
    env/valueFrom/secretKeyRef
    envFrom/secretRef
  7. Using Secrets: Files in Volumes
  8. Referencing Secrets's environment variables in the container's command
  9. Delete Secrets

  1. Notes
    See these pages for more details about Secrets:
    https://kubernetes.io/docs/concepts/configuration/secret/
    https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/
    https://kubernetes.io/docs/tasks/configmap-secret/managing-secret-using-kubectl/
  2. Kubernetes Secrets (secrets)
    Secrets allows creating data objects that can be consumed by Pods at runtime.

    Here's an example of a Secret (YAML):
    apiVersion: v1
    data:
      key1: dmFsdWUx
      key2: dmFsdWUy
    kind: Secret
    metadata:
      name: secretexample
    type: Opaque
    The manifest file of the Secret is pretty simple. It contains the fields apiVersion, kind, and metadata. It also contain the data field that contains the keys-values of the Secret.

    The data in Secrets is stored as key-value entries:
    • Key: is a string value formed by alphanumeric, dot (.), dash (-), and underscore (_) characters.

    • Value: is a base64-encoded string value.

    The key and the value, in the Secrets, are separated with a colon (key:value).

    The name of the Secrets must be a valid DNS subdomain name.

    The data stored in a Secrets can be consumed in a container in one the following ways:
    • Environment variables.

    • Command-line arguments of the container command.

    • Files in volumes.

    • Custom code (read the Secrets directly from the Kubernetes API).

    To encode a text into a base64 string:
    $ echo -n 'value1' | base64
    dmFsdWUx
    The -n flag ensures that the generated output doesn't have an extra newline character at the end of the text. This is to avoid that the extra newline character gets encoded along with the text.

    To decode a base64 data:
    $ echo 'dmFsdWUx' | base64 --decode
    value1
    Note: If you update a Secret that was already posted to the Kubernetes API server, then Pods that were already created will be able to leverage the new data only if it was injected as files in a volume. Secrets data injected as environment variables won't be updated in a running Pod unless you recreate it.
  3. Creating Secrets using kubectl
    The data of the Secrets can be specified using one of the following methods:

    • generic --from-literal:
      This command allows you to specify a key and literal value to insert in the Secret.

      You need to escape the special characters $, \, *, =, and ! (otherwise they will be interpreted by the shell).

      One way to escape the special characters is to enclose the value within single quotes (').

      Create the Secrets:
      $ kubectl create secret generic secretfromliteral --from-literal="key1=value1" --from-literal=key2='value2'
      secret/secretfromliteral created
      Check the Secret:
      $ kubectl get secret secretfromliteral
      NAME                TYPE     DATA   AGE
      secretfromliteral   Opaque   2      9m5s
      Describe the Secret:
      $ kubectl describe secret secretfromliteral
      Name:         secretfromliteral
      Labels:       <none>
      Annotations:  <none>
      
      Type:  Opaque
      
      Data
      ====
      key1:  6 bytes
      key2:  6 bytes
      View the YAML file of the Secret:
      $ kubectl get secrets secretfromliteral -o yaml
      apiVersion: v1
      data:
        key1: dmFsdWUx
        key2: dmFsdWUy
      kind: Secret
      metadata:
        name: secretfromliteral
      type: Opaque
      To decode the Secret of a specific key, you need to decode its base64 data:
      $ kubectl get secrets secretfromliteral -o jsonpath='{.data.key1}' | base64 --decode -
      value1
      $ kubectl get secrets secretfromliteral -o jsonpath='{.data.key2}' | base64 --decode -
      value2

    • generic --from-file:
      This command allows you to specify a file path (--from-file="./secrets/file1.txt"), in which case the file base name will be used as the Secret key.

      Optionally you can use a key with the file path (--from-file="mykey1=./secrets/file1.txt"), in which case the given key will be used as the Secret key.

      If you specify a directory (--from-file="./secrets/") then kubectl will iterate each file in the directory and create a new entry for each file whose base name is a valid Secret key.

      The path to the file (or directory) can be an absolute path or relative to the location from where the "kubectl create secret" is executed.

      The content of the file can be anything. You don't have to escape special characters in the text that you put in the file.

      Let's crate a directory to hold the Secrets data (this can be any location you want):
      $ mkdir ./secrets/
      Create a sample file "file1.txt" (single line text):
      $ echo -n 'value1' > "./secrets/file1.txt"
      Create a sample file "file2.txt" (multiple lines text):
      $ echo 'value2-1' > "./secrets/file2.txt"
      $ echo 'value2-2' >> "./secrets/file2.txt"
      • Create the Secret from a file without a key:
        $ kubectl create secret generic secret1fromfile --from-file="./secrets/file1.txt" --from-file="./secrets/file2.txt"
        secret/secret1fromfile created
        View the Secrets (notice that the content of the file is indented properly):
        $ kubectl get secret secret1fromfile -o yaml
        apiVersion: v1
        data:
          file1.txt: dmFsdWUx # note that the name of the key is file1.txt
          file2.txt: dmFsdWUyLTEKdmFsdWUyLTIK # note that the name of the key is file2.txt
        kind: Secret
        metadata:
          name: secret1fromfile
        type: Opaque
      • Create the Secret from a file with a key:
        $ kubectl create secret generic secret2fromfile --from-file="mykey1=./secrets/file1.txt" --from-file="mykey2=./secrets/file2.txt"
        secret/secret2fromfile created
        View the Secrets (notice that the content of the file is indented properly):
        $ kubectl get secret secret2fromfile -o yaml
        apiVersion: v1
        data:
          mykey1: dmFsdWUx # note that the name of the key is mykey1
          mykey2: dmFsdWUyLTEKdmFsdWUyLTIK # note that the name of the key is mykey2
        kind: Secret
        metadata:
          name: secret2fromfile
        type: Opaque
      • Create the Secret from a directory:
        $ kubectl create secret generic secretfromdirectory --from-file="./secrets/"
        secret/secretfromdirectory created
        View the Secrets (notice that the content of the file is indented properly):
        $ kubectl get secret secretfromdirectory -o yaml
        apiVersion: v1
        data:
          file1.txt: dmFsdWUx # note that the name of the key is file1.txt
          file2.txt: dmFsdWUyLTEKdmFsdWUyLTIK # note that the name of the key is file2.txt
        kind: Secret
        metadata:
          name: secretfromdirectory
        type: Opaque

    • --from-env-file:
      This command allows you to specify the path to an environement (properties) file (--from-file="./secrets/file1.properties") to read lines of key=value pairs to insert in the Secret.

      Create a sample property file:
      $ vi "./secrets/file1.properties"
      key1=value1
      key2=value2
      Create the Secret:
      $ kubectl create secret generic secretfromenvfile --from-env-file="./secrets/file1.properties"
      secret/secretfromenvfile created
      View the Secret (notice that each entry in the property file is represented by a key:value pairs in the Secret):
      $ kubectl get secret secretfromenvfile -o yaml
      apiVersion: v1
      data:
        key1: dmFsdWUx
        key2: dmFsdWUy
      kind: Secret
      metadata:
        name: secretfromenvfile
      type: Opaque
  4. Creating Secrets using manifest YAML file
    The manifest YAML file defines Secrets with key:value entries.

    The values must be base64 encoded strings.

    $ vi secretkeyvalue.yaml
    apiVersion: v1
    kind: Secret
    metadata:
      name: secretkeyvalue
    data:
      key1: dmFsdWUx
      key2: dmFsdWUy
    To apply the file:
    $ kubectl apply -f secretkeyvalue.yaml
    secret/secretkeyvalue created
  5. Edit Secrets
    If you have created a Secret using the manifest YAML file, then to change that Secret you can adjust the YAML file and run the command kubectl apply -f SECRET-YAML-FILE-PATH

    You can also use the command kubectl edit secret SECRET-NAME to edit a Secret. The command will open the Secret in your default text editor. Make your changes then save and exit the editor. Your changes will be submitted to API Server.

    For example to view and edit the Secret "secretkeyvalue":
    $ kubectl edit secret secretkeyvalue
    # Please edit the object below.
    # Lines beginning with a '#' will be ignored, and an empty file will abort the edit.
    # If an error occurs while saving this file will be reopened with the relevant failures.
    #
    apiVersion: v1
    data:
      key1: dmFsdWUx
      key2: dmFsdWUy
    kind: Secret
    metadata:
      annotations:
        kubectl.kubernetes.io/last-applied-configuration: |
          {"apiVersion":"v1","data":{"key1":"dmFsdWUx","key2":"dmFsdWUy"},"kind":"Secret","metadata":{"annotations":{},"name":"secretkeyvalue"}}
      name: secretkeyvalue
    type: Opaque
    secret/secretkeyvalue edited
  6. Using Secrets: Environment variables
    In a Pod YAML file, You can reference the entries of the Secrets directly in the "spec.containers.env" field. The environment variables will be set like any other standard Linux environment variables. You can check them using the env command directly from inside the container.

    • env/valueFrom/secretKeyRef

      Let's use the Secret "secretkeyvalue" (see above) with the Pod "hello-busybox-secret-keyref":
      $ vi hello-busybox-secret-keyref.yaml
      apiVersion: v1
      kind: Pod
      metadata:
        name: hello-busybox-secret-keyref
      spec:
        containers:
          - name: hello-busybox-secret-keyref
            image: busybox:latest
            tty: true # (TeleTYpewriter) allocates a TTY / terminal console on the container
            stdin: true # Keeps stdin open on the container
            env:
              - name: mykey1
                valueFrom:
                  secretKeyRef:
                    name: secretkeyvalue
                    key: key1
              - name: mykey2
                valueFrom:
                  secretKeyRef:
                    name: secretkeyvalue
                    key: key2
      Note: You can give the environment variable a different name than the Secrets key name (i.e. name: mykey1).

      Apply the Pod:
      $ kubectl apply -f hello-busybox-secret-keyref.yaml
      pod/hello-busybox-secret-keyref created
      Check the environment variables:
      $ kubectl exec hello-busybox-secret-keyref -- env | grep key
      mykey1=value1
      mykey2=value2
      Note that the secrets are clear text!

    • envFrom/secretRef

      Instead of referencing individual entries of the Secret, you can use the "spec.containers.envFrom" field to reference all entries of the Secret:
      $ vi hello-busybox-secret-ref.yaml
      apiVersion: v1
      kind: Pod
      metadata:
        name: hello-busybox-secret-ref
      spec:
        containers:
          - name: hello-busybox-secret-ref
            image: busybox:latest
            tty: true
            stdin: true
            envFrom:
              - secretRef:
                  name: secretkeyvalue
      Apply the Pod:
      $ kubectl apply -f hello-busybox-secret-ref.yaml
      pod/hello-busybox-secret-ref created
      Check the environment variables:
      $ kubectl exec hello-busybox-secret-ref -- env | grep key
      key1=value1
      key2=value2
  7. Using Secrets: Files in Volumes
    Secrets can also be referenced using volumes.

    Each entry of the Secrets will be referenced as a separate file in the volume.

    The changes to the Secrets will be reflect directly in the volumes.

    The Secrets is defined as a volume (spec.volumes) and mounted to the container (spec.containers.volumeMounts).

    • In the following example, the "spec.volumes" field creates a volume (named secretkeyvalue) from the "secretkeyvalue" Secrets.
      The "spec.containers.volumeMounts" field mounts the volume (secretkeyvalue) into the container (under /tmp/secretkeyvalue).
      The volume will be populated with files where the file name is the key of the Secrets (key1, key2) and the content of the file is the value of the key (value1, value2).

      $ vi hello-busybox-secret-volume.yaml
      apiVersion: v1
      kind: Pod
      metadata:
        name: hello-busybox-secret-volume
      spec:
        containers:
          - name: hello-busybox-secret-volume
            image: busybox:latest
            tty: true
            stdin: true
            volumeMounts:
              - name: secretkeyvalue
                mountPath: /tmp/secretkeyvalue
        volumes:
          - name: secretkeyvalue
            secret:
              secretName: secretkeyvalue
      Apply the Pod:
      $ kubectl apply -f hello-busybox-secret-volume.yaml
      pod/hello-busybox-secret-volume created
      Check the files in the volume (notice two files are created: key1, key2):
      $ kubectl exec hello-busybox-secret-volume -- ls -l /tmp/secretkeyvalue
      lrwxrwxrwx    1    root    root    key1 -> ..data/key1
      lrwxrwxrwx    1    root    root    key2 -> ..data/key2
      Check the content of the files:
      $ kubectl exec hello-busybox-secret-volume -- cat /tmp/secretkeyvalue/key1
      value1
    • You can also decide what entries of the Secret can be mounted.

      You can also decide the names of the files in the volume "path".

      $ vi hello-busybox-secret-volume-item.yaml
      apiVersion: v1
      kind: Pod
      metadata:
        name: hello-busybox-secret-volume-item
      spec:
        containers:
          - name: hello-busybox-secret-volume-item
            image: busybox:latest
            tty: true
            stdin: true
            volumeMounts:
              - name: secretkeyvalue
                mountPath: /tmp/secretkeyvalue
        volumes:
          - name: secretkeyvalue
            secret:
              secretName: secretkeyvalue
              items:
                - key: key1
                  path: key1path
      Apply the Pod:
      $ kubectl apply -f hello-busybox-secret-volume-item.yaml
      pod/ello-busybox-secret-volume-item created
      Check the files in the volume (notice the "key1path" file was created):
      $ kubectl exec hello-busybox-secret-volume-item -- ls -l /tmp/secretkeyvalue
      lrwxrwxrwx    1    root    root    key1path -> ..data/key1path
      Check the content of the files:
      $ kubectl exec hello-busybox-secret-volume-item -- cat /tmp/secretkeyvalue/key1path
      value1
  8. Referencing Secrets' environment variables in the container's command
    You can use the data of the Secret to set the arguments of the container command.

    You need to use the following syntax to reference the environment variable: $(ENV_VAR_NAME).

    As previously mentioned, changes to the Secret won't be reflected on the environment variables already set.

    $ vi hello-busybox-secret-keyref-arg.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: hello-busybox-secret-keyref-arg
    spec:
      containers:
        - name: hello-busybox-secret-keyref-arg
          image: busybox:latest
          command: ['sh', '-c', 'echo "mykey1:$(mykey1) | mykey2:$(mykey2)"; sleep 300;']
          env:
            - name: mykey1
              valueFrom:
                secretKeyRef:
                  name: secretkeyvalue
                  key: key1
            - name: mykey2
              valueFrom:
                secretKeyRef:
                  name: secretkeyvalue
                  key: key2
    Apply the Pod:
    $ kubectl apply -f hello-busybox-secret-keyref-arg.yaml
    pod/hello-busybox-secret-keyref-arg created
    Check the logs of the Pod:
    $ kubectl logs hello-busybox-secret-keyref-arg
    mykey1:value1 | mykey2:value2
  9. Delete Secrets
    To delete a Secret: using manifest file (kubectl delete):
    $ kubectl delete -f secretkeyvalue.yaml
    secret "secretkeyvalue" deleted
    To delete a Secret using its name:
    $ kubectl delete secret secretkeyvalue
    secret "secretkeyvalue" deleted
© 2025  mtitek