【K8s ConfigMap 配置管理创建、挂载与热更新实践】

提示:本文原创作品,良心制作,干货为主,简洁清晰,一看就会

文章目录


前言

在Kubernetes集群中,配置与应用解耦是云原生部署的关键实践。硬编码配置会导致镜像臃肿、环境适配困难,而ConfigMap正是解决这一问题的核心资源。它以键值对存储非敏感配置,支持环境变量、配置文件挂载等多种注入方式,实现配置集中管理与动态更新。本文将从原理、创建、使用到最佳实践,全面讲解ConfigMap的落地方法

一、ConfigMap介绍

ConfigMap 是 Kubernetes 中用于 存储非敏感配置信息 的核心资源,核心作用是 保存不需要加密的,应用所需的配置信息 ,让同一镜像可适配开发、测试、生产等不同环境,无需重新打包

它以 键值对 形式存放配置,可存储配置文件片段、环境变量、命令行参数等内容。创建后能通过环境变量注入、挂载为配置文件、命令行参数等方式供 Pod 使用,实现配置集中管理、灵活变更与统一分发,避免硬编码带来的维护难题,是云原生应用标准化配置的基础组件

二、ConfigMap创建

2.1 通过命令创建

yaml 复制代码
## 1. 直接在命令行中指定configmap
root@k8s-master1:~# kubectl create configmap test-configmap1 --from-literal=user=amdin --from-literal=pass=1234

# kube-root-ca.crt存储了k8s集群的根CA证书公钥,用于集群内的身份认证、加密通信
# K8s会自动把这个ConfigMap挂载到每一个新建的Pod里,让容器内的应用可以信任集群的证书,实现安全访问API Server等组件
root@k8s-master1:~# kubectl get configmap
NAME               DATA   AGE
kube-root-ca.crt   1      15d  # k8s集群自动创建的系统内置ConfigMap
test-configmap1    2      7s
root@k8s-master1:~# kubectl get configmap test-configmap1 -o yaml
apiVersion: v1
data:
  pass: "1234"
  user: amdin
kind: ConfigMap
metadata:
  creationTimestamp: "2026-04-23T06:11:32Z"
  name: test-configmap1
  namespace: default
  resourceVersion: "611852"
  uid: 5f136be4-bbb7-4f4e-8f4e-86e3fc675eab
yaml 复制代码
## 2. 将一个配置文件创建为configmap
root@k8s-master1:~# mkdir -p /k8s-test/configmap
root@k8s-master1:~# cd /k8s-test/configmap
root@k8s-master1:/k8s-test/configmap# vim app.properties
server.port=8080
database.url=jdbc:mysql://mysql:3306/test
redis.host=redis-service
log.level=info
root@k8s-master1:/k8s-test/configmap# kubectl create configmap test-configmap2 --from-file=app.properties
root@k8s-master1:/k8s-test/configmap# kubectl get configmap
NAME               DATA   AGE
kube-root-ca.crt   1      15d
test-configmap1    2      11m
test-configmap2    1      5s
root@k8s-master1:/k8s-test/configmap# kubectl get configmap test-configmap2 -o yaml  # 查看详细信息
apiVersion: v1
data:
  app.properties: |
    server.port=8080
    database.url=jdbc:mysql://mysql:3306/test
    redis.host=redis-service
    log.level=info
kind: ConfigMap
metadata:
  creationTimestamp: "2026-04-23T06:23:19Z"
  name: test-configmap2
  namespace: default
  resourceVersion: "613264"
  uid: f1d62b11-94e4-407e-aa18-4a50377cfe4f
root@k8s-master1:/k8s-test/configmap# 
yaml 复制代码
## 3. 将目录下的所有配置文件创建为configmap
root@k8s-master1:/k8s-test/configmap# mkdir config
root@k8s-master1:/k8s-test/configmap# echo 1111 > config/config1
root@k8s-master1:/k8s-test/configmap# echo 2222 > config/config2
root@k8s-master1:/k8s-test/configmap# kubectl create configmap test-configmap3 --from-file=config
configmap/test-configmap3 created
root@k8s-master1:/k8s-test/configmap# kubectl get configmap
NAME               DATA   AGE
kube-root-ca.crt   1      15d
test-configmap1    2      30m
test-configmap2    1      18m
test-configmap3    2      8s
root@k8s-master1:/k8s-test/configmap# kubectl get configmap test-configmap3 -o yaml
apiVersion: v1
data:
  config1: |
    1111
  config2: |
    2222
kind: ConfigMap
metadata:
  creationTimestamp: "2026-04-23T06:41:59Z"
  name: test-configmap3
  namespace: default
  resourceVersion: "615507"
  uid: 137fbc97-3458-4279-84f3-97178a655029

