ConfigMaps and Secrets: Managing Application Configuration in Kubernetes

Inject configuration data and sensitive information into Kubernetes pods using ConfigMaps and Secrets. Learn about mounting strategies, environment variables, and security best practices.

published: reading time: 25 min read author: GeekWorkBench updated: June 17, 2026
Quick Summary

Here's the thing about ConfigMaps versus Secrets: they work the same way, but you use Secrets for anything you'd rather not see printed in a YAML export. Volume mounts let you update config without restarting pods — environment variables don't, and I see engineers get burned by that distinction all the time. And please, enable encryption at rest before you put anything real into native Kubernetes Secrets; base64 isn't encryption. If you need audit logs and automatic rotation, External Secret Operators are the way to go.

ConfigMaps and Secrets: Managing Application Configuration in Kubernetes

Applications need configuration. Database URLs, feature flags, API keys, and connection strings change between environments. Hardcoding these values into container images defeats the purpose of containerization. Kubernetes provides two resources for injecting configuration into pods: ConfigMap and Secret.

This post explains how to create these resources, inject them into pods, and use them securely.

For Kubernetes basics, see the Kubernetes fundamentals post. For advanced patterns like external secret operators, read the Advanced Kubernetes post.

Introduction

ConfigMaps and Secrets feed configuration into your Kubernetes containers. ConfigMaps handle the boring stuff — feature flags, environment-specific settings, config files. Secrets handle the stuff you do not want in plaintext: database passwords, API keys, TLS certs. Both mount into pods as environment variables or files.

The line between them blurs in dev. It sharpens in production. Native Kubernetes Secrets are just base64-encoded in etcd — no encryption by default, and anyone with cluster access can decode them. ConfigMaps are stored in plaintext everywhere. If you are running regulated workloads (PCI, HIPAA, anything with serious compliance requirements), you need to harden both before they touch production.

This post covers the basics: creating and injecting ConfigMaps and Secrets, when to use volume mounts instead of environment variables, and where External Secret Operators fit in. After reading, you will have a config management approach that works across dev, staging, and prod without accidentally leaking anything sensitive.

When to Use / When Not to Use

Use ConfigMaps when

ConfigMaps work well for non-sensitive configuration that changes between environments: feature flags, environment variables, application settings, and configuration files like nginx.conf or config.yaml.

Share ConfigMaps across pods in the same namespace. The key benefit is keeping configuration out of container images so the same image works in dev, staging, and prod.

Use Secrets when

Secrets are for anything that should not appear in plaintext: database passwords, API keys, OAuth tokens, TLS certificates, SSH keys.

Kubernetes stores Secrets as base64-encoded strings in etcd. Without encryption at rest, these are readable by anyone with etcd access. For sensitive production workloads, use External Secret Operators that sync from Vault, AWS Secrets Manager, or similar.

Skip ConfigMaps for

Sensitive data is the obvious case, but there are others. If your configuration contains internal hostnames that change between clusters, or if the ConfigMap would need to embed cloud provider credentials, reach for a Secret or an external config store instead. ConfigMaps also have no concept of versioning or audit trails. If you need to track who changed a config value and when, native ConfigMaps cannot provide that.

Do not use ConfigMaps for anything that would be embarrassing if it appeared in a Git commit, a Slack message, or an etcd backup. Treat ConfigMap names and contents as semi-public — cluster metadata is often visible to more people than you assume.

The practical test: if you would hesitate to run kubectl get configmap app-config -o yaml in front of your security team, it belongs in a Secret or an external store.

Skip native Kubernetes Secrets for (without encryption at rest)

Native Secrets are base64-encoded, not encrypted. Anyone who can query the Kubernetes API or read an etcd snapshot can read your Secrets without any special privilege. This is fine for a single-tenant dev cluster. It is not acceptable in environments subject to PCI-DSS, HIPAA, SOC 2, or any compliance framework that treats credentials as sensitive material.

Multi-tenant clusters compound this problem. If you are running workloads for multiple customers on the same cluster, a compromised or misconfigured RBAC role on one tenant’s namespace could expose Secrets from another tenant’s namespace. Native Secrets have no namespace boundary enforcement for read operations beyond RBAC.

