HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于
  • 概览

    • K8s 实战学习实验室
    • 服务访问清单
    • K8s-Lab 学习总纲、仓库评估与专家路线图
  • 课程正文

    • 环境验证与第一课:认识你的真实集群
    • 第二课:kubectl apply 之后,到底发生了什么
    • 第三课:调度器如何选节点,为什么 Pod 会 Pending
    • 第四课:Kubernetes 网络、协议分层、VXLAN/IPIP/WireGuard 原理与排障
    • 第五课:NetworkPolicy、零信任网络与流量边界
    • 第六课:身份、认证、授权、准入与 ServiceAccount / RBAC 原理
    • 第七课:ConfigMap 与 Secret 注入模型、更新机制与安全边界
    • 第八课:存储持久化、PV / PVC / StorageClass 与 NFS 原理
    • 第九课:StatefulSet、Headless Service、稳定身份与存储原理
    • 第十课:探针、滚动更新、优雅终止与 PDB 原理
    • 第十一课:requests / limits、QoS、OOM 与驱逐原理
    • 第十二课:HPA、自动扩缩容、指标链路与副本伸缩原理
    • 第十三课:Service、EndpointSlice、kube-proxy、CoreDNS 与服务发现原理
    • 第十四课:Ingress-nginx、反向代理、Host / Path、NodePort 与北南向流量原理
    • 第十五课:HTTPS、TLS、SNI、证书信任与 Ingress 终止原理
    • 第十六课:cert-manager、Ingress 自动签发、证书生命周期与 ACME 工作流原理
    • 第十七课:ACME、Let's Encrypt、HTTP-01 / DNS-01、Orders / Challenges 与生产限制原理
    • 第十八课:大模型全生态,从数据到训练到部署到治理原理
    • 第十九课:大模型数据集、清洗、标注、切分、版本管理与质量治理原理
    • 第二十课:大模型训练、SFT、LoRA、Checkpoint、Adapter 与模型产物原理
    • 第二十一课:大模型推理、量化、KV Cache、vLLM、吞吐/延迟与部署发布链路原理
  • 实验操作记录

    • 本次仓库审查操作记录与命令原理
    • 本轮操作记录:环境验证、集群基线盘点与故障样本采集
    • 本轮操作记录:kubectl apply 主链路实验
    • 本轮操作记录:调度实验与 Pending 排查
    • 本轮操作记录:Kubernetes 网络原理、协议对比与调试实验
    • 本轮操作记录:NetworkPolicy 与零信任网络实验
    • 本轮操作记录:身份、认证、授权、准入实验
    • 本轮操作记录:ConfigMap 与 Secret 注入、更新与安全边界实验
    • 本轮操作记录:存储持久化、PV / PVC / StorageClass 与 NFS 实验
    • 本轮操作记录:StatefulSet、Headless Service 与稳定身份实验
    • 本轮操作记录:探针、滚动更新、优雅终止与 PDB 实验
    • 本轮操作记录:资源模型、QoS、OOM 与 CPU 节流实验
    • 本轮操作记录:HPA 自动扩缩容实验
    • 本轮操作记录:Service、EndpointSlice、CoreDNS 与服务发现排障实验
    • 本轮操作记录:Ingress-nginx、NodePort 与北南向流量实验
    • 本轮操作记录:HTTPS、TLS、自签证书与 Ingress 实验
    • 本轮操作记录:cert-manager 安装、CA 签发与 Ingress 自动证书实验
    • 本轮操作记录:ACME staging、HTTP-01 失败样本与排障实验
    • 本轮操作记录:大模型全生态与基础原理科普文撰写
    • 本轮操作记录:大模型数据集样本与治理文档编写
    • 本轮操作记录:大模型训练与模型产物概念文撰写
    • 本轮操作记录:大模型推理与服务发布概念文撰写

ConfigMap 与 Secret — 配置与敏感信息管理

为什么不把配置写死在镜像里?

一个 nginx 镜像可能在 dev 连 postgres-dev,在 prod 连 postgres-prod。如果配置写死在镜像里,每个环境要构建不同的镜像。

K8s 的理念是:镜像不变,配置外置。同一个镜像 + 不同的 ConfigMap = 不同环境的行为。


ConfigMap — 非敏感配置

创建方式

# 方式一:从字面值
kubectl -n dev create configmap app-config \
  --from-literal=APP_ENV=development \
  --from-literal=LOG_LEVEL=debug \
  --from-literal=DB_HOST=postgres.dev.svc.cluster.local

