26 lines
16 KiB
JSON
26 lines
16 KiB
JSON
{
|
||
"schema_version": 1,
|
||
"saved_at": "2026-08-07T04:55:14.8755306Z",
|
||
"content_sha256": "cbc1e56cb3bd28810412a827ab388e573684e80add926c01fcd00eaa5f054f76",
|
||
"result": {
|
||
"title": "ConfigMaps \u0026 Secrets | The Kubernetes Visual Handbook",
|
||
"url": "https://k8s.info/docs/core/config-secrets",
|
||
"snippet": "Learn how to use Kubernetes ConfigMaps and Secrets to decouple configuration and sensitive data from container images, including creation methods, consumption patterns, and security best practices.",
|
||
"content": "On this page\n\nKey Takeaways for AI \u0026 Readers\n\nConfiguration Decoupling : Separate settings (ConfigMaps) and sensitive data (Secrets) from application code to maintain portability. Never bake passwords, API keys, or environment-specific configuration into container images.\n\nSecurity Awareness : Secrets are only Base64 encoded by default -- this is not encryption. True security requires enabling \"Encryption at Rest\" in the API server configuration and restricting RBAC access to Secret objects.\n\nUpdate Mechanisms : Changes to environment variables require a Pod restart, while changes to volume-mounted configs eventually propagate to the Pod's filesystem (typically within 30-60 seconds via the kubelet sync period).\n\nImmutability : Mark ConfigMaps and Secrets as immutable: true in production to prevent accidental changes, improve cluster performance, and force explicit redeployment when configuration changes.\n\nSize Limit : Both ConfigMaps and Secrets are limited to 1 MiB of data. For larger payloads, use external storage or init containers.\n\nDecoupling configuration from application code is a key principle of Cloud Native development. You should never bake passwords or config files into your Docker image. Kubernetes provides two first-class resources for this purpose: ConfigMaps for non-sensitive configuration and Secrets for sensitive data.\n\n1. ConfigMaps \n\nConfigMap (Yaml)\n\nPod Container\n\nRunning\n\n# env\n\nDB_HOST = db.prod.local\n\nLOG_LEVEL = info\n\nHOSTNAME=pod-x7z9\n\nHOME=/root\n\nNotice: When you change the ConfigMap, the Pod must often restart to pick up new Environment Variables.\n\nConfigMaps allow you to decouple configuration artifacts from image content to keep containerized applications portable. A ConfigMap stores key-value pairs of string data or binary data that can be consumed by Pods as environment variables, command-line arguments, or configuration files mounted as volumes.\n\nCreating ConfigMaps \n\nThere are several ways to create a ConfigMap:\n\nFrom Literal Values \n\nkubectl create configmap app-config \\\n--from-literal=DATABASE_HOST=postgres.default.svc \\\n--from-literal=DATABASE_PORT=5432 \\\n--from-literal=LOG_LEVEL=info\n\nFrom a File \n\n# Create from a single file\nkubectl create configmap nginx-config --from-file=nginx.conf\n\n# Create from a file with a custom key name\nkubectl create configmap nginx-config --from-file=main-config=nginx.conf\n\nFrom an Env File \n\n# app.env contains KEY=VALUE pairs, one per line\nkubectl create configmap app-config --from-env-file=app.env\n\nDeclarative YAML \n\napiVersion : v1\nkind : ConfigMap\nmetadata :\nname : app - config\nnamespace : default\ndata :\n# Simple key-value pairs\nDATABASE_HOST : \"postgres.default.svc\"\nDATABASE_PORT : \"5432\"\nLOG_LEVEL : \"info\"\n\n# Multi-line configuration file\napp.properties : |\nserver.port=8080\nserver.context-path=/api\nspring.datasource.url=jdbc:postgresql://postgres:5432/mydb\nspring.datasource.hikari.maximum-pool-size=10\nlogging.level.root=INFO\n\n# Another config file\nnginx.conf : |\nserver {\nlisten 80;\nserver_name localhost;\nlocation / {\nproxy_pass http://backend:8080;\n\nNote that all values in a ConfigMap's data field are strings. If you need to store binary data (like a TLS certificate or a compressed file), use the binaryData field, which accepts Base64-encoded values.\n\nConsuming ConfigMaps \n\nAs Environment Variables \n\napiVersion : v1\nkind : Pod\nmetadata :\nname : app\nspec :\ncontainers :\n- name : app\nimage : myapp : 1.0\nenv :\n# Reference individual keys\n- name : DB_HOST\nvalueFrom :\nconfigMapKeyRef :\nname : app - config\nkey : DATABASE_HOST\n- name : DB_PORT\nvalueFrom :\nconfigMapKeyRef :\nname : app - config\nkey : DATABASE_PORT\n# Or inject ALL keys as env vars at once\nenvFrom :\n- configMapRef :\nname : app - config\n\nWhen using envFrom , each key in the ConfigMap becomes an environment variable name, and the corresponding value becomes the environment variable value. Keys that are not valid environment variable names (e.g., containing dots or hyphens) are skipped.\n\nAs Volume Mounts \n\napiVersion : v1\nkind : Pod\nmetadata :\nname : app\nspec :\ncontainers :\n- name : app\nimage : myapp : 1.0\nvolumeMounts :\n- name : config - volume\nmountPath : /etc/config\nreadOnly : true\nvolumes :\n- name : config - volume\nconfigMap :\nname : app - config\n# Optionally select specific keys\nitems :\n- key : nginx.conf\npath : nginx.conf\n- key : app.properties\npath : application.properties\n\nEach key in the ConfigMap becomes a file inside /etc/config/ . The file name is the key, and the file contents are the value. You can use the items field to select specific keys and control the file names.\n\nAs Command Arguments \n\nspec :\ncontainers :\n- name : app\nimage : myapp : 1.0\ncommand : [ \"./start.sh\" ]\nargs : [ \"--log-level\" , \"$(LOG_LEVEL)\" ]\nenv :\n- name : LOG_LEVEL\nvalueFrom :\nconfigMapKeyRef :\nname : app - config\nkey : LOG_LEVEL\n\n2. Secrets \n\nSecrets are used to store small amounts of sensitive data such as passwords, OAuth tokens, SSH keys, and TLS certificates. They are structurally similar to ConfigMaps but have a few important differences:\n\nKubernetes can be configured to encrypt Secrets at rest in etcd (ConfigMaps are not encrypted).\n\nRBAC policies can restrict access to Secrets independently from ConfigMaps.\n\nSecrets are stored as Base64-encoded data in the data field (or plain text in the stringData field for convenience during creation).\n\nBase64 Encoding Warning \n\nBase64 is not encryption. It is a reversible encoding scheme that anyone can decode:\n\n# Encoding\necho -n \"my-super-secret-password\" | base64\n# Output: bXktc3VwZXItc2VjcmV0LXBhc3N3b3Jk\n\n# Decoding (trivial)\necho \"bXktc3VwZXItc2VjcmV0LXBhc3N3b3Jk\" | base64 -d\n# Output: my-super-secret-password\n\nAnyone with kubectl get secret -o yaml permissions can read all your Secrets in plain text. Base64 encoding exists only to allow binary data to be stored in YAML/JSON, not for security.\n\nSecret Types \n\nKubernetes supports several built-in Secret types:\n\nType\n\nDescription\n\nOpaque\n\nDefault type. Arbitrary user-defined key-value pairs.\n\nkubernetes.io/dockerconfigjson\n\nDocker registry credentials for pulling private images.\n\nkubernetes.io/tls\n\nTLS certificate and private key pair.\n\nkubernetes.io/basic-auth\n\nBasic authentication credentials (username and password).\n\nkubernetes.io/ssh-auth\n\nSSH private key.\n\nkubernetes.io/service-account-token\n\nService account token (auto-created by Kubernetes).\n\nCreating Secrets \n\nOpaque Secret (YAML) \n\napiVersion : v1\nkind : Secret\nmetadata :\nname : db - credentials\ntype : Opaque\n# Use stringData for plain text (Kubernetes encodes to Base64 automatically)\nstringData :\nusername : admin\npassword : \"s3cur3-p@ssw0rd!\"\nconnection-string : \"postgresql://admin:s3cur3-p%40ssw0rd!@postgres:5432/mydb\"\n\nUsing stringData is preferred over data because you provide plain-text values and Kubernetes handles the Base64 encoding. When you retrieve the Secret with kubectl get secret -o yaml , the values appear in the data field as Base64.\n\nDocker Registry Secret \n\nkubectl create secret docker-registry regcred \\\n--docker-server=https://registry.example.com \\\n--docker-username=deploy-bot \\\n--docker-password=ghp_xxxxxxxxxxxx \\\n[email protected]\n\nThen reference it in a Pod or ServiceAccount:\n\nspec :\nimagePullSecrets :\n- name : regcred\n\nTLS Secret \n\nkubectl create secret tls my-tls-cert \\\n--cert=path/to/cert.pem \\\n--key=path/to/key.pem\n\nConsuming Secrets \n\nSecrets are consumed in exactly the same way as ConfigMaps -- as environment variables or volume mounts:\n\napiVersion : v1\nkind : Pod\nmetadata :\nname : app\nspec :\ncontainers :\n- name : app\nimage : myapp : 1.0\nenv :\n- name : DB_USERNAME\nvalueFrom :\nsecretKeyRef :\nname : db - credentials\nkey : username\n- name : DB_PASSWORD\nvalueFrom :\nsecretKeyRef :\nname : db - credentials\nkey : password\nvolumeMounts :\n- name : tls - certs\nmountPath : /etc/tls\nreadOnly : true\nvolumes :\n- name : tls - certs\nsecret :\nsecretName : my - tls - cert\ndefaultMode : 0400 # Restrict file permissions\n\nWhen mounted as a volume, Secret files are stored in a tmpfs (RAM-backed filesystem) on the node, so they are never written to physical disk.\n\n3. Encryption at Rest \n\nBy default, Secrets are stored unencrypted in etcd. Anyone with direct access to etcd can read all Secrets in your cluster. To enable encryption, you must configure an EncryptionConfiguration on the API server:\n\napiVersion : apiserver.config.k8s.io/v1\nkind : EncryptionConfiguration\nresources :\n- resources :\n- secrets\nproviders :\n- aescbc :\nkeys :\n- name : key1\nsecret : \u003cbase64 - encoded - 32 - byte - key \u003e\n- identity : { } # Fallback to read unencrypted secrets\n\nFor production environments, consider using a KMS (Key Management Service) provider instead of static keys. Cloud providers offer KMS integration:\n\nAWS : AWS KMS with the KMS plugin\n\nGCP : Cloud KMS (enabled by default on GKE)\n\nAzure : Azure Key Vault with the KMS plugin\n\n4. Update Behavior: The Critical Difference \n\nUnderstanding how updates propagate is one of the most important aspects of ConfigMaps and Secrets:\n\nEnvironment Variables: No Automatic Update \n\nIf a ConfigMap or Secret is consumed as an environment variable , changing the ConfigMap or Secret has no effect on running Pods. Environment variables are injected at Pod startup and are never refreshed. You must restart (or recreate) the Pod to pick up changes:\n\n# Restart all Pods in a Deployment to pick up ConfigMap changes\nkubectl rollout restart deployment/my-app\n\nVolume Mounts: Eventually Consistent \n\nIf a ConfigMap or Secret is mounted as a volume , the kubelet periodically checks for updates and refreshes the mounted files. The update delay depends on:\n\nThe kubelet's syncFrequency (default: 1 minute)\n\nThe ConfigMap cache TTL\n\nIn practice, volume-mounted updates propagate within 30 to 90 seconds . Your application must be programmed to watch for file changes (using inotify or periodic file polling) to reload configuration without a Pod restart.\n\nImportant caveat : If you use subPath to mount a specific key to a specific file path, that file is never updated. This is a known limitation. Use a full directory mount or a projected volume instead.\n\n5. Immutable ConfigMaps and Secrets \n\nKubernetes allows you to mark ConfigMaps and Secrets as immutable :\n\napiVersion : v1\nkind : ConfigMap\nmetadata :\nname : app - config - v2\ndata :\nLOG_LEVEL : \"warn\"\nimmutable : true\n\nOnce set, the immutable field cannot be changed, and the data in the ConfigMap or Secret cannot be modified. You must create a new ConfigMap with a different name and update your Pods to reference it.\n\nBenefits of immutability:\n\nProtection against accidental changes : Prevents operators from accidentally breaking production by editing a live ConfigMap.\n\nPerformance : The kubelet does not need to watch immutable objects for changes, reducing API server load. In clusters with thousands of ConfigMaps, this makes a measurable difference.\n\nAuditability : Every configuration change results in a new object, creating a clear audit trail.\n\n6. Real-World Pattern: Versioned Configuration \n\nA common production pattern is to version your ConfigMaps and use Deployments to reference specific versions:\n\napiVersion : v1\nkind : ConfigMap\nmetadata :\nname : app - config - v3\nlabels :\napp : myapp\nversion : \"3\"\ndata :\nconfig.yaml : |\ndatabase:\nhost: postgres.prod.svc\nport: 5432\npool_size: 20\ncache:\nhost: redis.prod.svc\nttl: 300\nimmutable : true\n---\napiVersion : apps/v1\nkind : Deployment\nmetadata :\nname : myapp\nspec :\ntemplate :\nmetadata :\nannotations :\n# Forces a rolling update when config changes\nconfigmap-version : \"v3\"\nspec :\ncontainers :\n- name : myapp\nimage : myapp : 2.1.0\nvolumeMounts :\n- name : config\nmountPath : /etc/app\nreadOnly : true\nvolumes :\n- name : config\nconfigMap :\nname : app - config - v3\n\nWhen you need to change configuration, you create app-config-v4 , update the Deployment to reference it, and Kubernetes performs a rolling update. The old ConfigMap remains available for rollback.\n\n7. Common Pitfalls \n\nTreating Base64 as encryption : Base64 is encoding, not encryption. Anyone with read access to the Secret object can decode the values instantly. Always enable encryption at rest and restrict RBAC.\n\nStoring Secrets in Git : Never commit Secret YAML files with real credentials to version control. Use sealed-secrets, SOPS, or an external secrets manager (HashiCorp Vault, AWS Secrets Manager) to manage secrets in Git safely.\n\nForgetting the 1 MiB size limit : ConfigMaps and Secrets are limited to 1 MiB. For large configuration files, consider using an init container to download the file or mount a PersistentVolume.\n\nUsing subPath and expecting updates : Volume mounts using subPath do not receive automatic updates. If your application depends on live configuration reloading, use a full directory mount.\n\nExposing Secrets in logs or environment : Secrets consumed as environment variables can leak into logs, crash dumps, and debugging tools. Prefer volume mounts for sensitive data, and configure your application to read credentials from files rather than environment variables.\n\nNot restarting Pods after ConfigMap changes : If you update a ConfigMap consumed as an environment variable, running Pods still have the old values. Use kubectl rollout restart or tools like Reloader to automate Pod restarts.\n\n8. Best Practices \n\nUse stringData for Secret creation : It is less error-prone than manually Base64-encoding values in the data field.\n\nMark production ConfigMaps and Secrets as immutable: true : This prevents accidental modification and reduces kubelet load.\n\nRestrict RBAC access to Secrets : Use Role and RoleBinding to ensure only the Pods and ServiceAccounts that need Secrets can access them. Avoid granting cluster-wide Secret read access.\n\nUse external secrets managers for production : Tools like HashiCorp Vault, AWS Secrets Manager, or the External Secrets Operator provide audit logging, automatic rotation, and centralized management.\n\nUse volume mounts for files, env vars for simple",
|
||
"content_type": "text/html",
|
||
"query": "How to systematically identify Secrets in Kubernetes and container environments?",
|
||
"language": "en-US",
|
||
"round": 1,
|
||
"fetched": true,
|
||
"relevant": true,
|
||
"relevance": 0.5733333333333334,
|
||
"source_quality": "reputable_secondary",
|
||
"source_quality_score": 0.736,
|
||
"actionable": true,
|
||
"covered_gap_ids": [
|
||
"G1"
|
||
],
|
||
"assessment_reason": "Die Quelle beschreibt ConfigMaps und Secrets in Kubernetes, aber sie konzentriert sich hauptsächlich auf die Grundlagen und nicht auf die systematische Identifizierung von Secrets. Sie bietet zwar grundlegende Informationen, aber keine konkreten Schritte oder Lösungen zur systematischen Identifizierung von Secrets in Kubernetes und Container-Umgebungen."
|
||
}
|
||
}
|