0%

K8s 配置管理最佳实践:ConfigMap 和 Secret 完全指南

K8s 配置管理最佳实践:ConfigMap 和 Secret 完全指南

写在前面:这篇文章源于今晚(2026-03-10)的真实配置管理需求。OpenClaw 部署到 K8s 需要管理大量配置和敏感信息,如何安全、高效地管理这些配置是一个关键问题。


一、背景及痛点分析

1.1 真实场景

没有配置管理时的状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# ❌ 硬编码在 Deployment 中
apiVersion: apps/v1
kind: Deployment
metadata:
name: openclaw-gateway
spec:
template:
spec:
containers:
- name: openclaw
image: hb.test/crystalforge/openclaw:1.0.3
env:
- name: FEISHU_APP_ID
value: "cli_a9278e8369b89bc6" # ❌ 敏感信息硬编码
- name: FEISHU_APP_SECRET
value: "J9Zg52nIDrufyq4YbBNDjhZuh74XcOyK" # ❌ 更敏感
- name: DASHSCOPE_API_KEY
value: "sk-sp-c35236a57fff40f2afea663e9472bbd9" # ❌ API 密钥泄露

遇到的问题

  1. 安全风险

    • 敏感信息写在 YAML 中
    • Git 仓库可见所有密钥
    • 人员离职,密钥未轮换
  2. 配置混乱

    • 开发、测试、生产环境配置混用
    • 修改配置需要重新构建镜像
    • 配置变更无审计日志
  3. 管理困难

    • 多个应用配置分散
    • 无法统一更新
    • 故障排查找不到配置

1.2 配置分类

配置类型 示例 敏感度 管理方式
应用配置 日志级别、超时时间 ConfigMap
数据库连接 主机、端口、数据库名 ConfigMap
密码密钥 数据库密码、API Key Secret
证书 TLS 证书、CA 证书 Secret
Docker 凭证 Harbor 用户名密码 Secret

1.3 技术方案

方案 适用场景 安全性 复杂度
ConfigMap 非敏感配置 ⭐⭐
Secret 敏感配置 ⭐⭐⭐ ⭐⭐
Sealed Secrets GitOps 场景 ⭐⭐⭐⭐ ⭐⭐⭐
SOPS + Git 加密存储 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐
Vault 企业级密钥管理 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐

我们的选择

  • 非敏感配置:ConfigMap
  • 敏感配置:Secret + Sealed Secrets
  • GitOps 场景:Sealed Secrets(加密提交到 Git)

二、解决方案:分层配置管理

2.1 架构设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌─────────────────────────────────────────┐
│ K8s 配置管理体系 │
├─────────────────────────────────────────┤
│ │
│ 应用层 │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ ConfigMap │ │ Secret │ │
│ │ (非敏感) │ │ (敏感) │ │
│ └──────────────┘ └──────────────┘ │
│ ↓ ↓ │
│ ┌─────────────────────────────┐ │
│ │ Sealed Secrets │ │
│ │ (加密存储到 Git) │ │
│ └─────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────┐ │
│ │ K8s Controller │ │
│ │ (自动解密) │ │
│ └─────────────────────────────┘ │
│ │
└─────────────────────────────────────────┘

2.2 配置管理流程

1
2
3
4
5
6
7
8
9
10
11
1. 创建配置

2. 加密(如敏感)

3. 提交到 Git

4. ArgoCD/GitOps 同步

5. K8s 自动解密

6. 应用使用配置

三、最佳实践案例

3.1 ConfigMap 管理

创建方式 1:从字面值创建

1
2
3
4
5
6
7
8
9
# 创建 ConfigMap
kubectl create configmap openclaw-config \
--from-literal=LOG_LEVEL=info \
--from-literal=TIMEOUT=30s \
--from-literal=MAX_CONNECTIONS=100 \
-n openclaw

# 验证
kubectl get configmap openclaw-config -n openclaw -o yaml

创建方式 2:从文件创建

1
2
3
4
5
6
7
8
9
10
11
12
# 准备配置文件
cat > openclaw.properties <<EOF
server.port=3000
server.host=0.0.0.0
log.level=info
timeout=30s
EOF

# 创建 ConfigMap
kubectl create configmap openclaw-config \
--from-file=openclaw.properties \
-n openclaw

创建方式 3:从 YAML 创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: openclaw-config
namespace: openclaw
labels:
app: openclaw
data:
LOG_LEVEL: "info"
TIMEOUT: "30s"
MAX_CONNECTIONS: "100"
openclaw.json: |
{
"models": {
"default": "bailian/qwen3.5-plus"
},
"channels": {
"feishu": {
"enabled": true
}
}
}
1
2
# 应用配置
kubectl apply -f configmap.yaml

在 Pod 中使用 ConfigMap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apiVersion: apps/v1
kind: Deployment
metadata:
name: openclaw-gateway
spec:
template:
spec:
containers:
- name: openclaw
image: hb.test/crystalforge/openclaw:1.0.3

