第 8 / 18 篇

第 7 章 ConfigMap 与 Secret:把配置移出镜像

为什么配置不应全部写进镜像

同一份程序在开发和生产可能使用不同的欢迎语、日志级别或数据库地址。如果每改一行配置就重新打包镜像,维护会变得笨重。ConfigMap 存放非敏感配置,Secret 用来承载需要谨慎处理的数据,例如令牌或密码。

本章把网页内容放进 ConfigMap。保存为 configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: hello-page
data:
  index.html: |
    <!doctype html>
    <html lang="zh-CN">
      <meta charset="utf-8">
      <title>我的 Kubernetes 小站</title>
      <h1>你好,Kubernetes!</h1>
      <p>这是我通过 ConfigMap 提供的第一个网页。</p>
    </html>

竖线 | 表示保留换行的多行文本。先创建 ConfigMap,下一章的完整 Deployment 会把它挂载到 NGINX 默认网页目录。

kubectl apply -n k8s-book -f configmap.yaml
kubectl get configmap hello-page -n k8s-book

两种常见注入方式

配置可以作为环境变量,也可以以卷挂载成文件。环境变量在容器启动时读取,修改 ConfigMap 后,已有容器的环境变量不会自动刷新,通常需要重新创建 Pod。普通 ConfigMap 卷的文件更新通常会经过一定延迟传播,应用是否重新读取还取决于自身行为;使用 subPath 挂载时,不会收到这类自动更新。

本书整目录挂载网页,不使用 subPath。初学阶段,为了明确结果,修改 ConfigMap 后可以执行滚动重启,让所有副本重新读取配置。

Secret 的边界

kubectl create secret generic demo-secret -n k8s-book \
  --from-literal=DEMO_TOKEN=only-for-practice

这里刻意使用无价值的练习字符串。真实机密不要直接留在命令历史、聊天记录或公开 Git 仓库中。Secret 的 data 常以 Base64 表示,Base64 是编码,不是加密。是否启用存储加密、谁有权限读取 Secret,都需要单独配置。

环境变量引用片段如下,阅读理解即可,不必加入本书网页项目:

env:
  - name: DEMO_TOKEN
    valueFrom:
      secretKeyRef:
        name: demo-secret
        key: DEMO_TOKEN

这段片段应放在某个容器定义下。它不是可以独立 apply 的完整资源。实验后可删除示例 Secret:

kubectl delete secret demo-secret -n k8s-book

本章自测:把密码做 Base64 后放进公开仓库安全吗?修改 ConfigMap 后,已有容器的环境变量会立即改变吗?