The minimum bar before using native Secrets in production is encryption at rest for etcd. This prevents snapshot exposure and disk-level theft. Even then, rotation, audit logging, and access controls require manual process. If you are building for regulated workloads, budget time for External Secret Operators from day one.

ScenarioNative Secrets OK?Recommendation
Local dev, single userYesNo hardening needed
Shared dev cluster, no sensitive dataYesStill no sensitive data in Secrets
Staging, non-production secretsLimitedEnable encryption at rest
Production, non-regulatedRiskyEnable encryption at rest + ESO
Production, PCI/HIPAA/SOC 2NoESO with Vault or cloud secret manager

ConfigMap/Secret Injection Flow

flowchart TD
    CM[ConfigMap<br/>or Secret] -->|kubectl apply| K8s[Kubernetes API Server]
    K8s -->|Store| etcd[etcd datastore]
    K8s -->|Watch| Pod[Pod with Container]
    Pod -->|Mount as| Volume[/etc/config<br/>or /run/secrets]
    Pod -->|Inject as| EnvVar[Environment<br/>Variables]

Volume mounts update automatically when the ConfigMap or Secret changes. Environment variables do not update after pod start. For dynamic configuration updates, use volume mounts with application-side file watching or SIGHUP reload.

ConfigMap Creation and Usage Patterns

ConfigMaps store non-sensitive configuration as key-value pairs or files. You create them from literal values, files, or directories.

Creating from literals

Pass --from-literal with a key=value pair to create a ConfigMap entry directly. The bit before the = is the key, everything after is the value. Stack the flag multiple times to add more entries in one command.

kubectl create configmap app-config \
  --from-literal=ENVIRONMENT=production \
  --from-literal=LOG_LEVEL=info \
  --from-literal=MAX_CONNECTIONS=100

This creates a ConfigMap named app-config with three keys: ENVIRONMENT, LOG_LEVEL, and MAX_CONNECTIONS.

Creating from a file

kubectl create configmap nginx-config \
  --from-file=nginx.conf

The filename becomes the configmap key. The file contents become the value.

Creating from a directory

Point --from-file at a directory and every file in it becomes a key in the ConfigMap, the file contents becoming the values. Subdirectories and hidden files are skipped — only top-level files get imported.

kubectl create configmap html-content \
  --from-file=html/

If html/ contains index.html and about.html, the ConfigMap has two keys. This works well for bulk-loading nginx conf directories, static asset folders, or anything an application reads as separate files rather than a single config blob.

Defining in YAML

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: production
data:
  ENVIRONMENT: "production"
  LOG_LEVEL: "info"
  DATABASE_HOST: "postgres.database.svc.cluster.local"
  DATABASE_PORT: "5432"

Injecting ConfigMap into Pods

You can inject ConfigMap values as environment variables or volume mounts.

Environment variables

apiVersion: v1
kind: Pod
metadata:
  name: web-app
  namespace: production
spec:
  containers:
    - name: web-app
      image: nginx:1.25
      envFrom:
        - configMapRef:
            name: app-config

With envFrom, all keys from the ConfigMap become environment variables. For selective injection, use env:

env:
  - name: LOG_LEVEL
    valueFrom:
      configMapKeyRef:
        name: app-config
        key: LOG_LEVEL
  - name: ENVIRONMENT
    valueFrom:
      configMapKeyRef:
        name: app-config
        key: ENVIRONMENT

Volume mounts

Mount ConfigMap values as files:

apiVersion: v1
kind: Pod
metadata:
  name: web-app
spec:
  containers:
    - name: web-app
      image: nginx:1.25
      volumeMounts:
        - name: config
          mountPath: /etc/nginx/conf.d
          readOnly: true
  volumes:
    - name: config
      configMap:
        name: nginx-config
        items:
          - key: nginx.conf
            path: default.conf

With this setup, /etc/nginx/conf.d/default.conf contains the contents of the nginx.conf key from the ConfigMap.