# 方式 1:作为环境变量
envFrom:
- configMapRef:
name: openclaw-config

# 方式 2:作为文件挂载
volumeMounts:
- name: config-volume
mountPath: /etc/openclaw
readOnly: true

volumes:
- name: config-volume
configMap:
name: openclaw-config

3.2 Secret 管理

创建方式 1:从字面值创建

1
2
3
4
5
6
7
8
9
10
11
12
13
# 创建 Secret
kubectl create secret generic openclaw-secrets \
--from-literal=FEISHU_APP_ID=cli_a9278e8369b89bc6 \
--from-literal=FEISHU_APP_SECRET=J9Zg52nIDrufyq4YbBNDjhZuh74XcOyK \
--from-literal=DASHSCOPE_API_KEY=sk-sp-c35236a57fff40f2afea663e9472bbd9 \
-n openclaw

# 验证
kubectl get secret openclaw-secrets -n openclaw
# 输出:openclaw-secrets Opaque 3 10s

# 查看内容(base64 解码)
kubectl get secret openclaw-secrets -n openclaw -o jsonpath='{.data}' | jq

创建方式 2:从文件创建

1
2
3
4
5
6
7
8
9
# 准备敏感文件
echo -n "admin" > username.txt
echo -n "SuperSecret123" > password.txt

# 创建 Secret
kubectl create secret generic db-credentials \
--from-file=username=username.txt \
--from-file=password=password.txt \
-n openclaw

创建方式 3:Docker Registry Secret

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 创建 Harbor 认证 Secret
kubectl create secret docker-registry harbor-secret \
--docker-server=hb.test \
--docker-username=crystalcreator \
--docker-password='glpat-FxE8Ka5HaApPLHnAQDtz' \
--docker-email=admin@example.com \
-n openclaw

# 在 Deployment 中使用
# deployment.yaml
spec:
template:
spec:
imagePullSecrets:
- name: harbor-secret

创建方式 4:TLS Secret

1
2
3
4
5
6
7
8
9
10
11
12
13
# 创建 TLS Secret
kubectl create secret tls openclaw-tls \
--cert=path/to/tls.crt \
--key=path/to/tls.key \
-n openclaw

# 在 Ingress 中使用
# ingress.yaml
spec:
tls:
- hosts:
- openclaw.example.com
secretName: openclaw-tls

3.3 Sealed Secrets(GitOps 友好)

安装 Sealed Secrets

1
2
3
4
5
6
7
8
9
10
11
# 添加 Helm 仓库
helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets
helm repo update

# 安装 Sealed Secrets Controller
helm install sealed-secrets sealed-secrets/sealed-secrets \
--namespace kube-system

# 验证
kubectl get pods -n kube-system | grep sealed-secrets
# 输出:sealed-secrets-controller-xxx 1/1 Running

安装 kubeseal 客户端

1
2
3
4
5
6
7
8
9
# 下载
wget https://github.com/bitnami-labs/sealed-secrets/releases/latest/download/kubeseal-linux-amd64

# 安装
sudo mv kubeseal-linux-amd64 /usr/local/bin/kubeseal
sudo chmod +x /usr/local/bin/kubeseal

# 验证
kubeseal --version

创建 Sealed Secret

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1. 创建普通 Secret(不应用到集群)
kubectl create secret generic openclaw-secrets \
--from-literal=FEISHU_APP_ID=cli_a9278e8369b89bc6 \
--from-literal=FEISHU_APP_SECRET=J9Zg52nIDrufyq4YbBNDjhZuh74XcOyK \
--dry-run=client -o yaml > secret.yaml

# 2. 使用 kubeseal 加密
kubeseal --format yaml < secret.yaml > sealed-secret.yaml

# 3. 提交到 Git
git add sealed-secret.yaml
git commit -m "Add sealed secret for OpenClaw"
git push

# 4. 应用到集群(ArgoCD 会自动同步)
kubectl apply -f sealed-secret.yaml

Sealed Secret 优势

特性 Secret Sealed Secret
Git 存储 ❌ 不安全 ✅ 加密安全
版本控制 ❌ 不推荐 ✅ 推荐
代码审查 ❌ 泄露风险 ✅ 安全审查
灾难恢复 ❌ 需要备份 ✅ Git 即备份

3.4 配置更新策略

ConfigMap 热更新

1
2
3
4
5
6
7
8
# 1. 更新 ConfigMap
kubectl patch configmap openclaw-config \
-n openclaw \
--type='json' \
-p='[{"op": "replace", "path": "/data/LOG_LEVEL", "value": "debug"}]'

# 2. 应用自动重新加载(需要应用支持)
# OpenClaw 会监听 ConfigMap 变化并自动重载

Secret 轮换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. 创建新 Secret
kubectl create secret generic openclaw-secrets-v2 \
--from-literal=FEISHU_APP_SECRET=NewSecret123 \
-n openclaw

