Sensitive application values need a cluster-side object that workloads can reference without storing the value directly in a Pod manifest or container image. A Kubernetes Secret is the namespaced object for passwords, tokens, and small key material, and it lets the value exist separately from the Pods that consume it.
kubectl create secret generic creates an Opaque Secret from literal values, files, directories, or environment-style files. The Secret must live in the same namespace as the workload that reads it, and each key can be exposed to a container as an environment variable or mounted file.
Secret data is base64-encoded in the API, not automatically encrypted for every cluster. Treat any account that can read Secrets, create Pods in the namespace, or access the backing datastore as sensitive, and avoid printing real credential values in shared terminals, screenshots, logs, or tickets.
Steps to create a Kubernetes Secret:
- Create a namespace for the Secret test.
$ kubectl create namespace app-secrets namespace/app-secrets created
Use the application namespace instead of app-secrets when adding a Secret to an existing workload.
Related: How to create a Kubernetes namespace
- Create the generic Secret from sample literal values.
$ kubectl create secret generic app-secret --namespace app-secrets --from-literal=DB_USERNAME=appuser --from-literal=DB_PASSWORD=not-a-real-password secret/app-secret created
Use non-sensitive sample values for tests. For real credentials, avoid pasting values into shared shell history and prefer a controlled secret manager or a local file that is not committed.
- Inspect the Secret type and stored key names.
$ kubectl describe secret app-secret --namespace app-secrets Name: app-secret Namespace: app-secrets Labels: <none> Annotations: <none> Type: Opaque Data ==== DB_PASSWORD: 19 bytes DB_USERNAME: 7 bytes
kubectl describe secret shows key names and byte counts without printing the stored values.
- Create a Pod manifest that reads the Secret keys as environment variables.
- secret-check-pod.yaml
apiVersion: v1 kind: Pod metadata: name: secret-check namespace: app-secrets spec: restartPolicy: Never containers: - name: secret-check image: busybox:1.36 command: - sh - -c - | echo DB_USERNAME=$DB_USERNAME if [ -n "$DB_PASSWORD" ]; then echo DB_PASSWORD_SET=yes; fi sleep 300 env: - name: DB_USERNAME valueFrom: secretKeyRef: name: app-secret key: DB_USERNAME - name: DB_PASSWORD valueFrom: secretKeyRef: name: app-secret key: DB_PASSWORD
secretKeyRef selects one key from one Secret. Use envFrom.secretRef only when all Secret keys are valid environment variable names and the container should receive the full set.
- Apply the Pod manifest.
$ kubectl apply -f secret-check-pod.yaml pod/secret-check created
- Wait for the Pod to become ready.
$ kubectl wait --for=condition=Ready pod/secret-check --namespace app-secrets --timeout=120s pod/secret-check condition met
The short sleep command keeps the test container running long enough for the readiness check and log readback.
- Read the Pod logs to confirm the Secret reached the container.
$ kubectl logs secret-check --namespace app-secrets DB_USERNAME=appuser DB_PASSWORD_SET=yes
The test prints only whether DB_PASSWORD is set, not the password value.
- Delete the lab namespace when the Secret test is finished.
$ kubectl delete namespace app-secrets namespace "app-secrets" deleted
Skip this command for a real application namespace. Delete only the test Pod and test Secret if the namespace contains other workloads.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.