Managing Secrets using Configuration File

Creating Secret objects using resource configuration file.

Before you begin

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:

Create the Secret

You can define the Secret object in a manifest first, in JSON or YAML format, and then create that object. The Secret resource 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 it allows you to provide the same data as unencoded strings. The keys of data and stringData must consist of alphanumeric characters, -, _ or ..

The following example stores two strings in a Secret using the data field.

  1. Convert the strings to base64:

    1. echo -n 'admin' | base64
    2. echo -n '1f2d1e2e67df' | base64

    Note: The serialized JSON and YAML values of Secret data are encoded as base64 strings. Newlines are not valid within these strings and must be omitted. When using the base64 utility on Darwin/macOS, users should avoid using the -b option to split long lines. Conversely, Linux users should add the option -w 0 to base64 commands or the pipeline base64 | tr -d '\n' if the -w option is not available.

    The output is similar to:

    1. YWRtaW4=
    2. MWYyZDFlMmU2N2Rm
  2. Create the manifest:

    1. apiVersion: v1
    2. kind: Secret
    3. metadata:
    4. name: mysecret
    5. type: Opaque
    6. data:
    7. username: YWRtaW4=
    8. password: MWYyZDFlMmU2N2Rm

    Note that the name of a Secret object must be a valid DNS subdomain name.

  3. Create the Secret using kubectl apply:

    1. kubectl apply -f ./secret.yaml

    The output is similar to:

    1. secret/mysecret created

To verify that the Secret was created and to decode the Secret data, refer to Managing Secrets using kubectl.

Specify unencoded data when creating a Secret

For certain scenarios, you may wish to use the stringData field instead. This field allows you to put a non-base64 encoded string directly into the Secret, and the string will be encoded for you when the Secret is created or updated.

A practical example of this might be where you are deploying an application that uses a Secret to store a configuration file, and you want to populate parts of that configuration file during your deployment process.

For example, if your application uses the following configuration file:

  1. apiUrl: "https://my.api.com/api/v1"
  2. username: "<user>"
  3. password: "<password>"

You could store this in a Secret using the following definition:

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: mysecret
  5. type: Opaque
  6. stringData:
  7. config.yaml: |
  8. apiUrl: "https://my.api.com/api/v1"
  9. username: <user>
  10. password: <password>

When you retrieve the Secret data, the command returns the encoded values, and not the plaintext values you provided in stringData.

For example, if you run the following command:

  1. kubectl get secret mysecret -o yaml

The output is similar to:

  1. apiVersion: v1
  2. data:
  3. config.yaml: YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IHt7dXNlcm5hbWV9fQpwYXNzd29yZDoge3twYXNzd29yZH19
  4. kind: Secret
  5. metadata:
  6. creationTimestamp: 2018-11-15T20:40:59Z
  7. name: mysecret
  8. namespace: default
  9. resourceVersion: "7225"
  10. uid: c280ad2e-e916-11e8-98f2-025000000001
  11. type: Opaque

Specify both data and stringData

If you specify a field in both data and stringData, the value from stringData is used.

For example, if you define the following Secret:

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: mysecret
  5. type: Opaque
  6. data:
  7. username: YWRtaW4=
  8. stringData:
  9. username: administrator

The Secret object is created as follows:

  1. apiVersion: v1
  2. data:
  3. username: YWRtaW5pc3RyYXRvcg==
  4. kind: Secret
  5. metadata:
  6. creationTimestamp: 2018-11-15T20:46:46Z
  7. name: mysecret
  8. namespace: default
  9. resourceVersion: "7579"
  10. uid: 91460ecb-e917-11e8-98f2-025000000001
  11. type: Opaque

YWRtaW5pc3RyYXRvcg== decodes to administrator.

Edit a Secret

To edit the data in the Secret you created using a manifest, modify the data or stringData field in your manifest and apply the file to your cluster. You can edit an existing Secret object unless it is immutable.

For example, if you want to change the password from the previous example to birdsarentreal, do the following:

  1. Encode the new password string:

    1. echo -n 'birdsarentreal' | base64

    The output is similar to:

    1. YmlyZHNhcmVudHJlYWw=
  2. Update the data field with your new password string:

    1. apiVersion: v1
    2. kind: Secret
    3. metadata:
    4. name: mysecret
    5. type: Opaque
    6. data:
    7. username: YWRtaW4=
    8. password: YmlyZHNhcmVudHJlYWw=
  3. Apply the manifest to your cluster:

    1. kubectl apply -f ./secret.yaml

    The output is similar to:

    1. secret/mysecret configured

Kubernetes updates the existing Secret object. In detail, the kubectl tool notices that there is an existing Secret object with the same name. kubectl fetches the existing object, plans changes to it, and submits the changed Secret object to your cluster control plane.

If you specified kubectl apply --server-side instead, kubectl uses Server Side Apply instead.

Clean up

To delete the Secret you have created:

  1. kubectl delete secret mysecret

What’s next