Master Kubernetes Secrets & ConfigMaps: Creation, Usage, and Best Practices
This guide explains how to create and manage Kubernetes Secrets and ConfigMaps, covering YAML and kubectl methods, different secret types, mounting techniques, environment variable injection, image pull secrets, and practical examples for secure configuration handling in cloud‑native environments.
In any application, configuration files are common; enterprises often use configuration centers like Apollo or Nacos, or Kubernetes built‑in configuration management, primarily Secret and ConfigMap.
Secret
When configuration data is stored in a Secret, it is encrypted in etcd. Pods can use Secrets via environment variables, volume mounts, or as image pull secrets.
Secrets typically hold sensitive data such as database credentials and should be kept small to avoid excessive memory usage by the API server and kubelet.
Creating a Secret
Secrets can be created using a YAML file or the
kubectlcommand.
Using a YAML file
First, explore the Secret fields with
kubectl explain secret. The main fields are
apiVersion,
kind,
metadata,
type, and
data.
Example YAML:
<code>apiVersion: v1
kind: Secret
metadata:
name: my-secret-volume
type: Opaque
data:
user: cm9vdA==
password: UEBzc1cwcmQ=
</code>The
typefield defines the secret type, such as
Opaque,
kubernetes.io/service-account-token,
kubernetes.io/dockerconfigjson,
kubernetes.io/basic-auth,
kubernetes.io/ssh-auth,
kubernetes.io/tls, etc. If omitted, the default type is
Opaque. Data values must be base64‑encoded.
Using the kubectl command
Create a generic secret from literals:
<code>$ kubectl create secret generic secret-auth-test --from-literal=username=joker --from-literal=password=123
</code>View the created secret:
<code>$ kubectl get secret secret-auth-test -o yaml
apiVersion: v1
kind: Secret
metadata:
name: secret-auth-test
namespace: default
uid: ff1b756a-6b38-4b68-a47c-c51988729b68
creationTimestamp: "2022-07-25T07:44:18Z"
resourceVersion: "652834"
type: Opaque
data:
password: MTIz
username: am9rZXI=
</code>You can also create a secret from files:
<code>$ 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
</code>Retrieve the plaintext value:
<code>$ kubectl get secret db-user-pass -o jsonpath='{.data.password}' | base64 --decode
</code>Using a Secret
Secrets are static resources; they are typically consumed in three ways:
Environment variables
Volume mounts
Image pull secrets
Environment variable injection
Reference a secret in a pod spec:
<code>apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: secret-auth-test
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: secret-auth-test
key: password
</code>Mounting a secret as a volume
Mount the secret into a container directory:
<code>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: secret-auth-test
</code>Only specific keys can be mounted by using the
itemsfield and setting a custom path.
<code>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: secret-auth-test
items:
- key: username
path: my-group/my-username
</code>File permissions can be controlled with
defaultMode(e.g.,
0400).
Image pull secret
Private registry credentials are stored in a secret of type
docker-registryand referenced via
imagePullSecretsin the pod spec.
<code>$ kubectl create secret docker-registry pull-registry-secret \
--docker-server=registry.test.cn \
--docker-username=ops \
--docker-password=ops123123
</code>Pod example:
<code>apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
imagePullSecrets:
- name: pull-registry-secret
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
volumes:
- name: foo
secret:
secretName: secret-auth-test
defaultMode: 0400
</code>ConfigMap
ConfigMaps store non‑sensitive configuration data and are used similarly to Secrets.
Creating a ConfigMap
ConfigMaps can be created via
kubectl create configmapor from a YAML file.
From the command line
Examples:
<code># Create from a directory
kubectl create configmap my-config --from-file=path/to/dir
# Create from literals
kubectl create configmap my-config --from-literal=db.host=localhost --from-literal=db.port=3306
</code>From a YAML file
<code>apiVersion: v1
kind: ConfigMap
metadata:
name: my-cm-daemon2
labels:
app: cm-daemon
data:
redis.conf: |
host=127.0.0.1
port=6379
</code>Using a ConfigMap
ConfigMap data can be consumed as environment variables or mounted as files.
Environment variables
<code>apiVersion: v1
kind: Pod
metadata:
name: env-configmap
spec:
containers:
- name: test-configmap
image: busybox
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: my-cm-daemo
key: db.host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: my-cm-daemo
key: db.port
envFrom:
- configMapRef:
name: my-cm-daemo
</code>Mounted as a volume
<code>apiVersion: v1
kind: Pod
metadata:
name: volume-configmap-test
spec:
containers:
- name: volume-configmap-test
image: busybox
command: ["/bin/sh", "-c", "cat /etc/config/redis.conf"]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: my-configmap
</code>Specific keys can be mapped to custom paths using the
itemsfield.
<code>apiVersion: v1
kind: Pod
metadata:
name: volume-path-configmap
spec:
containers:
- name: volume-path-configmap-test
image: busybox
command: ["/bin/sh", "-c", "cat /etc/config/path/to/msyqld.conf"]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: my-configmap
items:
- key: mysqld.conf
path: path/to/msyqld.conf
</code>When a ConfigMap is mounted as a volume, updates to the ConfigMap are reflected inside the pod without restarting, provided the application can reload the configuration.
Summary
Secrets are ideal for storing sensitive information such as credentials, and can be injected via environment variables, mounted as files, or used for image pulling. ConfigMaps handle non‑sensitive configuration data and support the same consumption methods, with the added benefit of live updates when mounted as volumes.
Ops Development Stories
Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.