2.2 通过yaml文件创建

yaml 复制代码
root@k8s-master1:/k8s-test/configmap# vim mysql-nginx.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-nginx
  namespace: default
data:
  # MySQL 配置
  mysql.cnf: |
    [mysqld]
    datadir=/var/lib/mysql
    socket=/var/run/mysqld/mysqld.sock
    port=3306
    character-set-server=utf8mb4
    collation-server=utf8mb4_unicode_ci
    max_connections=200
    wait_timeout=600
    bind-address=0.0.0.0

  # Nginx 配置
  nginx.conf: |
    user nginx;
    worker_processes auto;
    error_log /var/log/nginx/error.log warn;
    pid /var/run/nginx.pid;

    events {
        worker_connections 1024;
    }

    http {
        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_x_forwarded_for"';

        access_log /var/log/nginx/access.log main;

        sendfile on;
        keepalive_timeout 65;

        server {
            listen 80;
            server_name localhost;

            root /usr/share/nginx/html;
            index index.html index.htm;

            location / {
                try_files $uri $uri/ /index.html;
            }

            error_page 500 502 503 504 /50x.html;
            location = /50x.html {
                root /usr/share/nginx/html;
            }
        }
    }
root@k8s-master1:/k8s-test/configmap# kubectl apply -f mysql-nginx.yaml 
configmap/mysql-nginx created
root@k8s-master1:/k8s-test/configmap# kubectl get configmap
NAME               DATA   AGE
kube-root-ca.crt   1      15d
mysql-nginx        2      5s
test-configmap1    2      35m
test-configmap2    1      23m
test-configmap3    2      5m17s
root@k8s-master1:/k8s-test/configmap# 
root@k8s-master1:/k8s-test/configmap# kubectl get configmap mysql-nginx -o yaml

三、ConfigMap使用

3.1 环境变量引用

yaml 复制代码
## 我这先删除一下没用的configmap
root@k8s-master1:/k8s-test/configmap# kubectl get configmap
NAME               DATA   AGE
kube-root-ca.crt   1      15d
mysql-nginx        2      30m
test-configmap1    2      65m
test-configmap2    1      54m
test-configmap3    2      35m
root@k8s-master1:/k8s-test/configmap# kubectl delete configmap test-configmap1 test-configmap2 test-configmap3
yaml 复制代码
## 1. 创建一个configmap
root@k8s-master1:/k8s-test/configmap# vim configmap1.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
        name: test-config4
        namespace: default
data:
        name: jack
        sex: man
        age: ten
        my.cnf: |
                [mysqld]
                datadir=/var/lib/mysql
                socket=/var/run/mysqld/mysqld.sock
yaml 复制代码
## 2. 创建pod,用环境变量引用configmap中的部分key
root@k8s-master1:/k8s-test/configmap# kubectl apply -f configmap1.yaml 
root@k8s-master1:/k8s-test/configmap# kubectl get configmap
NAME               DATA   AGE
kube-root-ca.crt   1      15d
mysql-nginx        2      31m
test-config4       4      4s
root@k8s-master1:/k8s-test/configmap# vim pod.yaml 
---
apiVersion: v1
kind: Pod
metadata:
        name: test-pod
spec:
        containers:
                - name: test-pod
                  image: nginx:1.24
                  env:  # 专门在容器里面设置变量的关键字
                          - name: TEST_NAME  # 容器里设置的新变量的名字
                            valueFrom:
                                    configMapKeyRef:
                                            name: test-config4  # 引用哪个configmap
                                            key: name  # 引用这个configmap中的哪个key
                          - name: TEST_AGE
                            valueFrom:
                                    configMapKeyRef:
                                            name: test-config4
                                            key: age
root@k8s-master1:/k8s-test/configmap# kubectl apply -f pod.yaml 
root@k8s-master1:/k8s-test/configmap# kubectl get pod
NAME           READY   STATUS    RESTARTS      AGE
nginx-harbor   1/1     Running   1 (77m ago)   158m
test-pod       1/1     Running   0             4s
root@k8s-master1:/k8s-test/configmap# kubectl exec -it test-pod /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@test-pod:/# echo $TEST_NAME
jack
root@test-pod:/# echo $TEST_AGE
ten
root@test-pod:/# exit
exit
root@k8s-master1:/k8s-test/configmap# 
yaml 复制代码
## 3. 创建pod,用环境变量引用configmap中的所有key
root@k8s-master1:/k8s-test/configmap# vim pod2.yaml 
---
apiVersion: v1
kind: Pod
metadata:
        name: test-pod2
spec:
        containers:
                - name: test-pod2
                  image: nginx:1.24
                  envFrom:
                          - configMapRef:
                                  name: test-config4
