ConfigMap

在做容器化应用的时候,为了适配开发、测试、生产三个环境,给同一个应用打了三个不同的镜像 ------ 就因为配置文件里的数据库地址、端口不一样? 改了一行配置,就要重新打包镜像、重新推仓库、重新部署

Kubernetes 的 ConfigMap可以解决这些问题


ConfigMap 是什么?

ConfigMap 就是 K8s 给我们提供的一个 "配置仓库",你可以把所有的配置(不管是单个的参数,还是一整个配置文件的内容)都存在这里,然后在 Pod 启动的时候,把这些配置注入到容器里,给应用用。

它最核心的作用,就是把配置和容器镜像彻底解耦: 你的镜像再也不用带配置了,同一个镜像,搭配不同的 ConfigMap,就能跑在不同的环境里 ------ 开发的时候用开发的 ConfigMap,测试用测试的,生产用生产的,镜像完全不用改,打包一次就能到处跑

当然它也有个小限制:单个 ConfigMap 的大小不能超过 1MB,毕竟它是存在 K8s 的 etcd 存储里的,太大的内容就别往这里塞了,用独立的存储或者配置中心更合适。


上手实操:ConfigMap 怎么用?

第一步:创建你的 ConfigMap

创建 ConfigMap 有两种常用的方式,看你的场景选:

1. 正式环境:用 YAML 文件创建

如果是生产环境,我推荐用 YAML 文件来写,这样你的配置可以纳入 git 版本控制,谁改了配置、改了啥,都能追溯,非常规范。

比如我们要给一个游戏应用存配置,先写一个game-config.yaml文件:

复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: game-demo
data:
  # 单个的小配置,直接写就行
  player_initial_lives: "3"
  ui_properties_file_name: "tomcat"
  # 如果是一整个配置文件的内容?用|符号就行,换行空格都能保留
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5
  • data部分就是我们的配置,是键值对的形式 ------ 你给每个配置起个名字(键),然后把配置的内容(值)填进去,应用要读的时候,通过名字就能拿到内容。

  • 单个的小配置就直接写,比如player_initial_lives: "3",就是告诉应用,玩家初始的生命数是 3。

  • 如果是一整个配置文件的内容,就用|符号,它会把后面的所有行都当成这个配置的内容,完全保留格式,应用直接就能当成配置文件读。

写完之后,执行一句命令就能创建了:

复制代码
kubectl create -f game-config.yaml
2. 临时测试:用命令行快速创建

如果是临时测个东西,不想写文件,直接用命令行就能快速建,有两种:

  • 直接写键值对:

    复制代码
    kubectl create configmap player --from-literal=username=test --from-literal=age=18

    一行命令就把两个配置存进去了

  • 直接把本地文件导进去: 如果你已经有写好的配置文件,直接把整个文件导进去就行:

    复制代码
    # 先写个测试的网页文件
    echo hello world! > index.html
    # 导入到ConfigMap里
    kubectl create configmap indexcontent --from-file=index.html

    执行完,这个文件的内容就完整存到 ConfigMap 里了,文件名就是配置的名字。

创建完之后,你可以用kubectl describe configmaps 名字查看配置是不是存对了,能看到所有的键和值,非常清楚。


第二步:把配置注入到 Pod 里

创建好 ConfigMap 之后,怎么让应用拿到这些配置?有两种常用的方式,看你的需求选。

1. 配置文件?用 Volume 挂载

如果你的配置是一整个文件,比如 nginx 的配置、应用的 properties 文件,那用 Volume 挂载最合适 ------ConfigMap 里的每个配置,都会变成挂载目录下的一个文件,应用直接读文件就行,完全不用改代码

比如我们把刚才的indexcontent这个 ConfigMap,挂载到 apache 的 Pod 里,让 apache 能读到这个网页:

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo
spec:
  containers:
  - name: web
    image: httpd
    volumeMounts:
    # 把名为index的卷,挂载到apache的网页根目录
    - name: index
      mountPath: /usr/local/apache2/htdocs
  volumes:
  # 定义这个卷的来源,就是我们的ConfigMap
  - name: index
    configMap:
      name: indexcontent

