首页 / Kubernetes (k8s) 入门教程 / ConfigMap

Kubernetes (k8s) 入门教程

ConfigMap

本教程共 65 篇 · 第 32 篇 · 更新于 2026-08-14 · 约 9 分钟阅读

KubernetesConfigMap配置管理kubectl环境变量

本节目标:搞清楚 ConfigMap 是干什么的,会用两种主流方式把它喂给容器,知道什么数据不该放进去,以及”不可变”配置能帮你避开哪些麻烦。

你写完代码打包成镜像,里面却写死了数据库地址。换一个环境部署,就得重新打一遍包。这种事我早年没少干,后来才知道这叫”配置和代码耦合”。Kubernetes 给出的解法是 ConfigMap(配置映射)。

它就是一个存键值对的 API 对象。你可以把配置数据单独放进去,再让 Pod 去引用。镜像还是那个镜像,换环境只换 ConfigMap,不必重新构建。

32-1 ConfigMap 到底是什么

ConfigMap 跟大多数 Kubernetes 对象不一样,它没有 spec 字段。它只有 databinaryData 两个地方存数据。

data 里放 UTF-8 字符串,binaryData 里放 base64 编码的二进制。大多数时候你用 data 就够了。每个键名只能由字母、数字、-_. 组成。

Note

ConfigMap 不提供任何加密或保密能力。它只是把配置存起来,谁有 API 权限谁就能看。要存密码、令牌这类机密,请直接看下一章的 Secret。

还有一条要记牢:单个 ConfigMap 存的数据不能超过 1 MiB。如果你要放一大坨配置,老老实实挂个卷或者用别的存储方案,别硬塞。

32-2 怎么创建 ConfigMap

最省事的办法是用命令行。比如把环境变量式的配置直接生成出来:

kubectl create configmap game-demo \
  --from-literal=player_initial_lives=3 \
  --from-literal=ui_properties_file_name=user-interface.properties

也可以用文件生成,把现成的配置文件内容整段塞进去:

kubectl create configmap game-demo --from-file=game.properties

当然也能写 YAML。下面这个例子把”单行属性”和”整段配置”混在一起放:

apiVersion: v1
kind: ConfigMap
metadata:
  name: game-demo
data:
  player_initial_lives: "3"
  ui_properties_file_name: "user-interface.properties"
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true

这里 game.properties 的值看着像一整个文件,但其实它本质还是个字符串。ConfigMap 不区分单行还是多行,关键看 Pod 怎么消费它。

Tip

--from-file 时,键名默认就是文件名。想换个键名,可以写成 --from-file=mykey=game.properties,这样键就成了 mykey

32-3 用环境变量注入容器

这是最常见的接法。Pod 里的容器通过 valueFrom.configMapKeyRef 拿到某个键的值:

apiVersion: v1
kind: Pod
metadata:
  name: env-configmap
spec:
  containers:
  - name: envars-test-container
    image: nginx
    env:
    - name: CONFIGMAP_USERNAME
      valueFrom:
        configMapKeyRef:
          name: myconfigmap
          key: username

上面的意思是:从 myconfigmap 里取 username 这个键,放进容器环境变量 CONFIGMAP_USERNAME。环境变量名可以跟键名不一样,这点挺灵活。

如果你懒得一个个列,可以用 envFrom 把整个 ConfigMap 一次性展开成环境变量:

envFrom:
- configMapRef:
    name: myconfigmap
Warning

用环境变量方式引用的 ConfigMap,更新后不会自动刷新到容器里。要生效得重启 Pod。这一点经常被新手忽略,改了配置发现没变,多半是卡在这。

32-4 用卷挂载进容器

另一种方式更稳。把 ConfigMap 当成一个只读卷挂进去,每个键变成挂载目录下的一个文件,文件名就是键名。

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    configMap:
      name: myconfigmap

容器启动后,在 /etc/foo 目录下就能看到以键名命名的文件,读取它们就是读取配置。

这种方式有个大优点:ConfigMap 改了之后,kubelet 会周期性地把新内容同步进挂载的卷。容器下次读文件,拿到的就是新值。不过同步有延迟,取决于 kubelet 的同步周期和缓存策略,不是秒级生效。

Note

如果你用 subPath 把某个键单独挂成一个文件,那这个容器收不到更新。要用自动更新,就别用 subPath,挂整个目录。

32-5 不可变 ConfigMap 与边界

从 v1.19 起,ConfigMap 支持标记为”不可变”。你只要在对象里加一行:

immutable: true

设成不可变后,这个 ConfigMap 的数据就再也改不了,只能删除重建。好处有两个:一是防止手滑改错配置把应用搞挂;二是集群里上万个 ConfigMap 时,关掉监听能明显降低 API 服务器压力。

最后划一下边界。ConfigMap 适合放不敏感的配置:功能开关、日志级别、服务地址、配置文件片段。密码、证书、令牌请交给 Secret。静态 Pod 不能引用 ConfigMap,这点也要记住。