root@k8s-master1:/k8s-test/configmap# kubectl apply -f pod2.yaml
root@k8s-master1:/k8s-test/configmap# kubectl exec -it test-pod2 /bin/bash

进入容器内部,发现所有的key已经自动变成环境变量

3.2 卷挂载

yaml 复制代码
root@k8s-master1:/k8s-test/configmap# vim volupod.yaml
---
apiVersion: v1
kind: Pod
metadata:
        name: test-pod3
spec:
        containers:
                - name: test-pod3
                  image: nginx:1.24
                  volumeMounts:
                          - name: test-volume  # 挂载卷test-volume
                            mountPath: "/tmp/volume"  # 把它挂载到容器内的/tmp/volume目录下
        volumes:
                - name: test-volume  # 定义一个名为test-volume的卷
                  configMap:
                          name: test-config4  # test-volume卷的内容来自test-config4
root@k8s-master1:/k8s-test/configmap# kubectl apply -f volupod.yaml 
root@k8s-master1:/k8s-test/configmap# kubectl exec -it test-pod3 /bin/bash # 进入容器
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@test-pod3:/# ls /tmp/volume/  # test-config4中的每个key都变成了文件,文件中存的是key对应的值
age  my.cnf  name  sex
root@test-pod3:/# cat /tmp/volume/my.cnf 
[mysqld]
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
root@test-pod3:/# cat /tmp/volume/name   
jackroot@test-pod3:/# cat /tmp/volume/age  
tenroot@test-pod3:/# cat /tmp/volume/sex 
manroot@test-pod3:/# exit
exit

3.3 subPath参数

subPath:挂载文件用的,在 volumeMounts 下面,只挂载单个文件,不覆盖整个目录,不支持热更新

用了 subPath → 不支持热更新

如果你要 覆盖配置文件(nginx.conf、my.cnf)→ 必须用 subPath,接受不能热更新,例如主配置文件

如果你要 挂载配置目录→ 不用 subPath,可以热更新,例如子配置文件

yaml 复制代码
## 例:创建mysql和nginx pod,引用mysql-nginx configmap配置文件
root@k8s-master1:/k8s-test/configmap# kubectl get cm  # 查看当前的configmap
NAME               DATA   AGE
kube-root-ca.crt   1      15d
mysql-nginx        2      13m

## 1. 创建一个secret存放mysql的登录密码
root@k8s-master1:/k8s-test/configmap# echo -n "Abc@123" > password.txt
root@k8s-master1:/k8s-test/configmap# kubectl create secret generic mysql-pass --from-file=./password.txt
yaml 复制代码
## 3. 创建mysql和nginx的pod
root@k8s-master1:/k8s-test/configmap# vim mysql-nginx-pod.yaml 
---
apiVersion: v1
kind: Pod
metadata:
        name: mysql
spec:
        containers:
                - name: mysql
                  image: mysql:5.7
                  # 环境变量
                  env:
                          # 环境变量名:MYSQL_ROOT_PASSWORD(mysql的root密码)
                          - name: MYSQL_ROOT_PASSWORD
                            valueFrom:
                                    # 值从secret里提取
                                    secretKeyRef:
                                            # 来自哪个secret
                                            name: mysql-pass
                                            # 取该secret里的哪个键值
                                            key: password.txt
                  # 卷挂载:把外部卷挂到容器内部路径
                  volumeMounts:
                            # 使用一个名为mysql的卷
                          - name: mysql
                            # 容器内的挂载目标文件
                            mountPath: /etc/my.cnf
                            # 只挂载卷里的my.cnf这一个文件,不覆盖整个目录,如果不加subPath容器不能正常启动
                            subPath: my.cnf
        # 定义Pod级别的数据卷
        volumes:
                 # 定义一个卷的名字叫mysql
                - name: mysql
                  configMap:
                          # 使用名为mysql-nginx的configmap
                          name: mysql-nginx
                          items:
                                   # cm里的key是mysql.cnf
                                  - key: mysql.cnf
                                    # 映射到卷里的文件名叫my.cnf
                                    path: my.cnf
---
apiVersion: v1
kind: Pod
metadata:
        name: nginx

spec:
        containers:
                - name: nginx
                  image: nginx:1.24
                  volumeMounts:
                          - name: nginx
                            mountPath: /etc/nginx/nginx.conf
                            subPath: nginx.conf
        volumes:
                - name: nginx
                  configMap:
                          name: mysql-nginx
                          items:
                                  - key: nginx.conf
                                    path: nginx.conf
