在Kubernetes集群中,应用配置与敏感密钥的统一管理是容器化部署的核心环节。K8s提供了ConfigMap和Secret两种核心资源,分别用于管理普通明文配置和加密敏感数据,实现配置与容器镜像解耦,无需重新打包镜像即可修改应用配置,极大提升了容器应用的运维灵活性。本文将全方位讲解两种资源的原理、创建方式、使用场景、热更新机制,并补充SpringBoot项目适配实战案例。
一、ConfigMap 普通配置管理
1.1 什么是 ConfigMap
ConfigMap 是K8s用于存储非敏感、明文配置数据的资源对象,核心作用是实现应用配置与容器镜像分离。
简单理解:
- ConfigMap 可以看作是Pod的外置配置文件/环境变量仓库
- 支持以环境变量或数据卷挂载的形式注入Pod内部
- 全程明文存储,仅适用于数据库地址、端口、超时时间、日志级别等非敏感配置
1.2 ConfigMap 四种创建方式(实战)
1.2.1 命令行字面量创建(--from-literal)
直接在命令行指定键值对,适合少量临时配置创建。
# 创建包含host、port两个配置的ConfigMap
kubectl create configmap cm1 --from-literal=host=127.0.0.1 --from-literal=port=3306
# 查看ConfigMap列表
kubectl get cm
# 查看详细配置数据
kubectl describe cm cm11.2.2 命令行多文件创建(--from-file)
将本地多个独立配置文件,批量封装为ConfigMap,每个文件名对应key,文件内容对应value。
# 生成本地配置文件
echo -n 127.0.0.1 > host
echo -n 3306 > port
# 基于文件创建ConfigMap
kubectl create configmap cm2 --from-file=./host --from-file=./port
# 验证查看
kubectl get cm
kubectl describe cm cm21.2.3 命令行环境变量文件创建(--from-env-file)
适配SpringBoot、Java等项目的env配置文件,单个文件多键值对批量导入,自动解析key=value格式。
# 编写env配置文件
vim env.txt
# 文件内容
host=127.0.0.1
port=3306
spring.profiles.active=prod
log.level=info
# 基于env文件创建ConfigMap
kubectl create configmap cm3 --from-env-file=env.txt
# 验证
kubectl describe cm cm31.2.4 YAML清单文件创建(生产常用)
通过YAML资源文件声明式创建,配置可固化、可版本管理,是生产环境主流方式。
# 编写cm4配置清单
vim cm4.ymlapiVersion: v1
kind: ConfigMap
metadata:
name: cm4
namespace: default
data:
host: 127.0.0.1
port: "3306"
timeout: 3000# 应用配置创建资源
kubectl apply -f cm4.yml
# 验证
kubectl get cm
kubectl describe cm cm41.3 ConfigMap 两种核心使用方式
1.3.1 环境变量注入方式
将ConfigMap的所有键值对批量转为Pod环境变量,适合读取简单配置,不支持热更新。
vim pod-cm1.ymlapiVersion: v1
kind: Pod
metadata:
name: pod-cm1
spec:
containers:
- name: busybox
image: busybox
args: [ "/bin/sh", "-c", "sleep 10000" ]
# 批量注入ConfigMap为环境变量
envFrom:
- configMapRef:
name: cm1# 创建Pod并验证
kubectl apply -f pod-cm1.yml
kubectl exec pod-cm1 -- env | grep -E "host|port"1.3.2 数据卷挂载方式
将ConfigMap以文件形式挂载到容器指定目录,每个key对应一个配置文件,支持热更新,生产首选。
vim pod-cm2.ymlapiVersion: v1
kind: Pod
metadata:
name: pod-cm2
spec:
containers:
- name: busybox
image: busybox
args: [ "/bin/sh", "-c", "sleep 10000" ]
volumeMounts:
- name: vol-cm
mountPath: "/etc/mysql"
readOnly: true
volumes:
- name: vol-cm
configMap:
name: cm2# 创建Pod并验证文件配置
kubectl apply -f pod-cm2.yml
kubectl exec pod-cm2 -- ls /etc/mysql
kubectl exec pod-cm2 -- cat /etc/mysql/port1.4 拓展:SpringBoot 项目 ConfigMap 实战配置
SpringBoot项目默认读取
application.yml/application.properties 配置文件,我们可以通过ConfigMap挂载配置文件,实现SpringBoot配置外置、动态更新。1.4.1 创建SpringBoot专属ConfigMap
直接封装完整的
application.yml 配置文件内容。vim springboot-cm.ymlapiVersion: v1
kind: ConfigMap
metadata:
name: springboot-app-config
namespace: default
data:
# 完整的springboot应用配置
application.yml: |
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/test
username: root
driver-class-name: com.mysql.cj.jdbc.Driver
logging:
level:
root: INFO
com.example: DEBUGkubectl apply -f springboot-cm.yml1.4.2 Pod挂载配置适配SpringBoot
将ConfigMap中的
application.yml 挂载到SpringBoot容器的配置文件优先级目录,覆盖默认配置。vim springboot-pod.ymlapiVersion: v1
kind: Pod
metadata:
name: springboot-demo
spec:
containers:
- name: springboot-app
image: spring-boot-demo:latest
ports:
- containerPort: 8080
volumeMounts:
# 挂载springboot配置文件到容器指定目录
- name: app-config
mountPath: /app/config/application.yml
subPath: application.yml
readOnly: true
volumes:
- name: app-config
configMap:
name: springboot-app-configkubectl apply -f springboot-pod.yml核心优势:后续修改SpringBoot数据库地址、日志级别、端口等配置时,只需编辑ConfigMap资源,无需重新打包部署项目,挂载方式支持热更新(subPath挂载除外)。
1.5 ConfigMap 热更新机制详解
1.5.1 热更新规则
- 环境变量注入:修改ConfigMap后,Pod内部配置不会更新,需重启Pod生效
- 数据卷挂载:修改ConfigMap后,Kubelet会自动同步文件,约30秒热更新生效,无需重启Pod
1.5.2 热更新验证
1. 环境变量方式(无热更新)
# 编辑cm1,将port改为3307
kubectl edit cm cm1
# 查看Pod环境变量,配置无变化
kubectl exec pod-cm1 -- env | grep port
# 输出仍为 port=33062. 卷挂载方式(支持热更新)
# 编辑cm2,将port改为3308
kubectl edit cm cm2
# 等待30秒后查看,配置自动更新
kubectl exec pod-cm2 -- cat /etc/mysql/port
# 输出 3308二、Secret 敏感密钥管理
2.1 什么是 Secret
Secret 是K8s用于存储敏感数据的资源对象,核心区别于ConfigMap:
- ConfigMap:明文存储,适用于普通配置
- Secret:数据以 Base64编码 存储(非加密,仅规避明文展示),适用于密码、密钥、Token、证书等敏感数据
Secret 同样支持环境变量、数据卷两种注入方式,且支持热更新。
2.2 Secret 四大类型
K8s内置四种常用Secret类型,适配不同场景:
- Opaque(默认):通用型Secret,Base64编码,用于存储密码、自定义密钥,对应命令
generic - kubernetes.io/service-account-token:服务账号密钥,K8s自动创建,用于Pod访问集群API
- kubernetes.io/dockerconfigjson:镜像仓库认证密钥,用于私有Docker镜像拉取,对应命令
docker-registry - kubernetes.io/tls:SSL/TLS证书密钥,用于HTTPS通信,对应命令
tls
# 查看secret创建命令帮助
kubectl create secret -h2.3 Secret 实战案例(MySQL密码管理)
以最常用的 Opaque类型 为例,实现MySQL数据库密码的安全管理。
2.3.1 明文密码Base64编码
Opaque类型Secret要求数据必须经过Base64编码。
# 将明文密码123编码
echo -n 123 | base64
# 输出:MTIz2.3.2 创建Secret资源
vim secret-mysql.ymlapiVersion: v1
kind: Secret
metadata:
name: secret-mysql
namespace: default
type: Opaque
data:
password: MTIz # 123的base64编码值# 创建并查看Secret
kubectl apply -f secret-mysql.yml
kubectl get secret | grep secret-mysql2.4 Secret 两种使用方式
2.4.1 环境变量注入Pod
将Secret密钥注入容器环境变量,容器内自动解码为明文。
vim pod-mysql-secret1.ymlapiVersion: v1
kind: Pod
metadata:
name: pod-mysql-secret1
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: secret-mysql
key: password# 创建Pod并验证
kubectl apply -f pod-mysql-secret1.yml
kubectl exec -it pod-mysql-secret1 -- env | grep MYSQL_ROOT_PASSWORD
# 输出明文密码:MYSQL_ROOT_PASSWORD=1232.4.2 数据卷挂载Pod(支持热更新)
将Secret以文件形式挂载到容器,容器内自动解码,支持热更新,安全性更高。
vim pod-mysql-secret2.ymlapiVersion: v1
kind: Pod
metadata:
name: pod-mysql-secret2
spec:
containers:
- name: busybox
image: busybox
args: ["/bin/sh", "-c", "sleep 100000"]
volumeMounts:
- name: vol-secret
mountPath: "/opt/passwd"
readOnly: true
volumes:
- name: vol-secret
secret:
secretName: secret-mysql# 创建Pod并验证
kubectl apply -f pod-mysql-secret2.yml
kubectl exec pod-mysql-secret2 -- cat /opt/passwd/password
# 输出明文密码:1232.4.3 Secret 热更新验证
# 新密码haha123编码
echo -n haha123 | base64
# 输出:aGFoYTEyMw==
# 编辑secret更新密码
kubectl edit secret secret-mysql
# 等待30秒后验证,配置自动更新
kubectl exec pod-mysql-secret2 -- cat /opt/passwd/password
# 输出:haha123三、ConfigMap & Secret 核心对比与最佳实践
3.1 核心区别
特性 | ConfigMap | Secret |
|---|---|---|
数据存储 | 明文存储 | Base64编码存储(非加密) |
适用场景 | 普通配置(端口、地址、日志、参数) | 敏感数据(密码、证书、Token、密钥) |
热更新 | 仅挂载方式支持 | 仅挂载方式支持 |
数据权限 | 集群内可查看明文 | 默认隐藏原始编码数据,权限更严格 |
3.2 生产最佳实践
- 配置分离:所有业务配置外置,禁止将配置写入镜像或代码
- 场景区分:普通配置用ConfigMap,敏感密码、证书必须用Secret
- 更新方式:需要动态更新的配置,统一使用卷挂载方式,规避环境变量无热更新问题
- 安全强化:Secret仅Base64编码,生产环境需开启etcd加密,或对接Vault等外部密钥管理工具
- SpringBoot适配:优先挂载完整配置文件,实现配置集中管理、动态热更新