# 方式二:从文件
kubectl -n dev create configmap nginx-conf --from-file=nginx.conf

# 方式三:从 YAML
kubectl apply -f configmap.yaml

我们创建的 ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  namespace: dev
data:
  APP_ENV: development
  DB_HOST: postgres.dev.svc.cluster.local
  LOG_LEVEL: debug

data 下的每个 key-value 就是一条配置。

两种使用方式

1. 作为环境变量注入

spec:
  containers:
  - name: app
    env:
    - name: APP_ENV
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: APP_ENV
    # 或者一次性注入所有 key:
    envFrom:
    - configMapRef:
        name: app-config

特点: Pod 启动时读取一次,之后不会自动更新。修改 ConfigMap 后必须重启 Pod。

2. 挂载为文件

spec:
  containers:
  - name: app
    volumeMounts:
    - name: config-vol
      mountPath: /etc/config
  volumes:
  - name: config-vol
    configMap:
      name: app-config

挂载后目录结构:

/etc/config/
├── APP_ENV    → 内容: development
├── DB_HOST    → 内容: postgres.dev.svc.cluster.local
└── LOG_LEVEL  → 内容: debug

特点: 修改 ConfigMap 后,文件内容会自动更新(约 30-60 秒延迟)。但应用进程不一定会重新读取文件——需要应用自己支持 watch 配置文件变化,或者用 sidecar 触发 reload。

面试重点

Q: ConfigMap 更新后 Pod 能感知吗?

使用方式自动更新?原因
环境变量不能环境变量在进程启动时注入,之后不变
Volume 挂载能kubelet 定期同步挂载内容
subPath 挂载不能subPath 是静态绑定,不参与更新

Q: Immutable ConfigMap 是什么?

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
immutable: true    # 设置后不可修改,也不可取消
data:
  APP_ENV: production

好处:大规模集群中,kubelet 不需要持续 watch 不可变的 ConfigMap,减轻 API Server 压力。


Secret — 敏感信息(密码、证书、Token)

和 ConfigMap 的区别

特性ConfigMapSecret
用途普通配置密码、证书、Token
存储etcd 明文etcd base64(默认不加密!)
传输不加密TLS 传输
内存可用磁盘存储tmpfs(内存挂载,不写磁盘)
大小限制1MB1MB

创建

kubectl -n dev create secret generic db-creds \
  --from-literal=username=admin \
  --from-literal=password=SuperSecret123

查看

# 看到的是 base64 编码(不是加密!)
$ kubectl -n dev get secret db-creds -o jsonpath="{.data}"
{"password":"U3VwZXJTZWNyZXQxMjM=","username":"YWRtaW4="}

# 解码
$ echo "U3VwZXJTZWNyZXQxMjM=" | base64 -d
SuperSecret123

关键安全认知

base64 不是加密,只是编码。 任何人拿到 Secret 的 YAML 都能解码出原文。

Secret 的安全性依赖:

  1. RBAC — 限制谁能 get Secret
  2. etcd 加密 — 配置 EncryptionConfiguration 对 etcd 中的 Secret 做 AES 加密(Phase 3 练习)
  3. 传输加密 — API Server 和 kubelet 之间走 TLS
  4. tmpfs 挂载 — Secret 挂载到 Pod 时用内存文件系统,不落盘

使用方式(同 ConfigMap)

# 环境变量
env:
- name: DB_PASSWORD
  valueFrom:
    secretKeyRef:
      name: db-creds
      key: password

# Volume 挂载
volumes:
- name: db-creds-vol
  secret:
    secretName: db-creds

Secret 的类型

类型用途
Opaque默认,任意 key-value
kubernetes.io/tlsTLS 证书(tls.crt + tls.key)
kubernetes.io/dockerconfigjsonDocker Registry 认证
kubernetes.io/service-account-tokenServiceAccount Token

面试深度题

Q: 生产环境如何安全管理 Secret?

  1. etcd 加密 — EncryptionConfiguration + AES-CBC
  2. External Secrets Operator — 从 AWS Secrets Manager / Vault 同步
  3. Sealed Secrets — 加密后可安全存入 Git(GitOps 场景)
  4. RBAC 最小权限 — 只有需要的 ServiceAccount 能读 Secret
  5. 审计日志 — 记录谁访问了 Secret

实验验证总结

操作结果
创建 ConfigMapapp-config 含 APP_ENV, LOG_LEVEL, DB_HOST
创建 Secretdb-creds 含 username, password(base64 编码)
解码 Secretecho <base64> | base64 -d 可直接还原明文

→ 03-statefulset-daemonset-job.md