ConfigMap 基础:概念、创建与更新

各位好,今天我们聊聊 ConfigMap。这东西说白了,就是 Kubernetes 里用来存配置的。你想想看,以前我们部署应用,配置要么写死在代码里,要么挂在环境变量里,改一次就得重新打包镜像,多麻烦。

ConfigMap 就是来解决这个问题的。它把配置和容器镜像解耦了。我刚开始接触 K8s 时,觉得这玩意儿不就是个键值对存储吗?后来在项目中踩过坑才明白,它的设计其实挺讲究的。

ConfigMap 是什么?

ConfigMap 是 Kubernetes 的一种 API 对象。它专门用来存储非机密性的配置数据。比如应用端口号、日志级别、数据库地址这些。

它的核心作用就两个:

  • 配置与镜像分离:同一个镜像,挂不同的 ConfigMap,就能跑出不同的行为
  • 动态更新:改了 ConfigMap,Pod 里挂载的文件会自动更新(虽然进程不一定热加载)

重要提醒:ConfigMap 存的是明文数据。密码、密钥、Token 这些敏感信息,千万别放进去!那是 Secret 的活儿。

创建 ConfigMap 的几种方式

我个人习惯用 kubectl create configmap 命令。它有三种常用模式,咱们一个一个看。

1. 从字面量创建(--from-literal)

这种方式最简单。适合测试或少量配置。

kubectl create configmap app-config \
  --from-literal=APP_PORT=8080 \
  --from-literal=LOG_LEVEL=debug

嗯,这里要注意:键值对之间用等号连接,多个参数就重复写 --from-literal。我刚开始时老忘记这个,结果只传了一个参数进去,排查了半天才发现。

2. 从文件创建(--from-file)

这个我用的最多。项目里配置通常都写在文件里,比如 application.ymlnginx.conf 这些。

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

如果你不指定键名,默认就用文件名作为键。比如:

kubectl create configmap app-config \
  --from-file=./config/

这样会把 config/ 目录下所有文件都加进去。每个文件名就是键,文件内容就是值。

我的经验:从目录创建时,注意文件编码。我遇到过 Windows 下编辑的配置文件,换行符是 CRLF,结果容器里解析报错。建议统一用 LF。

3. 从环境变量文件创建(--from-env-file)

这种方式适合批量导入环境变量。文件格式就是 KEY=VALUE,一行一个。

# 先准备一个 .env 文件
echo "DB_HOST=localhost" > app.env
echo "DB_PORT=3306" >> app.env

# 然后创建
kubectl create configmap db-config \
  --from-env-file=app.env

注意:这个模式会把整个文件解析成多个键值对,而不是把文件本身当做一个值。跟 --from-file 有本质区别。

查看 ConfigMap

创建完了,怎么确认对不对?用 kubectl getkubectl describe

# 列出所有 ConfigMap
kubectl get configmap

# 查看详细信息
kubectl describe configmap app-config

如果想看完整的数据内容,用 -o yaml 导出:

kubectl get configmap app-config -o yaml

输出大概长这样:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: default
data:
  APP_PORT: "8080"
  LOG_LEVEL: debug

看到 data 字段了吗?里面就是咱们存的配置。键值对都在这里。

更新 ConfigMap

配置不可能一成不变。更新 ConfigMap 有两种方式。

方式一:直接编辑

kubectl edit configmap app-config

这会打开默认编辑器(通常是 vi),改完保存就行。适合小改动。

方式二:重新创建

我更喜欢这种方式,尤其是配置来自文件时:

# 先删除旧的
kubectl delete configmap app-config

# 再创建新的
kubectl create configmap app-config \
  --from-literal=APP_PORT=9090 \
  --from-literal=LOG_LEVEL=info

注意:ConfigMap 更新后,已经运行的 Pod 不会自动重新加载。除非你挂载的是 Volume,文件会更新(但进程不一定会热加载)。我曾经因为这个坑,改了配置后应用还是旧行为,排查了半天才发现 Pod 没重启。

解决办法?要么手动重启 Pod,要么用一些工具(比如 Reloader)监听 ConfigMap 变化自动滚动更新。

实战小贴士

最后分享几个我踩过的坑:

  • 命名规范:ConfigMap 的名字要见名知意。别用 config1config2 这种,三个月后你自己都看不懂。
  • 大小限制:ConfigMap 的数据大小不能超过 1MB。这是 etcd 的限制。配置太大?考虑用其他方案。
  • 命名空间隔离:ConfigMap 是命名空间级别的。不同命名空间里的同名 ConfigMap 互不影响。

好了,ConfigMap 的基础就这些。说白了就是存配置的,创建、查看、更新,三板斧。下一节咱们聊聊怎么把 ConfigMap 挂载到 Pod 里用,那才是真正发挥它价值的地方。