4. ConfigMap 基础:ConfigMap 是什么?创建方式(命令行、YAML、文件)

好,咱们进入正题。这一章聊的是 ConfigMap,说白了就是 K8s 里用来存配置的「小仓库」。你想想看,一个 vLLM 推理服务跑起来,需要多少参数?模型路径、GPU 数量、最大并发数、日志级别……这些要是硬编码在镜像里,每次改个参数都得重新打包、推送、部署,那运维效率就太低了。

ConfigMap 就是来解决这个问题的。它把配置和镜像解耦,让你能灵活地管理这些参数。我个人习惯把 ConfigMap 看作是「配置的声明」,你只管定义好,Pod 启动时去引用就行。

ConfigMap 到底是什么?

简单说,ConfigMap 是一个 K8s 资源对象,用来存储非敏感性的配置数据。它本质上就是一组键值对(key-value)。你可以把它挂载到 Pod 里作为环境变量,也可以作为文件挂载到容器里。

我在项目中遇到过一种情况:团队里有人把数据库密码也放进了 ConfigMap,结果被审计发现了。这里要特别提醒:ConfigMap 不适合存敏感信息,密码、密钥这些请用 Secret。ConfigMap 的数据是明文存储的,没有加密机制。

核心要点:

  • ConfigMap 是键值对存储
  • 用于非敏感配置
  • 数据大小限制为 1MB(etcd 的限制)
  • Pod 可以引用 ConfigMap 作为环境变量或文件

创建 ConfigMap 的三种方式

嗯,这里要注意,创建 ConfigMap 的方式有好几种。我按使用频率从高到低给你捋一遍。

方式一:命令行创建(kubectl create configmap)

这种方式最快,适合临时测试或快速验证。我经常在调试 vLLM 参数时用这个。

# 从字面量创建
kubectl create configmap vllm-config \
  --from-literal=model_name=llama-3-8b \
  --from-literal=max_num_batched_tokens=4096 \
  --from-literal=gpu_memory_utilization=0.9

# 从文件创建
kubectl create configmap vllm-config \
  --from-file=./vllm_params.conf

# 从目录创建(目录下所有文件都会成为 key)
kubectl create configmap vllm-config \
  --from-file=./config-dir/

# 从环境变量文件创建(.env 格式)
kubectl create configmap vllm-config \
  --from-env-file=./app.env

这里有个坑:--from-env-file 只支持 KEY=VALUE 格式,不支持注释(# 开头的行会被忽略)。我曾经因为 env 文件里写了注释,结果配置没生效,排查了半天才发现。

我的习惯:命令行创建适合快速验证,但生产环境我建议用 YAML 文件管理,方便版本控制和代码审查。

方式二:YAML 文件创建

这是最推荐的方式,尤其是团队协作时。YAML 文件可以提交到 Git 仓库,方便追踪变更。

apiVersion: v1
kind: ConfigMap
metadata:
  name: vllm-config
  namespace: default
data:
  # 键值对形式
  model_name: "llama-3-8b"
  max_num_batched_tokens: "4096"
  gpu_memory_utilization: "0.9"
  
  # 多行文本(用 | 保留换行)
  startup_script: |
    #!/bin/bash
    echo "Starting vLLM server..."
    python -m vllm.entrypoints.openai.api_server \
      --model /models/llama-3-8b \
      --tensor-parallel-size 2
  
  # 配置文件内容(用 |- 去掉末尾换行)
  logging.conf: |-
    [loggers]
    keys=root
  
  # 二进制文件(base64 编码)
  # 注意:二进制文件建议用 Secret 或单独存储

创建命令很简单:

kubectl apply -f vllm-config.yaml

为什么我推荐 YAML?因为你可以用 kubectl diff 对比变更,用 kubectl annotate 加备注,用 Git 做版本管理。说白了,这才是正经的运维姿势。

方式三:从文件创建

这种方式适合你已经有了现成的配置文件,不想手动转成 YAML。比如 vLLM 的启动参数文件:

# vllm_params.conf
model_name=llama-3-8b
max_num_batched_tokens=4096
gpu_memory_utilization=0.9
tensor_parallel_size=2
trust_remote_code=true

然后执行:

kubectl create configmap vllm-config \
  --from-file=vllm_params.conf

这样创建的 ConfigMap,key 就是文件名(vllm_params.conf),value 就是文件内容。如果你有多个文件,每个文件都会成为一个 key。

注意:当从文件创建时,文件名会成为 key。如果文件名包含特殊字符(如点号、连字符),在作为环境变量引用时可能会出问题。我建议文件名只用字母、数字和下划线。

ConfigMap 的数据结构

咱们用一张图来理解 ConfigMap 的内部结构:

ConfigMap apiVersion: v1, kind: ConfigMap metadata name: vllm-config namespace: default data (键值对) model_name: "llama-3-8b" gpu_memory_utilization: "0.9" 作为环境变量 envFrom / valueFrom 作为文件挂载 volumes / volumeMounts Pod 引用 ConfigMap

这张图展示了 ConfigMap 的核心结构:metadata 标识身份,data 存储配置,Pod 通过环境变量或文件挂载来使用。说白了,它就是配置的「中间人」。

ConfigMap 的命名规范

命名这块,K8s 要求 DNS 子域名格式:

  • 长度不超过 253 个字符
  • 只能包含小写字母、数字、连字符(-)和点号(.)
  • 必须以字母或数字开头和结尾

我个人的命名习惯是:<应用名>-config<应用名>-<环境>-config。比如 vLLM 项目,我会用 vllm-configvllm-prod-config。这样一眼就能看出是哪个应用的配置。

ConfigMap 的局限性

嗯,这里要泼点冷水。ConfigMap 虽然好用,但不是万能的:

限制项 说明
数据大小 单个 ConfigMap 最大 1MB(etcd 限制)
安全性 数据明文存储,不适合敏感信息
更新延迟 挂载为文件时,更新有延迟(kubelet 同步周期)
环境变量 已运行的 Pod 不会自动更新环境变量

我曾经踩过一个坑:ConfigMap 更新后,Pod 里挂载的文件确实更新了,但进程没重启,配置没生效。后来我加了 reload 机制或者用 kubectl rollout restart 才解决。

实战建议

给 vLLM 项目的一些建议:

  • 把模型路径、GPU 参数、并发数等高频变更的配置放 ConfigMap
  • 把 API 密钥、数据库密码等敏感信息放 Secret
  • 用 YAML 文件管理 ConfigMap,提交到 Git 仓库
  • ConfigMap 更新后,记得重启 Pod 或使用热加载机制

好了,这一章的内容就这些。ConfigMap 是 K8s 配置管理的基石,掌握了它,你就能灵活地管理 vLLM 的各种参数了。下一章咱们聊聊怎么把 ConfigMap 挂载到 Pod 里,以及环境变量和文件挂载的区别。


公众号:蓝海资料掘金营,微信deep3321