Secrets Types and Limitations

Secrets work like ConfigMaps but store sensitive data. Kubernetes stores Secrets as base64-encoded strings, not encrypted. Anyone with API access or etcd access can read Secrets.

apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
  namespace: production
type: Opaque
data:
  username: cG9zdGdyZXM=
  password: c2VjcmV0cGFzc3dvcmQ=

Generate base64 values:

echo -n "postgres" | base64
echo -n "secretpassword" | base64

Kubernetes Secret types

TypeUse Case
OpaqueArbitrary key-value pairs
kubernetes.io/tlsTLS certificates
kubernetes.io/dockerconfigjsonDocker registry credentials
kubernetes.io/basic-authBasic auth credentials

TLS Secret

apiVersion: v1
kind: Secret
metadata:
  name: tls-cert
  namespace: production
type: kubernetes.io/tls
data:
  tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...
  tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0t...

Mounting vs Environment Variables

Both approaches work, but they have different properties:

AspectEnvironment VariablesVolume Mounts
Update propagationPod must restartFiles update automatically (with sync wave)
VisibilityVisible in kubectl exec outputLess exposed
FormatSingle valuesFiles
Size limitNot suitable for large configsGood for config files

Environment variables work well for simple string values. Volume mounts are better for configuration files, certificates, and other structured data.

For configuration files that change, volume mounts update automatically. Kubernetes syncs the ConfigMap to the volume within a short delay (configurable via ConfigMap data section). Your application needs to watch for file changes or reload on SIGHUP.

External Secret Operators

Kubernetes Secrets have limitations. They are not encrypted by default, they have strict size limits (1MB), and they do not integrate with external secret managers. External Secret Operators bridge this gap.

Tools like External Secrets Operator (ESO), HashiCorp Vault, and AWS Secrets Manager integrate with Kubernetes to sync secrets from external stores.

External Secrets Operator example

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: database-secrets
  namespace: production
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: vault-backend
    kind: ClusterSecretStore
  target:
    name: db-secrets
    creationPolicy: Owner
  data:
    - secretKey: password
      remoteRef:
        key: production/database
        property: password

This ExternalSecret syncs the password field from the Vault key production/database into a Secret named db-secrets. The Operator handles rotation and updates.

ESO supports AWS Secrets Manager, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, and other providers.

Security Hardening for Secrets

Since Kubernetes does not encrypt Secrets by default, you need additional measures for sensitive data:

Enable encryption at rest

Configure the kube-apiserver to encrypt Secrets before storing them in etcd:

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
    providers:
      - aesgcm:
          keys:
            - name: key1
              secret: <base64-encoded-32-byte-key>
      - identity: {}

Enable this in the kube-apiserver configuration:

--encryption-provider-config=/path/to/encryption-config

Use RBAC to restrict Secret access

Limit who can read Secrets using Role-Based Access Control:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: secret-reader
rules:
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "list"]

Enable RBAC authentication

Without RBAC, any authenticated user or service account in the cluster can read any resource, including your Secrets. GKE, EKS, and AKS enable it by default. Self-hosted setups sometimes ship with AlwaysAllow.

Check your kube-apiserver:

kubectl get pod kube-apiserver -n kube-system -o jsonpath='{.spec.containers[0].command}' | grep -i rbac

If RBAC shows up in --authorization-mode, you are fine. If you see AlwaysAllow or nothing at all, add RBAC to that flag and restart the apiserver. On managed clusters, do this through the cloud console or your infrastructure-as-code tool — not by SSHing into the node.

Consider third-party solutions

Native Kubernetes Secrets cover the basic case. Third-party solutions cover the production case. The gap between them is real and matters when you have auditors in the room.

HashiCorp Vault is the most mature option. It handles secret rotation, lease management, dynamic credentials, and audit logs. The Vault Kubernetes Authentication method lets pods authenticate with ServiceAccount tokens rather than embedding static credentials. Vault can generate database credentials on demand that expire after a TTL — something native Secrets cannot do.

