This is the multi-page printable view of this section. Click here to print.
Managing Secrets
- 1: Managing Secrets using kubectl
- 2: Managing Secrets using Configuration File
- 3: Managing Secrets using Kustomize
1 - Managing Secrets using kubectl
This page shows you how to create, edit, manage, and delete Kubernetes
Secrets using the kubectl
command-line tool.
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 a Secret
A Secret
object stores sensitive data such as credentials
used by Pods to access services. For example, you might need a Secret to store
the username and password needed to access a database.
You can create the Secret by passing the raw data in the command, or by storing
the credentials in files that you pass in the command. The following commands
create a Secret that stores the username admin
and the password S!B\*d$zDsb=
.
Use raw data
Run the following command:
kubectl create secret generic db-user-pass \
--from-literal=username=admin \
--from-literal=password='S!B\*d$zDsb='
You must use single quotes ''
to escape special characters such as $
, \
,
*
, =
, and !
in your strings. If you don't, your shell will interpret these
characters.
stringData
field for a Secret does not work well with server-side apply.
Use source files
-
Store the credentials in files:
echo -n 'admin' > ./username.txt echo -n 'S!B\*d$zDsb=' > ./password.txt
The
-n
flag ensures that the generated files do not have an extra newline character at the end of the text. This is important because whenkubectl
reads a file and encodes the content into a base64 string, the extra newline character gets encoded too. You do not need to escape special characters in strings that you include in a file. -
Pass the file paths in the
kubectl
command:kubectl create secret generic db-user-pass \ --from-file=./username.txt \ --from-file=./password.txt
The default key name is the file name. You can optionally set the key name using
--from-file=[key=]source
. For example:kubectl create secret generic db-user-pass \ --from-file=username=./username.txt \ --from-file=password=./password.txt
With either method, the output is similar to:
secret/db-user-pass created
Verify the Secret
Check that the Secret was created:
kubectl get secrets
The output is similar to:
NAME TYPE DATA AGE
db-user-pass Opaque 2 51s
View the details of the Secret:
kubectl describe secret db-user-pass
The output is similar to:
Name: db-user-pass
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 12 bytes
username: 5 bytes
The commands kubectl get
and kubectl describe
avoid showing the contents
of a Secret
by default. This is to protect the Secret
from being exposed
accidentally, or from being stored in a terminal log.
Decode the Secret
-
View the contents of the Secret you created:
kubectl get secret db-user-pass -o jsonpath='{.data}'
The output is similar to:
{ "password": "UyFCXCpkJHpEc2I9", "username": "YWRtaW4=" }
-
Decode the
password
data:echo 'UyFCXCpkJHpEc2I9' | base64 --decode
The output is similar to:
S!B\*d$zDsb=
Caution: This is an example for documentation purposes. In practice, this method could cause the command with the encoded data to be stored in your shell history. Anyone with access to your computer could find the command and decode the secret. A better approach is to combine the view and decode commands.kubectl get secret db-user-pass -o jsonpath='{.data.password}' | base64 --decode
Edit a Secret
You can edit an existing Secret
object unless it is
immutable. To edit a
Secret, run the following command:
kubectl edit secrets <secret-name>
This opens your default editor and allows you to update the base64 encoded
Secret values in the data
field, such as in the following example:
# 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, it will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
password: UyFCXCpkJHpEc2I9
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: "2022-06-28T17:44:13Z"
name: db-user-pass
namespace: default
resourceVersion: "12708504"
uid: 91becd59-78fa-4c85-823f-6d44436242ac
type: Opaque
Clean up
To delete a Secret, run the following command:
kubectl delete secret db-user-pass
What's next
- Read more about the Secret concept
- Learn how to manage Secrets using config file
- Learn how to manage Secrets using kustomize
2 - Managing Secrets using 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.
-
Convert the strings to base64:
echo -n 'admin' | base64 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 thebase64
utility on Darwin/macOS, users should avoid using the-b
option to split long lines. Conversely, Linux users should add the option-w 0
tobase64
commands or the pipelinebase64 | tr -d '\n'
if the-w
option is not available.The output is similar to:
YWRtaW4= MWYyZDFlMmU2N2Rm
-
Create the manifest:
apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4= password: MWYyZDFlMmU2N2Rm
Note that the name of a Secret object must be a valid DNS subdomain name.
-
Create the Secret using
kubectl apply
:kubectl apply -f ./secret.yaml
The output is similar to:
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:
apiUrl: "https://my.api.com/api/v1"
username: "<user>"
password: "<password>"
You could store this in a Secret using the following definition:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
stringData:
config.yaml: |
apiUrl: "https://my.api.com/api/v1"
username: <user>
password: <password>
stringData
field for a Secret does not work well with server-side apply.
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:
kubectl get secret mysecret -o yaml
The output is similar to:
apiVersion: v1
data:
config.yaml: YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IHt7dXNlcm5hbWV9fQpwYXNzd29yZDoge3twYXNzd29yZH19
kind: Secret
metadata:
creationTimestamp: 2018-11-15T20:40:59Z
name: mysecret
namespace: default
resourceVersion: "7225"
uid: c280ad2e-e916-11e8-98f2-025000000001
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:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
stringData:
username: administrator
stringData
field for a Secret does not work well with server-side apply.
The Secret
object is created as follows:
apiVersion: v1
data:
username: YWRtaW5pc3RyYXRvcg==
kind: Secret
metadata:
creationTimestamp: 2018-11-15T20:46:46Z
name: mysecret
namespace: default
resourceVersion: "7579"
uid: 91460ecb-e917-11e8-98f2-025000000001
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:
-
Encode the new password string:
echo -n 'birdsarentreal' | base64
The output is similar to:
YmlyZHNhcmVudHJlYWw=
-
Update the
data
field with your new password string:apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4= password: YmlyZHNhcmVudHJlYWw=
-
Apply the manifest to your cluster:
kubectl apply -f ./secret.yaml
The output is similar to:
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:
kubectl delete secret mysecret
What's next
- Read more about the Secret concept
- Learn how to manage Secrets using kubectl
- Learn how to manage Secrets using kustomize
3 - Managing Secrets using Kustomize
kubectl
supports using the Kustomize object management tool to manage Secrets
and ConfigMaps. You create a resource generator using Kustomize, which
generates a Secret that you can apply to the API server using kubectl
.
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 a Secret
You can generate a Secret by defining a secretGenerator
in a
kustomization.yaml
file that references other existing files, .env
files, or
literal values. For example, the following instructions create a Kustomization
file for the username admin
and the password 1f2d1e2e67df
.
stringData
field for a Secret does not work well with server-side apply.
Create the Kustomization file
secretGenerator:
- name: database-creds
literals:
- username=admin
- password=1f2d1e2e67df
-
Store the credentials in files. The filenames are the keys of the secret:
echo -n 'admin' > ./username.txt echo -n '1f2d1e2e67df' > ./password.txt
The
-n
flag ensures that there's no newline character at the end of your files. -
Create the
kustomization.yaml
file:secretGenerator: - name: database-creds files: - username.txt - password.txt
You can also define the secretGenerator in the kustomization.yaml
file by
providing .env
files. For example, the following kustomization.yaml
file
pulls in data from an .env.secret
file:
secretGenerator:
- name: db-user-pass
envs:
- .env.secret
In all cases, you don't need to base64 encode the values. The name of the YAML
file must be kustomization.yaml
or kustomization.yml
.
Apply the kustomization file
To create the Secret, apply the directory that contains the kustomization file:
kubectl apply -k <directory-path>
The output is similar to:
secret/database-creds-5hdh7hhgfk created
When a Secret is generated, the Secret name is created by hashing the Secret data and appending the hash value to the name. This ensures that a new Secret is generated each time the data is modified.
To verify that the Secret was created and to decode the Secret data,
kubectl get -k <directory-path> -o jsonpath='{.data}'
The output is similar to:
{ "password": "UyFCXCpkJHpEc2I9", "username": "YWRtaW4=" }
echo 'UyFCXCpkJHpEc2I9' | base64 --decode
The output is similar to:
S!B\*d$zDsb=
For more information, refer to Managing Secrets using kubectl and Declarative Management of Kubernetes Objects Using Kustomize.
Edit a Secret
-
In your
kustomization.yaml
file, modify the data, such as thepassword
. -
Apply the directory that contains the kustomization file:
kubectl apply -k <directory-path>
The output is similar to:
secret/db-user-pass-6f24b56cc8 created
The edited Secret is created as a new Secret
object, instead of updating the
existing Secret
object. You might need to update references to the Secret in
your Pods.
Clean up
To delete a Secret, use kubectl
:
kubectl delete secret db-user-pass
What's next
- Read more about the Secret concept
- Learn how to manage Secrets using kubectl
- Learn how to manage Secrets using config file