当前位置: 首页 > news >正文

第32篇 k8s 之 配置管理:ConfigMap 详解

IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章,助你少走弯路。


在之前的文章中,我们通过环境变量向容器传递配置——REDIS_HOST=redis-serviceFLASK_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 created
kubectl get configmap flask-config
NAME DATA AGE flask-config310s

DATA=3表示这个 ConfigMap 包含 3 个键值对。查看详细内容:

kubectl describe configmap flask-config
Name: flask-config Namespace: default Data====FLASK_ENV: ---- production LOG_LEVEL: ---- warn REDIS_HOST: ---- redis-service

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

K8s 会用文件名作为键(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.yaml

YAML 方式支持kubectl diffkubectl 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-yaml

3.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# production

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

4.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:2

envFrom.configMapRefflask-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-config

Nginx 容器启动时会读取/etc/nginx/conf.d/nginx.conf,使用 ConfigMap 中的配置。修改 ConfigMap 中的配置,Nginx 需要 reload 才能生效(关于热更新,见下文)。

五、ConfigMap 的更新与热重载

ConfigMap 更新后,通过不同方式注入的配置有不同的生效行为:

5.1 触发滚动更新

如果修改了作为环境变量注入的 ConfigMap,需要触发 Deployment 滚动更新让 Pod 重建并获取新值:

kubectl rollout restart deployment/flask-deployment

rollout 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 思维 !

http://www.jsqmd.com/news/934088/

相关文章:

  • 7-7. 开题报告等文档资料学校会查重吗?
  • 深入QNX Screen:利用screencmd命令行工具调试与动态修改窗口属性
  • 【无】2000-2024年各省人力资本水平数据(含原始数据+计算过程+计算结果)
  • 毕设直用|Python版Paillier加密联邦聚合系统(带双端一键启动脚本)
  • PC屏保画报广告5月档无与伦比的夏日经济
  • 别再只盯着ACOS了!亚马逊广告报告里的ROAS、ACOAS、ASOAS,哪个才是你该关心的核心指标?
  • AI 编程浪潮下,Zig 等开源项目为何坚守「拒绝 AI 代码」?
  • imx6ull 开发板,手机,MQTT 物联网通信实验。
  • OpenHarmony 4.0 Release版源码下载后,你的50G硬盘里到底多了些什么?
  • 【Agent】OpenCode 接入 DeepSeek-V4-Pro 开启1M上下文 保姆级教程
  • 用Python动手推导:能量守恒、勾股定理与机器学习损失函数之间的奇妙联系
  • 数字信任技术全景:从密码学基础到隐私保护实战
  • DeepSeek LeetCode 2911. 得到 K 个半回文串的最少修改次数 TypeScript实现
  • 【智能制造】- APS系列|16 生产计划与生产排程:核心概念与分类
  • Java 集成 LibreOffice 实现离线文档转换:Windows 与 Linux 环境详解
  • 快放≠质量牺牲!Sora 2 v2.3实测数据:启用motion-aware upsampling后PSNR提升11.6dB,延迟降低43%
  • Iinux:网络编程
  • 当样本量太小怎么办?Fisher精确检验实战指南(附SPSS操作避坑点)
  • 从OpenCLIP到Qwen-7B:手把手拆解Qwen-VL的视觉-语言对齐‘三明治’架构
  • DISCOUNT: Counting in Large Image Collections with Detector-Based Importance Sampling
  • 微软音频技术三十年:从语音降噪到空间音频的演进与应用
  • UE5动画重定向保姆级教程:从IK绑定到导出,手把手教你让不同体型角色共享一套动作
  • Windows环境下OpenClaw本地部署完整指南
  • AI 编程大势下,Zig 等开源项目为何坚决拒绝 AI 代码贡献?
  • 深入大模型-42-大模型交互之前端代码详解JavaScript代码
  • 基于Azure云平台的海量多媒体智能检索系统架构与实践
  • 公司日常考勤系统毕业设计
  • 为什么你的回归测试一直靠经验?因为少了这条数据链路
  • 上电后MCU从哪开始执行?深入解析工业采集卡的BOOT启动配置电路
  • HTML+fastAPI+Dify|打通前后端至智能体的路