AWS Secrets Manager, Azure Key Vault, and GCP Secret Manager integrate with their respective cloud providers. If your cluster runs on a cloud provider, the managed secret stores reduce operational overhead significantly. The External Secrets Operator (ESO) standardizes these integrations into a single Kubernetes-native resource definition.

The External Secrets Operator deserves special mention because it does not require a Vault deployment. ESO defines an ExternalSecret resource that maps to any of the major providers. If you start on AWS and later migrate to Azure, the Kubernetes manifests stay the same. Only the SecretStore configuration changes. This portability matters more than it sounds when you are in the middle of an incident.

Audit logs are the feature that brings most teams to third-party solutions. Kubernetes does not log who read a Secret or when. Vault and cloud secret managers log every access with identity, timestamp, and source IP. If your compliance posture requires access evidence, native tooling cannot provide it.

Trade-off Analysis

ConfigMap Mounting vs Environment Variables

AspectEnvironment VariablesVolume Mounts
Update propagationRequires pod restartAutomatic update within ~1 minute
Maximum size1MB total per pod env vars1MB per ConfigMap, good for config files
Application supportUniversal — all apps read env varsRequires file-watch or SIGHUP handling
Type safetyString values onlyCan map to JSON, YAML files
VisibilityVisible in kubectl exec outputLess exposed in process arguments

Native Secrets vs External Secret Operators

AspectNative Kubernetes SecretsExternal Secret Operators (ESO)
EncryptionBase64 only, not encrypted by defaultFull encryption with external provider
RotationManual rotation requiredAutomatic sync and rotation from external store
Audit logsNone built-inFull audit trail from the secret manager
Size limit1MB1MB but better distributed across providers
IntegrationNoneVault, AWS SM, Azure KV, GCP SM

ConfigMap Binary Data vs UTF-8 Data

AspectUTF-8 Data (data)Binary Data (binaryData)
EncodingUTF-8 strings directlyBase64-encoded binary content
Use caseConfig files, text valuesTLS certificates, private keys, images
ValidationKubernetes validates as stringNo content validation — you manage encoding
Size limit1MB1MB

YAML vs kubectl create configmap

AspectYAML (kubectl apply)kubectl create commands
Version controlYes — declarative, reviewableImperative — not self-documenting
Drift detectionYesNo
ReusabilityYes — with kustomize/helm overlaysLimited — hard to adapt for different envs
SpeedSlower to typeFaster for quick local dev

For production, use YAML with GitOps workflows. For local development, kubectl create commands are acceptable for temporary ConfigMaps.

Production Failure Scenarios

Secret Not Found at Pod Startup

If a Secret referenced in a pod does not exist when the pod starts, the pod fails to start with SecretNotFound error.

Symptoms: Pod stuck in Pending or ContainerCreating state, Secrets not found in events.

Diagnosis:

kubectl describe pod <pod-name> -n <namespace>
kubectl get secret <secret-name> -n <namespace>

Mitigation: Create Secrets before applying Pods that reference them. Use depends_on in Helm or kustomize to enforce ordering.

ConfigMap Update Not Propagating to Pods

When a ConfigMap is updated, volume-mounted files reflect the change, but environment variables do not update without pod restart.

Symptoms: Application uses stale configuration even after ConfigMap update.

Mitigation: Use volume mounts for configuration that changes at runtime. Implement SIGHUP handling in your application to reload on file change, or restart pods automatically using a tool like Reloader.

Base64 Encoding Errors in Secrets

Kubernetes Secrets store values as base64 strings. If the base64 encoding is wrong (missing padding, wrong characters), the decoded value is corrupted.

Symptoms: Application fails to connect to database with authentication failed, decoded values are garbled.

Mitigation: Always use echo -n "value" | base64 (note the -n to avoid trailing newline) and echo "b64value" | base64 -d for decoding.

Anti-Patterns

Storing Secrets in ConfigMaps

This one looks obvious until you see it in a real cluster. The problem is not the kind: ConfigMap declaration — it is the naming and the context drift that follows.