# 2. 更新 Deployment 引用
kubectl set env deployment/openclaw-gateway \
--from=secret/openclaw-secrets-v2 \
-n openclaw

# 3. 验证
kubectl rollout status deployment/openclaw-gateway -n openclaw

# 4. 删除旧 Secret
kubectl delete secret openclaw-secrets -n openclaw

四、深度思考体会

4.1 为什么需要 Sealed Secrets?

传统 Secret 的问题

1
2
3
4
5
# ❌ Secret 只是 base64 编码,不是加密
apiVersion: v1
kind: Secret
data:
password: U3VwZXJTZWNyZXQxMjM= # 任何人都可以解码

base64 解码

1
2
echo "U3VwZXJTZWNyZXQxMjM=" | base64 -d
# 输出:SuperSecret123

Sealed Secrets 的优势

1
2
3
4
5
6
7
8
# ✅ 使用非对称加密
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: openclaw-secrets
spec:
encryptedData:
FEISHU_APP_SECRET: AgBy8hCi... # 只有 Controller 能解密

我的理解

Sealed Secrets = GitOps 友好的 Secret。可以安全地提交到 Git,由 Controller 在集群内解密。

4.2 配置管理的核心原则

1. 分离原则

  • 配置与代码分离
  • 敏感与非敏感分离
  • 环境与配置分离

2. 安全原则

  • 最小权限访问
  • 定期轮换密钥
  • 审计所有变更

3. 自动化原则

  • GitOps 自动同步
  • 自动轮换
  • 自动告警

4.3 配置版本控制

Git 分支策略

1
2
3
4
5
main (生产环境)

staging (测试环境)

develop (开发环境)

配置目录结构

1
2
3
4
5
6
7
8
9
10
11
config/
├── base/ # 基础配置(所有环境共享)
│ ├── configmap.yaml
│ └── secret-template.yaml
├── overlays/
│ ├── dev/ # 开发环境
│ │ └── config-patch.yaml
│ ├── staging/ # 测试环境
│ │ └── config-patch.yaml
│ └── prod/ # 生产环境
│ └── config-patch.yaml

五、踩坑记录

5.1 坑 1:ConfigMap 更新不生效

问题

1
2
3
4
# 更新 ConfigMap
kubectl patch configmap openclaw-config ...

# Pod 没有重新加载

原因

  • ConfigMap 作为环境变量注入时,不会自动更新
  • 需要重启 Pod

解决

1
2
3
4
5
# 方式 1:重启 Pod
kubectl rollout restart deployment/openclaw-gateway -n openclaw

# 方式 2:使用文件挂载 + 热重载
# 应用监听文件变化,自动重新加载

5.2 坑 2:Secret 大小写问题

问题

1
2
3
4
5
6
7
8
9
10
kubectl create secret generic my-secret \
--from-literal=API_KEY=abc123

# 在 Pod 中引用
env:
- name: API_KEY
valueFrom:
secretKeyRef:
name: my-secret
key: api_key # ❌ 小写,找不到

错误

1
Error: secret "my-secret" not found

解决

1
2
3
4
5
6
7
# 确保 key 名称完全匹配
env:
- name: API_KEY
valueFrom:
secretKeyRef:
name: my-secret
key: API_KEY # ✅ 大小写一致

5.3 坑 3:Sealed Secrets 解密失败

问题

1
2
3
kubectl apply -f sealed-secret.yaml

# SealedSecret 创建成功,但 Secret 没有创建

原因

  • Sealed Secrets Controller 未运行
  • 密钥不匹配(不同集群)

解决

1
2
3
4
5
6
7
8
# 1. 检查 Controller
kubectl get pods -n kube-system | grep sealed-secrets

# 2. 查看日志
kubectl logs -n kube-system sealed-secrets-controller-xxx

# 3. 如果是新集群,需要重新加密
kubeseal --re-encrypt < sealed-secret.yaml > new-sealed-secret.yaml

六、总结

6.1 核心要点

  1. ConfigMap - 非敏感配置,支持热更新
  2. Secret - 敏感配置,base64 编码
  3. Sealed Secrets - 加密 Secret,GitOps 友好
  4. 配置分离 - 代码与配置分离,环境分离
  5. 安全轮换 - 定期更新密钥,审计变更

6.2 实战经验

这篇文章是今晚 45 分钟实战的总结

  • 创建 ConfigMap 和 Secret
  • 部署 Sealed Secrets Controller
  • 配置 GitOps 流程
  • 记录踩坑经验

6.3 后续计划

本周

  • 所有配置迁移到 ConfigMap/Secret
  • 敏感信息使用 Sealed Secrets
  • 配置 GitOps 自动同步

本月

  • 实现自动密钥轮换
  • 配置审计日志
  • 建立配置管理规范

本季度

  • 集成 Vault(企业级)
  • 配置自动备份
  • 定期安全审计

作者:John,高级技术架构师,CrystalForge 项目负责人
时间:2026-03-11 01:50
地点:深圳
项目:OpenClaw K8s 配置管理实战