yaml 复制代码
## 4. 运行pod
root@k8s-master1:/k8s-test/configmap# kubectl apply -f mysql-nginx-pod.yaml 
root@k8s-master1:/k8s-test/configmap# kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
mysql   1/1     Running   0          59s
nginx   1/1     Running   0          10s
yaml 复制代码
## 5. 进入nginx pod内部,看看nginx能否正常访问
root@k8s-master1:/k8s-test/configmap# kubectl exec -it nginx /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx:/# curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
root@nginx:/# exit
exit
yaml 复制代码
## 6. 进入mysql pod中,看看能否登录mysql
root@k8s-master1:/k8s-test/configmap# kubectl exec -it mysql /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
bash-4.2# mysql -uroot -p'Abc@123'  # 登录成功
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.44 MySQL Community Server (GPL)

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> exit
Bye
bash-4.2# exit
exit

3.4 configmap的热更新

不热更新案例

验证subPath支不支持热更新

yaml 复制代码
## 例:
root@k8s-master1:/k8s-test/configmap# vim mysql-nginx.yaml 
worker_processes 2;  # 更改这一行,之前是worker_processes auto;
root@k8s-master1:/k8s-test/configmap# kubectl apply -f mysql-nginx.yaml
root@k8s-master1:/k8s-test/configmap# kubectl get configmap mysql-nginx -o yaml


由此可知,subPath不支持热更新

热更新案例

想要支持热更新,需要用yaml文件方式创建configmap,并且不能使用subPath参数,并且需要卷挂载configmap才能实现热更新

yaml 复制代码
# 例,热更新案例
## 1. 创建一个nginx的configmap,里面存放网页配置
root@k8s-master1:/k8s-test/configmap# vim nginx-configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx
  namespace: default
data:
  # Nginx 页面
  index.html: |
          welcome nginx
          hello
root@k8s-master1:/k8s-test/configmap# kubectl apply -f nginx-configmap.yaml

## 2. 创建nginx pod,用卷挂载的方式引用nginx configmap
root@k8s-master1:/k8s-test/configmap# vim nginx-pod.yaml 
---
apiVersion: v1
kind: Pod
metadata:
        name: nginx-pod
spec:
        hostNetwork: true
        containers:
                - name: nginx
                  image: nginx:1.24
                  ports:
                          - containerPort: 80
                  volumeMounts:
                          - mountPath: /usr/share/nginx/html
                            name: index
        volumes:
                - name: index
                  configMap:
                          name: nginx
                          items:
                                  - key: index.html
                                    path: index.html
root@k8s-master1:/k8s-test/configmap# kubectl apply -f nginx-pod.yaml 
root@k8s-master1:/k8s-test/configmap# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          7s

## 3. 访问页面,看是否挂载成功
root@k8s-master1:/k8s-test/configmap# curl 192.168.13.139:80
welcome nginx
hello
yaml 复制代码
## 4. 更改nginx configmap,看看nginx pod的页面是否会改变
root@k8s-master1:/k8s-test/configmap# vim nginx-configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx
  namespace: default
data:
  # Nginx 页面
  index.html: |
          welcome nginx  # 删除了最后一行
root@k8s-master1:/k8s-test/configmap# kubectl apply -f nginx-configmap.yaml

## 5. 重新访问页面,由于某种延迟过几秒后会刷新出新的页面
root@k8s-master1:/k8s-test/configmap# curl 192.168.13.139:80  
welcome nginx

注:

文中若有疏漏,欢迎大家指正赐教。

本文为100%原创,转载请务必标注原创作者,尊重劳动成果。

求赞、求关注、求评论!你的支持是我更新的最大动力,评论区等你~

相关推荐
Dillon Dong4 小时前
【系统运维】Docker版本冲突问题详解:从错误到解决方案
docker·容器
Dillon Dong4 小时前
【系列主题】从 Docker 构建失败看依赖隔离:多阶段构建的“隐形陷阱”
运维·docker·容器
如果'\'真能转义说6 小时前
《数据不丢失!本地挂载的 Docker 一键启动PS1脚本》
运维·docker·容器
郝开7 小时前
Docker Compose 本地环境搭建:mysql
mysql·docker·容器
人工智能培训7 小时前
AI模型部署进阶:Docker容器化部署AI项目
人工智能·深度学习·机器学习·docker·容器·transformer·知识图谱
胡小禾8 小时前
K8S Helm
docker·容器·kubernetes
SPC的存折8 小时前
1、K8S-单Master集群部署-OpenEuler24.03
云原生·容器·kubernetes
Cat_Rocky8 小时前
k8s-单Master集群部署(简练理解)
java·容器·kubernetes
眷蓝天9 小时前
K8S 单 Master 集群在 openEuler 24.03 上的部署指南
容器·kubernetes·php