Teams start with good intentions: a ConfigMap named app-config containing DATABASE_PASSWORD=.... Six months later someone creates api-keys as a ConfigMap and puts AWS credentials in it. The pattern is established. A new engineer sees both and assumes ConfigMaps are fine for secrets because nobody corrected the first one.

ConfigMaps export cleanly with kubectl get configmap -o yaml. That output ends up in Git history, in CI logs, in Kubernetes dashboards, and in etcd backups. If a ConfigMap with a misleading name contains sensitive data, it will eventually be exposed through one of these channels.

The second problem is that ConfigMaps have no access control beyond namespace-level RBAC. Anyone who can list ConfigMaps in a namespace can read every ConfigMap in it. Secrets at least have the kubernetes.io/service-account-token type and get somewhat more careful treatment in tooling. ConfigMaps do not even get that.

The fix is simple: name things accurately. If it is a Secret, call it app-secrets or db-credentials. If you find sensitive data in a ConfigMap, treat it as a potential security incident and rotate the exposed credential immediately.

Not Using binaryData for Non-UTF8 Content

The data field in a ConfigMap expects UTF-8 strings. If you put a binary file into data — a TLS certificate, a private key, a PNG — Kubernetes validates the content as a UTF-8 string and rejects it if the bytes are not valid UTF-8. The error message is not immediately obvious: you get a validation error saying the value is not a valid UTF-8 string.

This trips people up when they try to store a certificate bundle or a private key directly using kubectl create configmap with --from-file. If the file is binary, the command fails or creates a corrupted entry depending on how the shell handles the bytes.

The binaryData field is where binary content belongs. You base64-encode the binary content yourself, and Kubernetes stores it without validating it as text. The catch is that you cannot read decoded values directly with kubectl get configmap. You must decode them manually:

kubectl get configmap my-cert --output jsonpath='{.data.tls\.crt}' | base64 -d > certificate.crt

When you see validation errors on ConfigMap creation for what should be a simple file, check whether the file is binary. TLS certificates, SSH keys, and signed payloads are all binary data. Putting them in data as a string will fail or produce garbled output when the shell tries to interpret raw bytes as UTF-8.

If you need to mount a binary file into a pod as-is, binaryData is the correct field. If you are storing text that happens to include non-ASCII characters, ensure your editor saved it as UTF-8 before creating the ConfigMap.

Copying Entire ConfigMap into Every Environment

Different environments (dev, staging, prod) need different configurations. Copying the same ConfigMap across environments leads to hardcoded production URLs in dev or debug flags in production.

Use Kustomize overlays or Helm values to inject environment-specific configuration.

Interview Questions

1. What is the difference between a ConfigMap and a Secret in Kubernetes?

Expected answer points:

  • ConfigMaps store non-sensitive configuration as UTF-8 key-value pairs
  • Secrets store sensitive data (passwords, tokens, keys) but are base64-encoded, not encrypted by default
  • Both are namespaced resources accessible by pod volume mounts or environment variables
  • Secrets should be used for anything that must not appear in plaintext in YAML exports or etcd
2. How do you inject a ConfigMap value as an environment variable in a pod?

Expected answer points:

  • Use `envFrom` with `configMapRef` to inject all keys as environment variables
  • Use `env` with `configMapKeyRef` for selective injection of specific keys
  • Environment variables are set at pod startup — they do not update when the ConfigMap changes
  • For dynamic updates, use volume mounts instead of environment variables
3. What happens when a ConfigMap mounted as a volume is updated?

Expected answer points:

  • Kubernetes syncs the updated ConfigMap to the volume within a short delay (configurable)
  • The application must watch for file changes or reload on SIGHUP signal
  • Environment variables do NOT update without pod restart — volume mounts are required for dynamic updates
  • Tools like Reloader can automate pod restarts when ConfigMaps change
4. Why should you avoid storing Secrets in native Kubernetes Secrets without encryption at rest?

Expected answer points:

  • Kubernetes stores Secrets as base64-encoded strings in etcd — this is not encryption
  • Anyone with etcd access (cluster admin, etcd backup files) can read Secret values
  • Encryption at rest must be explicitly enabled via kube-apiserver encryption configuration
  • For regulated environments (PCI-DSS, HIPAA), native Secrets without encryption are insufficient
