运维实战

Kubernetes 配置与身份:ConfigMap、Secret、ServiceAccount 实战

区分非敏感配置、Secret 与工作负载身份,掌握挂载、轮换、变更触发和最小权限发布流程。

TY
Tycho
技术博主
• 2026-09-16 • 20 分钟阅读 • 1 次浏览
Kubernetes 配置与身份:ConfigMap、Secret、ServiceAccount 实战

实验基线:Kubernetes v1.37.0、kubectl v1.37.0。先在测试环境执行,记录变更前状态与回滚点;生产集群不得直接照抄节点地址、网段、存储类或资源额度。

配置、秘密与身份是三件事

ConfigMap 保存非敏感配置;Secret 的 base64 只是编码,不等于加密;ServiceAccount 为 Pod 提供集群身份。生产环境还需要 etcd 静态加密、外部密钥系统、访问审计与轮换流程。

创建并消费配置

kubectl create configmap app-config -n lab --from-literal=LOG_LEVEL=info
kubectl create secret generic db-credential -n lab \
  --from-literal=username=app --from-literal=password='replace-me'
kubectl create serviceaccount app -n lab
kubectl get configmap app-config -n lab -o yaml
kubectl get secret db-credential -n lab -o jsonpath='{.data.username}' | base64 -d

命令历史可能泄漏密码,真实环境应从受控文件或外部秘密管理系统导入,并及时清理。不要把 Secret 明文提交到 Git。

挂载与轮换规则

spec:
  serviceAccountName: app
  automountServiceAccountToken: false
  containers:
  - name: app
    image: nginx:1.27-alpine
    envFrom:
    - configMapRef: {name: app-config}
    volumeMounts:
    - name: credential
      mountPath: /run/secrets/app
      readOnly: true
  volumes:
  - name: credential
    secret:
      secretName: db-credential
      defaultMode: 0400

环境变量不会自动刷新;卷投射最终会更新,但应用是否重载取决于自身实现。推荐对配置内容计算哈希并放入 Pod 模板注解,以触发可审计的滚动发布。只有确实调用 Kubernetes API 的工作负载才开启令牌自动挂载。

从文件生成配置,避免手工转义

kubectl create configmap app-config -n lab \
  --from-file=application.yaml=./application.yaml \
  --dry-run=client -o yaml > app-config.yaml
kubectl diff -f app-config.yaml
kubectl apply -f app-config.yaml

将生成的 YAML 审阅后提交版本库。ConfigMap 单个对象不适合存放大文件;二进制与大型配置应放对象存储或镜像,并记录不可变版本。

环境变量与卷更新差异

方式变更后适用
env/envFrom已运行进程不会更新启动期固定配置
volumekubelet 最终更新投射文件应用支持文件重载
subPath不会收到自动更新明确接受重启生效

发布流水线可计算配置哈希并写入 Pod template annotation,从而触发受控滚动更新。

Secret 安全操作

umask 077
kubectl create secret generic db-credential -n lab \
  --from-env-file=.secret.env --dry-run=client -o yaml > /tmp/db-secret.yaml
kubectl apply -f /tmp/db-secret.yaml
shred -u /tmp/db-secret.yaml

macOS 不一定提供 shred,应改用受控临时目录并安全清理。生产更推荐 External Secrets/CSI 驱动等外部密钥集成。轮换时采用“双凭据窗口”:先让服务接受新旧凭据,再更新消费者,确认旧凭据无流量后撤销。

ServiceAccount 最小化

spec:
  serviceAccountName: app
  automountServiceAccountToken: false

若应用确需访问 API,可显式投射短期令牌并设置 audience 与 expirationSeconds;再用 Role/RoleBinding 限制资源、动词、命名空间和 resourceNames。执行:

kubectl auth can-i get configmap/app-config -n lab --as=system:serviceaccount:lab:app
kubectl auth can-i list secrets -n lab --as=system:serviceaccount:lab:app

第一条应按设计允许,第二条必须拒绝。把正向和反向权限测试加入发布门禁。

完整工作负载示例与配置发布

apiVersion: apps/v1
kind: Deployment
metadata: {name: app, namespace: lab}
spec:
  replicas: 2
  selector: {matchLabels: {app: app}}
  template:
    metadata:
      labels: {app: app}
      annotations: {config.checksum: "replace-with-real-sha256"}
    spec:
      serviceAccountName: app
      automountServiceAccountToken: false
      containers:
      - name: app
        image: nginx:1.27-alpine
        env: [{name: LOG_LEVEL, valueFrom: {configMapKeyRef: {name: app-config, key: LOG_LEVEL}}}]
        volumeMounts: [{name: credential, mountPath: /run/secrets/app, readOnly: true}]
      volumes: [{name: credential, secret: {secretName: db-credential, defaultMode: 0400}}]
HASH=$(kubectl get configmap app-config -n lab -o json | sha256sum | cut -d' ' -f1)
kubectl patch deployment app -n lab --type=merge \
  -p "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"config.checksum\":\"$HASH\"}}}}}"
kubectl rollout status deployment/app -n lab

GitOps/Helm 环境应在渲染阶段生成哈希,而不是由终端临时 patch;这里用于解释触发原理。

短期 API 令牌

确需访问 API 时,显式投射有 audience 与过期时间的令牌,避免长期 Secret 令牌:

volumes:
- name: api-token
  projected:
    sources:
    - serviceAccountToken:
        path: token
        audience: my-api
        expirationSeconds: 3600

服务端必须校验 audience。轮换演练应验证旧令牌过期、新令牌自动刷新以及 API 暂时不可用时应用的容错行为。

可复现记录模板

每次实验记录:集群版本、容器运行时、CNI/CSI 版本、命名空间、使用的 YAML Git 提交、开始与结束时间。命令输出至少保留对象状态、事件、关键日志和回滚结果。文中的占位符必须替换成自己的值,生产执行前应由第二人复核。

故障处理原则

  1. 先缩小影响面,不删除现场。
  2. 按对象状态—事件—日志—依赖顺序收集证据。
  3. 提出可证伪假设,一次只改变一个变量。
  4. 验证恢复后清理临时权限、调试 Pod、端口转发和测试数据。

完成检查

  • 命令退出码为 0,目标对象状态与预期一致。
  • 保存执行前后 YAML、事件与关键日志,确认没有把测试命名空间以外的对象改动。
  • 故障演练完成后执行清理或回滚,再进行下一章。

官方资料

TY

Tycho

热爱分享技术知识,帮助开发者成长。

评论 (0)

评论功能当前已关闭
暂无评论,快来抢沙发吧!