Evolution of application deployment over the past 20 years.
Configure your local and remote lab environments.
Covers the resource types that are included with Kubernetes.
•Pod
•Job
Using helm to manage Kubernetes resources
Example microservice application.
Kubernetes manifests to deploy the demo application.
Explore how custom resources can add functionality
Install additional software to enhance the deployment.
Improving the DevX when working with Kubernetes.
How to safely upgrade your clusters and nodes.
Implement CI/CD for your applications (with GitOps!)
Kubernetes Secrets provide a way to manage sensitive information, such as passwords, tokens, or API keys, that require more security than standard configurations. Secrets can be consumed in a similar way to ConfigMaps, either as environment variables or mounted into a pod's filesystem. One key difference is that the data in Secrets is base64 encoded, but it's important to note that this is not a security measure, just a method to support binary data. To protect secrets properly, cluster encryption policies should be considered, especially for sensitive environments, as base64 encoding alone doesn’t provide protection.
Secrets can be defined using plain text through the stringData field or directly as base64 encoded data. Kubernetes supports several types of secrets, including opaque (for arbitrary user-defined data), docker-config-json (for authenticating to private container registries), TLS (for storing certificates), and service account tokens (for granting access to cluster resources). These types allow fine-grained control over access and management, and Kubernetes provides tools like kubectl to generate and manage secrets efficiently, ensuring the right format and encoding are used for specific use cases.
Official docs: https://kubernetes.io/docs/concepts/configuration/secret/
Let's explore how to create and managing Secrets using practical commands.
First, create a namespace for these examples and set it as the default.
# task 01-create-namespace
# - Create a namespace for these examples and set as default.
kubectl apply -f Namespace.yaml
kubens 04--secret
stringData
fieldNext, apply a secret using the stringData
field. This method allows you to define values in plain text, which Kubernetes will automatically base64 encode.
# task 02-apply-secret-string-data
# - Apply Secret using stringData field.
kubectl apply -f Secret.string-data.yaml
apiVersion: v1
kind: Secret
metadata:
name: string-data
type: Opaque
stringData:
foo: bar
If you can't represent your data as a string, or you want to match the format that will be used in the cluster, you can provide the secret data already base64 encoded.
# task 06-apply-secret-base64-data
# - Apply secret using base64 encoded data.
kubectl apply -f Secret.base64-data.yaml
apiVersion: v1
kind: Secret
metadata:
name: base64-data
type: Opaque
data:
foo: YmFy # <- This is "bar" base64 encoded
One common use case for kubernetes secrets is to store credentials to pull private container images.
It can be hard to get the syntax for this just right, so using the kubectl create command can be helpful.
# task 07-create-dockerconfigjson
# - Create a Docker registry secret.
kubectl create secret docker-registry dockerconfigjson \
--docker-email=foo@bar.com \
--docker-username=username \
--docker-password=password \
--docker-server=https://index.docker.io/v1/
This results in a secret like:
apiVersion: v1
kind: Secret
metadata:
name: dockerconfigjson
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: |
eyJhdXRocyI6eyJodHRwczovL2luZGV4LmRvY2tlci5pby92MSI6eyJ1c2VybmFtZSI6InVzZXJuYW1lIiwicGFzc3dvcmQiOiJwYXNzd29yZCIsImVtYWlsIjoiZm9vQGJhci5jb20iLCJhdXRoIjoiZFhObGNtNWhiV1U2Y0dGemMzZHZjbVE9In19fQ==
With these secrets created, we can now create a pod that consumes the data from these secrets.
Like with ConfigMaps, Secrets can be consumed as environment variables as volumes.
# task 09-apply-pod
# - Apply a pod that consumes the secret.
kubectl apply -f Pod.secret-example.yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-example
spec:
containers:
- name: nginx
image: nginx:1.26.0
volumeMounts:
- name: secret-base64-data
mountPath: /etc/config
env:
- name: ENV_VAR_FROM_SECRET
valueFrom:
secretKeyRef:
name: base64-data
key: foo
imagePullSecrets:
# Not necessary since example uses a public image, but including to show how
# you would use a registry credential secret to access a private image
- name: dockerconfigjson
volumes:
- name: secret-base64-data
secret:
secretName: base64-data
Once the pod is running we can inspect the environment variables and filesystem of the running container to confirm it worked.
# task 10-exec-printenv
# - Print the environment variables within the container.
kubectl exec secret-example -c nginx -- printenv
# task 11-exec-cat-config
# - Cat the secret file within the container.
kubectl exec secret-example -c nginx -- cat /etc/config/foo
Finally, clean up by deleting the namespace, which will also delete all resources within it.
# task 12-delete-namespace
# - Delete the namespace to clean up.
kubectl delete -f Namespace.yaml