5. What is the External Secrets Operator and why would you use it?

Expected answer points:

  • ESO syncs secrets from external secret managers (Vault, AWS SM, Azure KV, GCP SM) into Kubernetes Secrets
  • It provides automatic rotation, audit logs, and encryption that native Secrets lack
  • You define an ExternalSecret resource that references the external store — ESO reconciles them
  • Best practice for production workloads in regulated or multi-tenant environments
6. What is the difference between `data` and `binaryData` fields in a ConfigMap?

Expected answer points:

  • `data` stores UTF-8 string values as-is
  • `binaryData` stores base64-encoded binary content for non-text files like certificates or images
  • If you need to store binary content in `data`, you must base64-encode it yourself
  • `binaryData` is an alternative that Kubernetes handles as raw binary without UTF-8 validation
7. How do you restrict which pods can read a specific Secret using RBAC?

Expected answer points:

  • Create a Role (namespace-scoped) with `get` and `list` verbs on `secrets`
  • Create a ServiceAccount for the pod
  • Create a RoleBinding to associate the ServiceAccount with the Role
  • The pod uses that ServiceAccount via `spec.serviceAccountName`
8. How do you enable encryption at rest for Secrets in etcd?

Expected answer points:

  • Create an EncryptionConfiguration YAML with AES-GCM or another provider
  • Pass the config to kube-apiserver via `--encryption-provider-config` flag
  • All Secrets written to etcd after enabling the provider are encrypted
  • Existing Secrets are not encrypted until they are rewritten (re-created)
9. What are the four built-in Secret types in Kubernetes?

Expected answer points:

  • Opaque — arbitrary key-value pairs (default type)
  • kubernetes.io/tls — TLS certificates and keys
  • kubernetes.io/dockerconfigjson — Docker registry credentials
  • kubernetes.io/basic-auth — basic authentication credentials
10. Why is it bad practice to copy the same ConfigMap across dev, staging, and production environments?

Expected answer points:

  • Dev, staging, and prod have different database URLs, API endpoints, and feature flags
  • Copying the same ConfigMap means production URLs end up in dev, or debug flags in production
  • Use Kustomize overlays or Helm values to inject environment-specific values
  • GitOps workflows should treat ConfigMaps as code with environment-specific variants
11. How do you debug a ConfigMap that is not being injected into a pod correctly?

Expected answer points:

  • Verify the ConfigMap exists in the same namespace as the pod: `kubectl get configmap -n `
  • Check the pod spec references the correct ConfigMap name and injection method (env vs volume)
  • Use `kubectl describe pod ` to see events — look for ConfigMap or Secret not found errors
  • Verify key names match exactly — Kubernetes is case-sensitive for ConfigMap keys
12. What is the maximum size for a ConfigMap and a Secret?

Expected answer points:

  • Both ConfigMaps and Secrets have a maximum size of 1MB
  • For very large configuration files, consider storing them in object storage and pulling them at runtime
  • Large ConfigMaps impact etcd performance and kubectl response times
13. How does a pod access a Secret mounted as a file?

Expected answer points:

  • Secrets mounted as volumes appear as files in the mount directory (default: `/run/secrets`)
  • Each Secret key becomes a file containing the decoded value
  • The mount is `tmpfs` — secrets are never written to disk
  • Files update automatically when the Secret changes (similar to ConfigMap volume mounts)
14. What is the recommended way to handle Secret rotation in Kubernetes?

Expected answer points:

  • Native Kubernetes Secrets do not support automatic rotation — you must manually update and restart pods
  • External Secret Operators can automate rotation by monitoring the external secret store
  • Application must support SIGHUP reload or be restarted when secrets change
  • Use versioned secrets or secret snapshots to avoid breaking running applications during rotation
15. Can you share a ConfigMap across namespaces?

Expected answer points:

  • No — ConfigMaps are namespace-scoped resources
  • To share a ConfigMap across namespaces, you must create identical ConfigMaps in each namespace
  • Operators can replicate ConfigMaps across namespaces if needed
  • Consider an external config store if you need true cross-namespace shared configuration
