
在 Kubernetes (简称 K8s)集群中,应用配置管理是核心环节——如果把配置硬编码到镜像或 Pod 定义中,不仅会导致镜像复用性差,还会泄露敏感信息(如密码、API 密钥)。K8s 提供的 ConfigMaps 和 Secrets 两大资源,正是为解决这一问题而生。本文将从概念、工作原理、实战案例到最佳实践,全面拆解这两种配置管理方案。
一、核心价值:为什么需要 ConfigMaps 和 Secrets?
在没有 ConfigMaps 和 Secrets 之前,开发者一般会面临两个痛点:
1. 配置与代码耦合:不同环境(开发/测试/生产)的配置(如数据库地址、端口)需要打包成不同镜像,镜像冗余且维护成本高;
2. 敏感信息暴露:密码、令牌直接写在 Pod YAML 或代码中,提交到 Git 仓库后极易泄露。
ConfigMaps 和 Secrets 通过「配置外置」的方式解决这些问题:
• 把非敏感配置(如环境变量、配置文件)交给 ConfigMaps 管理;
• 把敏感信息(如密码、证书)交给 Secrets 保护;
• 应用通过「引用」而非「内置」的方式获取配置,实现「一次镜像,多环境复用」。
二、ConfigMaps:非敏感配置的「容器」
1. 什么是 ConfigMaps?
ConfigMaps 是 K8s 中的一种非敏感配置存储资源,可存储键值对(Key-Value)、配置文件片段或完整的配置文件(如 app.conf、nginx.conf),支持应用在不修改镜像的情况下适配不同环境。
典型使用场景:
• 存储应用的功能开关(如 FEATURE_FLAG=true);
• 保存数据库连接地址(如 DB_HOST=mysql-service);
• 注入完整的配置文件(如 Nginx 的 nginx.conf)。
2. ConfigMaps 实战:3种创建与使用方式
ConfigMaps 的核心流程是「创建 ConfigMap → Pod 引用 ConfigMap」,下面通过实战案例演示最常用的 3 种方式。
方式1:通过 kubectl create configmap 命令创建(键值对)
适用于存储简单的键值对配置(如环境变量)。
步骤1:创建 ConfigMap
假设我们需要存储「数据库地址」和「应用端口」两个配置,执行命令:
# 格式:kubectl create configmap <ConfigMap名称> --from-literal=<键1>=<值1> --from-literal=<键2>=<值2>
kubectl create configmap app-config --from-literal=db.host=mysql-service --from-literal=app.port=8080
步骤2:查看 ConfigMap 详情
kubectl get configmap app-config -o yaml
输出结果核心片段(可见配置以明文存储):
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
app.port: "8080" # 键值对配置
db.host: mysql-service
步骤3:Pod 引用(作为环境变量)
在 Pod YAML 中通过 env 或 envFrom 引用 ConfigMap 的键值对:
apiVersion: v1
kind Pod
metadata:
name: app-pod
spec:
containers:
- name: app-container
image: nginx:alpine
# 方式A:单个引用(指定键)
env:
- name: DB_HOST # 容器内的环境变量名
valueFrom:
configMapKeyRef:
name: app-config # 关联的ConfigMap名称
key: db.host # 引用的ConfigMap键
# 方式B:批量引用(所有键)
envFrom:
- configMapRef:
name: app-config # 容器内会自动创建 DB_HOST、APP_PORT 两个环境变量
验证:进入 Pod 查看环境变量是否生效:
kubectl exec -it app-pod -- env | grep -E "DB_HOST|APP_PORT"
# 输出:
# DB_HOST=mysql-service
# APP_PORT=8080
方式2:从本地文件创建 ConfigMap(完整配置文件)
适用于存储完整的配置文件(如 nginx.conf、application.yml),避免手动在 YAML 中写配置内容。
步骤1:准备本地配置文件
创建 nginx.conf 文件,内容如下:
# nginx.conf
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
步骤2:从文件创建 ConfigMap
# 格式:kubectl create configmap <名称> --from-file=<本地文件路径>
kubectl create configmap nginx-config --from-file=./nginx.conf
步骤3:Pod 引用(挂载为文件)
通过 volumeMounts 将 ConfigMap 中的配置文件挂载到容器内的指定目录:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config-volume # 关联的Volume名称
mountPath: /etc/nginx/conf.d/ # 容器内挂载目录(覆盖原有配置)
readOnly: true # 配置文件只读,防止容器内修改
volumes:
- name: nginx-config-volume
configMap:
name: nginx-config # 关联的ConfigMap名称
items:
- key: nginx.conf # ConfigMap中的键(默认是文件名)
path: default.conf # 挂载到容器内的文件名(可自定义)
验证:进入 Pod 查看配置文件是否生效:
kubectl exec -it nginx-pod -- cat /etc/nginx/conf.d/default.conf
# 输出与本地 nginx.conf 一致,说明挂载成功
方式3:通过 YAML 文件创建 ConfigMap(自定义结构)
适用于配置复杂、需要版本控制的场景(可将 YAML 提交到 Git 仓库管理)。
创建 app-config.yaml 文件:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config-yaml
data:
# 1. 键值对配置
app.env: "production"
log.level: "info"
# 2. 完整配置文件(键为文件名,值为文件内容)
application.yml: |
spring:
datasource:
url: jdbc:mysql://mysql-service:3306/mydb
username: ${DB_USER} # 敏感信息后续用Secrets注入
server:
port: 8080
执行创建命令:
kubectl apply -f app-config.yaml
3. ConfigMaps 关键特性
• 动态更新:若 ConfigMap 内容修改,已通过「文件挂载」的 Pod 会在约 1 分钟内同步更新(无需重启 Pod);但「环境变量」引用的配置不会自动更新,需重启 Pod 生效。
• 明文存储:ConfigMaps 的数据以明文形式存储在 K8s -etcd 中,禁止存储敏感信息。
三、Secrets:敏感信息的「保险箱」
1. 什么是 Secrets?
Secrets 是 K8s 中用于存储敏感信息的资源,如密码、API 密钥、TLS 证书等,核心作用是避免敏感数据暴露在 Pod YAML、镜像或 Git 仓库中。
注意:Secrets 并非绝对安全——其数据默认以 Base64 编码存储(不是加密),任何人获取编码后都可解码。需额外配置「etcd 静态加密」才能实现真正的安全存储。
2. Secrets 实战:2种核心类型与使用
Secrets 支持多种类型,最常用的是「Opaque(通用密钥)」和「tls(TLS 证书)」,下面分别演示。
类型1:Opaque Secrets(通用键值对)
适用于存储简单的敏感键值对(如数据库密码、API 令牌)。
步骤1:Base64 编码敏感数据
由于 Secrets 要求数据以 Base64 编码存储,需先对原始数据编码(以密码 myDBpass123 为例):
# 编码命令:echo -n “原始数据” | base64
echo -n "myDBpass123" | base64
# 输出编码结果:bXlEQnBhc3MxMjM=
步骤2:通过 YAML 创建 Opaque Secret
创建 db-secret.yaml 文件,注意 type: Opaque:
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque # 通用类型
data:
db.password: bXlEQnBhc3MxMjM= # Base64编码后的密码
api.token: dG9rZW4xMjM0NTY3OA== # 示例:API令牌的编码值
执行创建命令:
kubectl apply -f db-secret.yaml
步骤3:Pod 引用(2种方式)
Secrets 的引用方式与 ConfigMaps 类似,支持「环境变量」和「文件挂载」。
方式A:作为环境变量(适用于短敏感值)
apiVersion: v1
kind: Pod
metadata:
name: app-with-secret
spec:
containers:
- name: app
image: nginx:alpine
env:
- name: DB_PASSWORD # 容器内环境变量名
valueFrom:
secretKeyRef:
name: db-secret # 关联的Secret名称
key: db.password # 引用的Secret键
optional: false # 若Secret不存在,Pod启动失败
验证:进入 Pod 查看环境变量(敏感值已正确注入):
kubectl exec -it app-with-secret -- env | grep DB_PASSWORD
# 输出:DB_PASSWORD=myDBpass123(自动解码为原始值)
方式B:挂载为文件(适用于证书、长令牌)
apiVersion: v1
kind: Pod
metadata:
name: app-secret-file
spec:
containers:
- name: app
image: nginx:alpine
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets/ # 容器内挂载目录
readOnly: true # 敏感文件只读,防止篡改
volumes:
- name: secret-volume
secret:
secretName: db-secret # 关联的Secret名称
验证:进入 Pod 查看文件内容(自动解码):
kubectl exec -it app-secret-file -- cat /etc/secrets/db.password
# 输出:myDBpass123
类型2:tls Secrets(TLS 证书)
适用于存储 HTTPS 所需的 TLS 证书和私钥(如 Nginx、Ingress 控制器的证书),K8s 会自动验证证书格式的合法性。
步骤1:准备 TLS 证书文件
假设已拥有 tls.crt(证书)和 tls.key(私钥)两个文件(可通过 openssl 生成测试证书)。
步骤2:创建 tls Secret
直接通过命令创建(无需手动编码,K8s 会自动处理):
# 格式:kubectl create secret tls <名称> --cert=<证书文件> --key=<私钥文件>
kubectl create secret tls nginx-tls --cert=./tls.crt --key=./tls.key
步骤3:Ingress 引用 tls Secret
tls Secrets 最常用的场景是为 Ingress 提供 HTTPS 证书:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
spec:
tls:
- hosts:
- example.com # 证书对应的域名(需与TLS Secret中的证书域名一致)
secretName: nginx-tls # 关联的TLS Secret名称(存储证书和私钥)
rules:
- host: example.com # 匹配的域名(需与tls.hosts一致)
http:
paths:
- path: / # 匹配的路径(Prefix类型表明前缀匹配)
pathType: Prefix
backend:
service:
name: nginx-service # 转发目标Service名称
port:
number: 80 # 转发目标Service的端口号
3. Secrets 安全增强:启用 etcd 静态加密
由于 Secrets 默认仅 Base64 编码(可解码),必须配置「etcd 静态加密」才能让数据在存储层(etcd)真正加密。
核心步骤(简化版):
1. 创建加密配置文件 encryption-config.yaml:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
metadata:
name: encryption-config # 配置名称(固定,需与APIServer启动参数对应)
resources:
- resources:
- secrets # 需加密的资源类型:Secret(仅对Secret进行静态加密)
providers:
- aescbc: # 加密算法:AES-CBC(对称加密,K8s推荐用于Secret加密)
keys:
- name: key1 # 密钥名称(自定义,用于标识密钥)
secret: <生成的32字节AES密钥> # 32字节AES-256密钥(通过 openssl rand -hex 32 生成)
- identity: {} # 降级策略:未匹配加密规则时,使用明文存储(必填,避免配置失效)
2. 修改 K8s API Server 启动参数,添加
–encryption-provider-config=
/etc/kubernetes/encryption-config.yaml;
3. 重启 API Server,新创建的 Secrets 会自动加密存储。
四、ConfigMaps 与 Secrets 核心区别
对比维度 ConfigMaps Secrets
存储内容 非敏感配置(环境变量、配置文件) 敏感信息(密码、证书、令牌)
存储方式 明文存储(etcd 中可见原始值) 默认 Base64 编码(需额外加密)
安全级别 低(仅用于非敏感数据) 中(需配置 etcd 加密提升安全)
使用场景 功能开关、数据库地址、Nginx 配置 数据库密码、API 密钥、TLS 证书
大小限制 无明确限制(提议不超过 1MB) 最大 1MB(K8s 内置限制)
五、最佳实践:让配置管理更安全、更高效
1. 严格分离代码与配置:所有环境相关的配置(包括敏感和非敏感)都通过 ConfigMaps/Secrets 管理,禁止硬编码到镜像或代码中。
2. 敏感数据必须用 Secrets:即使是测试环境的密码,也不能放在 ConfigMaps 或 Pod YAML 中,避免意外提交到 Git。
3. 启用 Secrets 加密存储:生产环境必须配置 etcd 静态加密,并定期轮换加密密钥。
4. 限制访问权限:通过 RBAC(基于角色的访问控制)策略,仅允许必要的 Pod/用户访问 ConfigMaps/Secrets,例如:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: app # 仅作用于 app 命名空间(与目标 Secret 同命名空间)
name: secret-reader
rules:
- apiGroups: [""] # 核心 API 组(secrets 属于核心组)
resources: ["secrets"] # 授权资源类型:Secret
resourceNames: ["db-secret"] # 仅授权指定 Secret(精准控制)
verbs: ["get", "list"] # 允许的操作:获取、列出(无修改/删除权限)
5. 使用外部密钥管理工具:对于高安全需求场景,提议用外部工具(如 HashiCorp Vault、AWS Secrets Manager)替代 K8s 原生 Secrets,实现更细粒度的权限控制和密钥轮换。
6. 避免 ConfigMaps/Secrets 过大:若配置文件超过 1MB(如大型配置文件、静态资源),提议用 PersistentVolume(PV)或配置中心(如 Apollo、Nacos)存储。
六、总结
ConfigMaps 和 Secrets 是 K8s 配置管理的「左膀右臂」:
• ConfigMaps 解决了「非敏感配置外置」的问题,让应用更灵活、可复用;
• Secrets 解决了「敏感信息保护」的问题,降低了数据泄露风险;
• 二者结合使用,再配合最佳实践(如加密、权限控制),可确保 K8s 应用在多环境中既安全又易于管理。
掌握这两种资源,是搭建生产级 K8s 集群的必备技能。
#pgc-card .pgc-card-href { text-decoration: none; outline: none; display: block; width: 100%; height: 100%; } #pgc-card .pgc-card-href:hover { text-decoration: none; } /*pc 样式*/ .pgc-card { box-sizing: border-box; height: 164px; border: 1px solid #e8e8e8; position: relative; padding: 20px 94px 12px 180px; overflow: hidden; } .pgc-card::after { content: ” “; display: block; border-left: 1px solid #e8e8e8; height: 120px; position: absolute; right: 76px; top: 20px; } .pgc-cover { position: absolute; width: 162px; height: 162px; top: 0; left: 0; background-size: cover; } .pgc-content { overflow: hidden; position: relative; top: 50%; -webkit-transform: translateY(-50%); transform: translateY(-50%); } .pgc-content-title { font-size: 18px; color: #222; line-height: 1; font-weight: bold; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .pgc-content-desc { font-size: 14px; color: #444; overflow: hidden; text-overflow: ellipsis; padding-top: 9px; overflow: hidden; line-height: 1.2em; display: -webkit-inline-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } .pgc-content-price { font-size: 22px; color: #f85959; padding-top: 18px; line-height: 1em; } .pgc-card-buy { width: 75px; position: absolute; right: 0; top: 50px; color: #406599; font-size: 14px; text-align: center; } .pgc-buy-text { padding-top: 10px; } .pgc-icon-buy { height: 23px; width: 20px; display: inline-block; background: url(https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/pgc/v2/pgc_tpl/static/image/commodity_buy_f2b4d1a.png); }
云原生入门必读书
¥138
购买
<script src=”//mp.toutiao.com/mp/agw/mass_profit/pc_product_promotions_js?item_id=7575136830153867822″></script>

专栏
微服务治理指南
作者:SuperOps
9.9币
60人已购
查看



收藏了,感谢分享