创建完 Pod 之后,访问 Pod 的 IP,你就能看到hello world!了 ------apache 直接就读到了 ConfigMap 里的文件,完全不用改镜像

这种方式还有个好处:如果你更新了 ConfigMap,挂载的文件会自动更新,应用不用重启就能拿到新配置(当然部分应用需要你通知它重读配置,不过这已经比重新打包镜像方便太多了)。

2. 启动参数 用环境变量注入

如果你的配置是单个的启动参数,比如数据库的地址、应用的开关,那用环境变量注入更方便 ------ 应用直接读环境变量就能拿到配置,很多镜像本身就是这么设计的。

比如我们给 MySQL 设置 root 密码,MySQL 的镜像本身就会读MYSQL_ROOT_PASSWORD这个环境变量当密码,我们把 ConfigMap 里的密码注入进去就行:

首先先建存密码的 ConfigMap:

复制代码
kubectl create configmap mysql-pw --from-literal=password=MySecurePass123

然后写 Pod 的配置:

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: mysql
spec:
  containers:
  - name: mysql
    image: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      # 这个环境变量的值,来自ConfigMap的某个键
      valueFrom:
        configMapKeyRef:
          name: mysql-pw
          key: password

创建完 Pod,MySQL 启动的时候,就自动把 ConfigMap 里的密码当成 root 密码了,直接就能用这个密码登录,完全不用把密码写死在镜像里。


1. 别把敏感密码存进 ConfigMap!

ConfigMap 里的所有内容都是明文的,任何人只要能访问这个 ConfigMap,就能看到里面的内容! 敏感的密码、密钥,一律用Secret!Secret 是加密存储的,专门用来存敏感信息的

2. 环境变量的配置不会自动更新!

如果你用环境变量的方式注入 ConfigMap,那你更新了 ConfigMap 之后,已经启动的 Pod 里的环境变量是不会变的!必须重启 Pod 才能生效! 只有用 Volume 挂载的方式,配置才会自动更新,这个一定要注意

3. ConfigMap 是有命名空间的!

ConfigMap 是属于命名空间的资源,你在 default 命名空间建的 ConfigMap,在另一个命名空间的 Pod 里是用不了的

4. 别往 ConfigMap 里塞大文件!

别忘了 1MB 的大小限制,大文件还是用存储卷吧。


总结

  1. 正式环境一律用 YAML 管理 ConfigMap,纳入 git 版本控制,别用命令行乱建,不然配置丢了你都不知道。

  2. 敏感配置永远用 Secret,别用 ConfigMap,安全第一。

  3. 配置文件用 Volume 挂载,启动参数用环境变量,按需选择,别搞混了。

  4. 需要热更新的配置,一定要用 Volume 挂载,不然改了配置不生效。

相关推荐
东北甜妹2 小时前
Docker 命令
云原生·eureka
倔强的胖蚂蚁3 小时前
Ollama 大模型参数调整
运维·人工智能·云原生
文静小土豆18 小时前
Java 应用上 K8s 全指南:从部署到治理的生产级实践
java·开发语言·kubernetes
努力搬砖的咸鱼18 小时前
Label 与 Selector:Kubernetes 资源选择的核心机制
微服务·云原生·容器·架构·kubernetes
Devin~Y1 天前
大厂Java面试实战:Spring Boot/WebFlux、Redis+Kafka、K8s可观测性与Spring AI RAG/Agent三轮连环问
java·spring boot·redis·kafka·kubernetes·resilience4j·spring webflux
立莹Sir1 天前
SaaS多租户资源隔离的云原生解决方案:在不单独部署的情况下实现租户级资源保障
云原生
密瓜智能1 天前
从 Device Plugin 到 DRA:GPU 调度范式升级与 HAMi-DRA 实践
人工智能·kubernetes·开源·密瓜智能
人道领域1 天前
GPT-5架构泄露?Kubernetes 1.31发布与Rust重构浪潮下的云原生之变
gpt·云原生·架构
刘~浪地球1 天前
云原生与容器--Service Mesh (Istio) 入门实战
云原生·istio·service_mesh