16. How do you use subPath in a ConfigMap volume mount and what are its limitations?

Expected answer points:

  • subPath allows mounting a single key from a ConfigMap as a specific file without exposing all keys
  • It is useful for mounting config files that conflict with the directory structure of the container
  • The major limitation is that when using subPath, the application does not receive automatic updates when the ConfigMap changes — the pod must be restarted
  • subPath bypasses symlink updates that work with regular volume mounts, making it unsuitable for frequently-updated configuration
17. What are immutable ConfigMaps and when would you use them?

Expected answer points:

  • Set `immutable: true` in the ConfigMap spec to prevent any changes after creation
  • Immutable ConfigMaps have significant performance benefits — Kubernetes skips synchronization for ConfigMaps that cannot change
  • Use for configuration that must never change at runtime (security policies, feature flags, environment defaults)
  • If you need to change an immutable ConfigMap, you must delete and recreate it — there is no update operation
18. How does the size limit of 1MB for ConfigMaps and Secrets affect design decisions?

Expected answer points:

  • 1MB is the total size limit for both ConfigMaps and Secrets — large configurations must be split across multiple resources
  • For application configs exceeding 1MB, consider storing them in object storage (S3, GCS) and pulling at startup or via init container
  • For TLS certificates or binary assets, use `binaryData` field with base64 encoding, but be aware of base64 overhead (~33%)
  • Large ConfigMaps impact etcd performance and kube-apiserver response times — keep ConfigMaps small
19. What is the difference between merging configuration via multiple envFrom declarations versus mounting multiple ConfigMap volumes?

Expected answer points:

  • Multiple `envFrom` entries with different ConfigMaps merge all keys into environment variables — if keys conflict, one overwrites the other (order matters)
  • Multiple volume mounts from different ConfigMaps create separate files in different directories — no merge, no conflict
  • Volume mounts allow files to be updated dynamically; env vars do not update after pod start
  • For config that needs to be updated at runtime, use volumes; for static initialization values, use env vars
20. How do you combine ConfigMaps and Secrets in the same volume mount for a twelve-factor application?

Expected answer points:

  • You can mount both ConfigMaps and Secrets as volumes in the same container, giving the application a unified `/etc/config` or `/run/secrets` directory structure
  • Use projected volumes to combine multiple ConfigMaps and Secrets into a single mount point with specific file permissions
  • Projected volumes allow you to map specific keys from each resource to specific file names, controlling exactly what the application sees
  • This approach separates non-sensitive configuration (ConfigMap) from sensitive data (Secret) while presenting them in a unified file-based interface

Further Reading

Conclusion

Use this checklist when managing ConfigMaps and Secrets:

  • Used ConfigMaps for non-sensitive configuration, Secrets for credentials and keys
  • Mounted ConfigMaps as volumes for configuration files and dynamic updates
  • Injected ConfigMap values as environment variables only for static configuration
  • Enabled encryption at rest for etcd to protect Secret data
  • Used RBAC to restrict who can read Secrets
  • Used External Secret Operators for production workloads requiring audit trails
  • Tested application behavior when ConfigMap or Secret values change at runtime
  • Used binaryData field for non-UTF8 secret content
  • Never committed Secret values to version control
  • Used depends_on or ordering tools to ensure Secrets exist before Pods start

Category

Related Posts

Kustomize: Native Kubernetes Configuration Management

Use Kustomize for declarative Kubernetes configuration management without Helm's templating—overlays, patches, and environment-specific customization.

#kubernetes #kustomize #devops

Container Security: Image Scanning and Vulnerability Management

Implement comprehensive container security: from scanning images for vulnerabilities to runtime security monitoring and secrets protection.

#container-security #docker #kubernetes

Deployment Strategies: Rolling, Blue-Green, and Canary Releases

Compare and implement deployment strategies—rolling updates, blue-green deployments, and canary releases—to reduce risk and enable safe production releases.

#deployment #devops #kubernetes