第32篇 k8s 之 配置管理:ConfigMap 详解
IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章,助你少走弯路。
在之前的文章中,我们通过环境变量向容器传递配置——REDIS_HOST=redis-service、FLASK_ENV=production。这种方式在第 13 篇 Compose 环境变量管理中已经熟悉了。但当配置项越来越多(几十个甚至上百个)、需要挂载整个配置文件、或者需要在多个 Pod 之间共享同一份配置时,环境变量就显得力不从心了。
Kubernetes 为此提供了专门的配置管理对象——ConfigMap。它用来存储非敏感的键值对配置,可以注入为环境变量、挂载为文件,或者作为命令行参数。与之对应的是Secret(第 33 篇主题),用于存储密码、密钥等敏感信息。今天这篇,我们就把 ConfigMap 的创建、注入、更新策略彻底搞清楚,并把它应用到贯穿案例的 Flask + Redis 应用中,将之前硬编码的配置迁移出来。
一、ConfigMap 是什么?解决什么痛点?
ConfigMap 是 K8s 中用来存储非敏感配置的 API 对象。它本质上是一个键值对集合,键是配置项名称,值可以是简单的字符串,也可以是一整个配置文件的内容。
它的核心价值是将配置与镜像解耦——镜像只包含应用代码和运行时,不同环境(开发、测试、生产)的差异化配置通过 ConfigMap 在运行时注入,无需为每个环境重新构建镜像。这和 Compose 中的env_file+.env文件的组合用法思想一致,但 ConfigMap 更进一步:它不依赖文件位置,可以在多个 Pod 之间共享,可以作为独立资源进行版本管理,并且可以与 Deployment、Service 等 K8s 对象协同使用。
先明确一个概念:ConfigMap vs Secret。ConfigMap 用于非敏感配置(如日志级别、服务端口、功能开关),Secret 用于敏感信息(密码、API 密钥、TLS 证书)。两者在创建和使用方式上高度相似——Secret 也支持以环境变量或文件挂载的方式注入 Pod。本篇聚焦 ConfigMap,第 33 篇将专门讲解 Secret 的安全实践。
二、创建 ConfigMap 的四种方式
2.1 从字面量创建
最直接的方式,适合少量配置项:
kubectl create configmap flask-config\--from-literal=FLASK_ENV=production\--from-literal=LOG_LEVEL=warn\--from-literal=REDIS_HOST=redis-service输出:
configmap/flask-config createdkubectl get configmap flask-configNAME DATA AGE flask-config310sDATA=3表示这个 ConfigMap 包含 3 个键值对。查看详细内容:
kubectl describe configmap flask-configName: flask-config Namespace: default Data====FLASK_ENV: ---- production LOG_LEVEL: ---- warn REDIS_HOST: ---- redis-service2.2 从文件创建
如果配置以文件形式存在,比如一个 JSON 配置文件app-config.json:
{"flask_env":"production","log_level":"warn","redis_host":"redis-service"}kubectl create configmap flask-config-file\--from-file=app-config.jsonK8s 会用文件名作为键(app-config.json),文件内容作为值。也可以指定自定义键名:
kubectl create configmap flask-config-custom\--from-file=config=app-config.json这样键名就是config。
2.3 从目录创建
如果一个目录下有多个配置文件:
mkdirconfig-direcho"production">config-dir/FLASK_ENVecho"redis-service">config-dir/REDIS_HOST kubectl create configmap flask-config-dir\--from-file=config-dir/每个文件名成为一个键,文件内容成为对应的值。
2.4 声明式 YAML(推荐)
命令行创建适合快速测试。生产环境中,推荐使用声明式 YAML,便于纳入 Git 管理和 CI/CD 流程:
apiVersion: v1 kind: ConfigMap metadata: name: flask-config-yaml data: FLASK_ENV:"production"LOG_LEVEL:"warn"REDIS_HOST:"redis-service"REDIS_PORT:"6379"kubectl apply-fflask-configmap.yamlYAML 方式支持kubectl diff(kubectl diff -f flask-configmap.yaml),在实际修改 ConfigMap 之前预览变更差异,避免意外覆盖。
三、将 ConfigMap 注入 Pod
创建好 ConfigMap 后,有三种方式将其注入容器:环境变量、文件挂载、命令行参数。
3.1 注入为环境变量
这是最接近第 13 篇 Composeenvironment的方式。可以将 ConfigMap 中的一个键注入为一个环境变量:
env: - name: FLASK_ENV valueFrom: configMapKeyRef: name: flask-config-yaml key: FLASK_ENV也可以将整个 ConfigMap 的所有键值对一次性注入为环境变量(键名自动转为环境变量名):
envFrom: - configMapRef: name: flask-config-yaml3.2 挂载为文件
这是 ConfigMap 最强大的用法——将一个或多个配置项作为文件挂载到容器内指定路径。容器内的应用可以直接读取文件来获取配置:
volumes: - name: config-volume configMap: name: flask-config-yaml containers: - name: flask volumeMounts: - name: config-volume mountPath: /app/config挂载后,/app/config/目录下会为每个键生成一个同名文件。验证:
kubectlexec<pod-name>--ls/app/config# FLASK_ENV LOG_LEVEL REDIS_HOST REDIS_PORTkubectlexec<pod-name>--cat/app/config/FLASK_ENV# production3.3 作为命令行参数
ConfigMap 的值也可以注入为容器的启动参数:
command:["python","app.py"]args: -"--log-level=$(LOG_LEVEL)"env: - name: LOG_LEVEL valueFrom: configMapKeyRef: name: flask-config-yaml key: LOG_LEVEL四、实战:为 Flask + Redis 迁移配置
现在把贯穿案例中的硬编码配置迁移到 ConfigMap。
4.1 创建 ConfigMap
apiVersion: v1 kind: ConfigMap metadata: name: flask-counter-config data: FLASK_ENV:"production"LOG_LEVEL:"info"REDIS_HOST:"redis-service"REDIS_PORT:"6379"kubectl apply-fflask-config.yaml4.2 更新 Deployment 使用 ConfigMap
apiVersion: apps/v1 kind: Deployment metadata: name: flask-deployment spec: replicas:3selector: matchLabels: app: flask-counter template: spec: containers: - name: flask image: flask-redis-counter:2.0 ports: - containerPort:5000envFrom: - configMapRef: name: flask-counter-config startupProbe: httpGet: path: /health port:5000periodSeconds:5failureThreshold:12livenessProbe: httpGet: path: /health port:5000periodSeconds:15failureThreshold:3readinessProbe: httpGet: path: /health port:5000periodSeconds:5failureThreshold:2envFrom.configMapRef将flask-counter-config中的所有键值对作为环境变量注入容器。Flask 应用通过os.environ.get('FLASK_ENV')读取这些变量——完全不需要修改app.py。
kubectl apply-fflask-deployment.yaml验证环境变量注入:
kubectlexecdeploy/flask-deployment --env|grep-E"FLASK_ENV|LOG_LEVEL|REDIS_HOST"# FLASK_ENV=production# LOG_LEVEL=info# REDIS_HOST=redis-service# REDIS_PORT=6379验证服务正常运行:
curlhttp://$(minikubeip)/counter# Hello World! I have been seen 1 times.4.3 注入 Nginx 配置文件(文件挂载示例)
如果你的 Flask 应用前端有一个 Nginx Sidecar,可以通过 ConfigMap 注入 Nginx 配置:
apiVersion: v1 kind: ConfigMap metadata: name: nginx-config data: nginx.conf:|server{listen80;location /{proxy_pass http://127.0.0.1:5000;}location /health{return200'{"status":"ok"}';}}在 Pod 中挂载:
containers: - name: nginx image: nginx:alpine volumeMounts: - name: nginx-config-volume mountPath: /etc/nginx/conf.d volumes: - name: nginx-config-volume configMap: name: nginx-configNginx 容器启动时会读取/etc/nginx/conf.d/nginx.conf,使用 ConfigMap 中的配置。修改 ConfigMap 中的配置,Nginx 需要 reload 才能生效(关于热更新,见下文)。
五、ConfigMap 的更新与热重载
ConfigMap 更新后,通过不同方式注入的配置有不同的生效行为:
5.1 触发滚动更新
如果修改了作为环境变量注入的 ConfigMap,需要触发 Deployment 滚动更新让 Pod 重建并获取新值:
kubectl rollout restart deployment/flask-deploymentrollout restart会触发一次滚动更新(第 26 篇学过的机制),所有 Pod 逐步重建,新 Pod 读取最新的 ConfigMap 值。生产环境中,通常将 ConfigMap 版本号作为 Pod 注解,配合 CI/CD 自动触发更新。
5.2 Immutable ConfigMap
从 K8s v1.21 起,可以将 ConfigMap 设置为不可变(immutable),这对于大规模集群有显著的性能优势——kubelet 不需要持续监控 ConfigMap 的变化:
apiVersion: v1 kind: ConfigMap metadata: name: immutable-config immutable:truedata: KEY:"value"一旦创建为 immutable,就不能再修改其内容。如果需要变更,只能删除旧 ConfigMap 并创建新的。
六、ConfigMap vs Docker Compose 配置管理
回顾第 13 篇,Compose 通过.env文件和环境变量实现配置管理。对比一下:
七、命令速查表
八、本篇总结
ConfigMap 的本质:K8s 原生的非敏感配置管理 API 对象,实现配置与镜像的解耦。
创建方式:字面量、文件、目录、YAML。YAML 是生产环境的推荐方式。
注入方式:环境变量(适合简单配置)、文件挂载(适合复杂配置文件,支持热更新)、命令行参数(适合启动参数)。
更新策略:环境变量注入需重启 Pod,文件挂载支持自动同步(kubelet 定期刷新),不可变 ConfigMap 可提升集群性能。
与 Compose 的区别:ConfigMap 是 K8s 的独立资源对象,支持多 Pod 共享、版本追踪、热更新,是配置管理从“文件驱动”到“API 驱动”的升级。
本篇解决了非敏感配置的管理问题。但对于密码、API 密钥、TLS 证书等敏感信息,明文 ConfigMap 显然不够安全。下一篇——第 33 篇:敏感信息管理:Secret 与安全实践,我们将学习 K8s 的 Secret 对象,以及如何使用 Sealed Secrets 实现 GitOps 安全的密钥管理。
想了解更多还可以去各个平台搜索「IT策士」,一起升级 IT 思维 !
