个人随笔
目录
Kubernetes配置与密钥管理:ConfigMap&Secret 超全实战笔记
2026-07-01 23:14:58
在Kubernetes集群中,应用配置与敏感密钥的统一管理是容器化部署的核心环节。K8s提供了ConfigMapSecret两种核心资源,分别用于管理普通明文配置和加密敏感数据,实现配置与容器镜像解耦,无需重新打包镜像即可修改应用配置,极大提升了容器应用的运维灵活性。本文将全方位讲解两种资源的原理、创建方式、使用场景、热更新机制,并补充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 cm1

1.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 cm2

1.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 cm3

1.2.4 YAML清单文件创建(生产常用)

通过YAML资源文件声明式创建,配置可固化、可版本管理,是生产环境主流方式。
# 编写cm4配置清单
vim cm4.yml
apiVersion: 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 cm4

1.3 ConfigMap 两种核心使用方式

1.3.1 环境变量注入方式

将ConfigMap的所有键值对批量转为Pod环境变量,适合读取简单配置,不支持热更新
vim pod-cm1.yml
apiVersion: 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.yml
apiVersion: 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/port

1.4 拓展:SpringBoot 项目 ConfigMap 实战配置

SpringBoot项目默认读取 application.yml/application.properties 配置文件,我们可以通过ConfigMap挂载配置文件,实现SpringBoot配置外置、动态更新。

1.4.1 创建SpringBoot专属ConfigMap

直接封装完整的 application.yml 配置文件内容。
vim springboot-cm.yml
apiVersion: 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: DEBUG
kubectl apply -f springboot-cm.yml

1.4.2 Pod挂载配置适配SpringBoot

将ConfigMap中的 application.yml 挂载到SpringBoot容器的配置文件优先级目录,覆盖默认配置。
vim springboot-pod.yml
apiVersion: 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-config
kubectl 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=3306
2. 卷挂载方式(支持热更新)
# 编辑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类型,适配不同场景:
  1. Opaque(默认):通用型Secret,Base64编码,用于存储密码、自定义密钥,对应命令 generic
  2. kubernetes.io/service-account-token:服务账号密钥,K8s自动创建,用于Pod访问集群API
  3. kubernetes.io/dockerconfigjson:镜像仓库认证密钥,用于私有Docker镜像拉取,对应命令 docker-registry
  4. kubernetes.io/tls:SSL/TLS证书密钥,用于HTTPS通信,对应命令 tls
# 查看secret创建命令帮助
kubectl create secret -h

2.3 Secret 实战案例(MySQL密码管理)

以最常用的 Opaque类型 为例,实现MySQL数据库密码的安全管理。

2.3.1 明文密码Base64编码

Opaque类型Secret要求数据必须经过Base64编码。
# 将明文密码123编码
echo -n 123 | base64
# 输出:MTIz

2.3.2 创建Secret资源

vim secret-mysql.yml
apiVersion: 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-mysql

2.4 Secret 两种使用方式

2.4.1 环境变量注入Pod

将Secret密钥注入容器环境变量,容器内自动解码为明文。
vim pod-mysql-secret1.yml
apiVersion: 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=123

2.4.2 数据卷挂载Pod(支持热更新)

将Secret以文件形式挂载到容器,容器内自动解码,支持热更新,安全性更高。
vim pod-mysql-secret2.yml
apiVersion: 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
# 输出明文密码:123

2.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 生产最佳实践

  1. 配置分离:所有业务配置外置,禁止将配置写入镜像或代码
  2. 场景区分:普通配置用ConfigMap,敏感密码、证书必须用Secret
  3. 更新方式:需要动态更新的配置,统一使用卷挂载方式,规避环境变量无热更新问题
  4. 安全强化:Secret仅Base64编码,生产环境需开启etcd加密,或对接Vault等外部密钥管理工具
  5. SpringBoot适配:优先挂载完整配置文件,实现配置集中管理、动态热更新
 5

啊!这个可能是世界上最丑的留言输入框功能~


当然,也是最丑的留言列表

有疑问发邮件到 : suibibk@qq.com 侵权立删
Copyright : 个人随笔   备案号 : 粤ICP备18099399号-2