Qingular

ConfigMap 和 Secret

·CKAk8s练习

ConfigMap 和 Secret 的创建、注入和挂载

← 返回 CKA 练习目录

概述

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> 快速验证注入是否成功

官方文档链接