ConfigMap 和 Secret
ConfigMap 和 Secret 的创建、注入和挂载
概述
ConfigMap 和 Secret 用于将配置数据与容器镜像解耦。ConfigMap 存储非敏感数据,Secret 存储敏感数据(Base64 编码)。
一、ConfigMap
1.1 创建 ConfigMap
kubectl create configmap app-config --from-literal=APP_COLOR=blue --from-literal=APP_MODE=production
# 从文件创建(文件名作为 key)
kubectl create configmap app-config --from-file=app.properties
# 从文件创建(自定义 key)
kubectl create configmap app-config --from-file=custom-key=app.properties
# 从 env-file 创建
kubectl create configmap app-config --from-env-file=app.env
# 从目录创建
kubectl create configmap app-config --from-dir=config/
# 生成 YAML
kubectl create configmap app-config --from-literal=APP_COLOR=blue --dry-run=client -o yaml
1.2 ConfigMap YAML 示例
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_COLOR: blue
APP_MODE: production
app.properties: |
key1=value1
key2=value2
# 查看 ConfigMap
kubectl get configmaps
kubectl get cm
kubectl describe cm app-config
kubectl get cm app-config -o yaml
二、Secret
Secret 中的数据以 Base64 编码存储。
2.1 创建 Secret
# generic:从字面值创建
kubectl create secret generic db-secret \
--from-literal=DB_USER=admin \
--from-literal=DB_PASSWORD=supersecret
# generic:从文件创建
kubectl create secret generic db-secret --from-file=db.env
# tls:创建 TLS 证书 Secret
kubectl create secret tls tls-secret \
--cert=path/to/tls.crt \
--key=path/to/tls.key
# docker-registry:镜像仓库认证
kubectl create secret docker-registry regcred \
--docker-server=https://index.docker.io/v1/ \
--docker-username=<user> \
--docker-password=<password> \
--docker-email=<email>
# 生成 YAML
kubectl create secret generic db-secret --from-literal=DB_PASSWORD=pass123 --dry-run=client -o yaml
2.2 Secret YAML 示例
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
DB_USER: YWRtaW4= # base64 编码
DB_PASSWORD: c3VwZXJzZWNyZXQ=
2.3 Base64 编解码
# 编码
echo -n "admin" | base64
echo -n "supersecret" | base64
# 解码
echo "YWRtaW4=" | base64 -d
echo "c3VwZXJzZWNyZXQ=" | base64 -d
# 在 Secret YAML 中直接使用 stringData(纯文本,K8s 自动编码)
# 使用 stringData(明文存储,创建时自动转为 data)
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData:
DB_USER: admin
DB_PASSWORD: supersecret
三、注入 Pod 环境变量
3.1 使用 env(单条注入)
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: app
image: nginx
env:
- name: APP_COLOR # 容器中的环境变量名
valueFrom:
configMapKeyRef:
name: app-config # ConfigMap 名称
key: APP_COLOR # ConfigMap 中的 key
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: DB_PASSWORD
3.2 使用 envFrom(批量注入)
apiVersion: v1
kind: Pod
metadata:
name: envfrom-pod
spec:
containers:
- name: app
image: nginx
envFrom:
- configMapRef:
name: app-config # 注入所有 ConfigMap 条目
optional: true # ConfigMap 不存在时不报错
- secretRef:
name: db-secret # 注入所有 Secret 条目
3.3 前缀处理
envFrom:
- configMapRef:
name: app-config
prefix: CONFIG_ # 所有变量前加 CONFIG_ 前缀
四、挂载为卷
4.1 ConfigMap 挂载为卷
apiVersion: v1
kind: Pod
metadata:
name: configmap-volume
spec:
volumes:
- name: config-volume
configMap:
name: app-config
items: # 可选:只挂载指定 key
- key: app.properties
path: myapp.properties # 挂载后的文件名
containers:
- name: app
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/config
4.2 Secret 挂载为卷
apiVersion: v1
kind: Pod
metadata:
name: secret-volume
spec:
volumes:
- name: secret-volume
secret:
secretName: db-secret
defaultMode: 0400 # 文件权限(默认为 0644)
containers:
- name: app
image: nginx
volumeMounts:
- name: secret-volume
mountPath: /etc/secret
# 检查挂载的 Secret(每个 key 对应一个文件)
kubectl exec secret-volume -- ls /etc/secret
kubectl exec secret-volume -- cat /etc/secret/DB_PASSWORD
# 注意:挂载为卷的 Secret 会自动解码为明文内容
4.3 热更新(自动更新)
ConfigMap/Secret 挂载为卷时,更新 ConfigMap/Secret 后 Pod 中的文件会自动更新(延迟数秒到数分钟)。
# 更新 ConfigMap
kubectl edit cm app-config
# 验证卷中文件更新
kubectl exec configmap-volume -- cat /etc/config/APP_COLOR
注意:通过 env/envFrom 注入的环境变量不会热更新,需要重启 Pod。
五、Immutable ConfigMap/Secret
Kubernetes 1.21+ 支持不可变 ConfigMap/Secret,提高性能并防止意外修改。
apiVersion: v1
kind: ConfigMap
metadata:
name: immutable-config
data:
APP_COLOR: blue
immutable: true
apiVersion: v1
kind: Secret
metadata:
name: immutable-secret
type: Opaque
stringData:
DB_PASSWORD: supersecret
immutable: true
# 设为 immutable 后,delete 并重新 create 才能修改
kubectl delete cm immutable-config
kubectl create cm immutable-config --from-literal=APP_COLOR=red
六、考试实用命令
# 快速创建并注入 ConfigMap
kubectl create configmap app-env --from-literal=DEBUG=true --from-literal=LOG_LEVEL=info
kubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml
# 在 pod.yaml 中添加 envFrom
# 创建 Secret 并在 Pod 中使用
kubectl create secret generic my-secret --from-literal=SECRET_KEY=abc123
kubectl run secret-pod --image=busybox --dry-run=client -o yaml -- sleep 3600 > secret-pod.yaml
# 添加 env/volume 引用该 Secret
# 检查 Secret 内容
kubectl get secret my-secret -o jsonpath='{.data.SECRET_KEY}' | base64 -d
# 将 ConfigMap/Secret 的所有 key 作为环境变量注入
kubectl create configmap full-config --from-env-file=./app.env
kubectl run app --image=nginx --restart=Never -o yaml --dry-run=client > app.yaml
# 编辑添加 envFrom.configMapRef
# 从 Secret 加载并验证
kubectl create secret generic creds --from-literal=user=admin --from-literal=pass=secret123
kubectl run secret-test --image=busybox --restart=Never -it --rm -- env | grep user
🧪 完整操作实例:创建 ConfigMap 和 Secret 并注入 Pod
场景描述
创建应用配置 ConfigMap 和数据库密码 Secret,通过环境变量和卷挂载两种方式注入 Pod。
前置条件
- 可用的 Kubernetes 集群
- kubectl 已配置连接集群
操作步骤
Step 1: 创建 ConfigMap 和 Secret
# 创建 ConfigMap(应用配置)
kubectl create configmap app-config \
--from-literal=APP_COLOR=blue \
--from-literal=APP_MODE=production \
--from-literal=LOG_LEVEL=info
# 预期输出:configmap/app-config created
# 创建 Secret(数据库凭据)
kubectl create secret generic db-secret \
--from-literal=DB_USER=admin \
--from-literal=DB_PASSWORD=Sup3rS3cret!
# 预期输出:secret/db-secret created
# 查看创建结果
kubectl get cm app-config -o yaml | head -10
kubectl get secret db-secret -o yaml | head -10
Step 2: 通过环境变量注入 Pod
cat <<'EOF' > pod-env-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-env-demo
spec:
containers:
- name: app
image: busybox:1.28
command: ["sleep", "3600"]
env:
- name: APP_COLOR
valueFrom:
configMapKeyRef:
name: app-config
key: APP_COLOR
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-secret
key: DB_USER
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: DB_PASSWORD
EOF
kubectl apply -f pod-env-demo.yaml
# 预期输出:pod/pod-env-demo created
Step 3: 通过卷挂载注入 Pod
cat <<'EOF' > pod-volume-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-volume-demo
spec:
volumes:
- name: config-volume
configMap:
name: app-config
- name: secret-volume
secret:
secretName: db-secret
containers:
- name: app
image: busybox:1.28
command: ["sleep", "3600"]
volumeMounts:
- name: config-volume
mountPath: /etc/config
- name: secret-volume
mountPath: /etc/secret
EOF
kubectl apply -f pod-volume-demo.yaml
# 预期输出:pod/pod-volume-demo created
验证结果
# 验证环境变量注入
kubectl exec pod-env-demo -- env | grep -E "APP_COLOR|DB_USER|DB_PASSWORD"
# 预期输出:
# APP_COLOR=blue
# DB_USER=admin
# DB_PASSWORD=Sup3rS3cret!
# 验证卷挂载注入
kubectl exec pod-volume-demo -- ls /etc/config
# 预期输出:APP_COLOR APP_MODE LOG_LEVEL
kubectl exec pod-volume-demo -- cat /etc/secret/DB_PASSWORD
# 预期输出:Sup3rS3cret! (Secret 挂载为卷时自动解码为明文)
# 清理
kubectl delete pod pod-env-demo pod-volume-demo
kubectl delete cm app-config
kubectl delete secret db-secret
# 预期输出:pod "pod-env-demo" deleted
# pod "pod-volume-demo" deleted
# configmap "app-config" deleted
# secret "db-secret" deleted
考试提示
- Secret 中的值 Base64 编码,但并非加密。敏感数据应使用外部密钥管理工具(如 Vault)或启用 KMS 加密
envFrom可以批量注入 ConfigMap/Secret 的所有条目,节省 YAML 篇幅,但无法选择特定 key- 卷挂载方式支持热更新(修改 ConfigMap/Secret 后,Pod 中文件自动更新),但
env注入不会 - 挂载为卷时 Secret 的文件默认权限是 0644,可通过
defaultMode修改为 0400 - 考试中常用
kubectl exec <pod> -- env | grep <key>快速验证注入是否成功