Cloud Native 18 min read

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.

Ops Development Stories
Ops Development Stories
Ops Development Stories
Master Kubernetes Secrets & ConfigMaps: Creation, Usage, and Best Practices

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

kubectl

command.

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

type

field 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

items

field 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-registry

and referenced via

imagePullSecrets

in 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 configmap

or 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

items

field.

<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.

cloud-nativeKubernetesDevOpsK8sConfigMapSecret
Ops Development Stories
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.