IMPLEMENTATION_GUIDE.md 14 KB

Kubernetes Secret 和 ConfigMap 实施指南

目录

  1. 快速开始
  2. 详细步骤
  3. 验证清单
  4. 故障排查
  5. 维护操作

快速开始

前置条件

  • Kubernetes 集群已部署(v1.19+)
  • kubectl 已配置并可访问集群
  • PowerShell 5.1+ (Windows) 或 bash (Linux/Mac)
  • 所有敏感信息已准备好

第一步:生成配置文件

# 1. 进入 helm 目录
cd d:\coding-area\devops\helm

# 2. 运行生成脚本
powershell -ExecutionPolicy Bypass -File generate-secrets.ps1 `
  -OutputDir "d:\coding-area\devops\helm\kubernetes-secrets" `
  -Namespace "production"

# 3. 查看生成的文件
ls kubernetes-secrets\secrets\
ls kubernetes-secrets\configmaps\

第二步:配置敏感信息

# 编辑每个 Secret 文件,替换占位符
# 示例:
cd kubernetes-secrets/secrets

# 使用您偏好的编辑器打开文件
# 将 ${DB_USERNAME} 替换为实际的用户名
# 将 ${DB_PASSWORD} 替换为实际的密码

vim shop-recycle-payment-web-secret.yaml

第三步:验证 YAML 语法

# 验证所有 Secret YAML
for file in secrets/*.yaml; do
  kubectl apply -f "$file" --dry-run=client
done

# 验证所有 ConfigMap YAML
for file in configmaps/*.yaml; do
  kubectl apply -f "$file" --dry-run=client
done

第四步:应用到集群

# 切换到正确的命名空间
kubectl config set-context --current --namespace=production

# 应用 Secrets
kubectl apply -f kubernetes-secrets/secrets/

# 应用 ConfigMaps
kubectl apply -f kubernetes-secrets/configmaps/

# 验证
kubectl get secrets | grep shop-recycle
kubectl get configmaps | grep shop-recycle

详细步骤

步骤 1:环境准备

1.1 检查 Kubernetes 版本

kubectl version --client
kubectl version --short

# 预期输出: v1.19.x 或更高版本

1.2 检查集群连接

kubectl cluster-info
kubectl get nodes

# 预期输出: 应该看到多个节点

1.3 创建或切换命名空间

# 创建 production 命名空间
kubectl create namespace production

# 或,如果已存在,切换到该命名空间
kubectl config set-context --current --namespace=production

# 验证
kubectl get namespace production

步骤 2:生成并配置 Secret

2.1 运行生成脚本

$config = @{
  OutputDir = "d:\coding-area\devops\helm\kubernetes-secrets"
  Namespace = "production"
}

& "d:\coding-area\devops\helm\generate-secrets.ps1" @config

2.2 审查生成的文件

# 查看生成的 Secret 列表
ls kubernetes-secrets/secrets/ | head -10

# 示例输出:
# shop-recycle-account-secret.yaml
# shop-recycle-agent-pc-web-secret.yaml
# ...

2.3 编辑 Secret 文件

# 打开第一个 Secret 文件进行编辑
vim kubernetes-secrets/secrets/shop-recycle-account-secret.yaml

示例 Secret 内容(编辑前):

apiVersion: v1
kind: Secret
metadata:
  name: shop-recycle-account-secret
  namespace: production
type: Opaque
stringData:
  server: "${SERVER_HOST}"
  username: "${DB_USERNAME}"
  password: "${DB_PASSWORD}"
  host: "${DB_HOST}"
  url: "${DB_URL}"
  userName: "${DB_USER_NAME}"

示例 Secret 内容(编辑后):

apiVersion: v1
kind: Secret
metadata:
  name: shop-recycle-account-secret
  namespace: production
type: Opaque
stringData:
  server: "192.168.1.10"
  username: "db_account_user"
  password: "MySecurePassword123!"
  host: "mysql-master.internal"
  url: "jdbc:mysql://mysql-master.internal:3306/shop_recycle_account"
  userName: "db_account_user"

2.4 创建 Secret 编辑脚本(可选但推荐)

# create-secrets-interactive.ps1
# 交互式创建 Secret

$services = @(
    'shop-recycle-account',
    'shop-recycle-payment-web',
    'shop-recycle-merchant-wechat-web'
    # ... 其他服务
)

foreach ($service in $services) {
    Write-Host "Configuring $service..." -ForegroundColor Yellow
    
    $username = Read-Host "  Database Username"
    $password = Read-Host "  Database Password" -AsSecureString
    $host = Read-Host "  Database Host"
    
    # 保存到环境或配置文件
    # ...
}

步骤 3:应用 Secret 到 Kubernetes

3.1 干运行(验证不出错)

# 验证单个 Secret
kubectl apply -f kubernetes-secrets/secrets/shop-recycle-account-secret.yaml --dry-run=client -o yaml

# 预期输出: 完整的 YAML,无错误信息

3.2 实际应用

# 应用所有 Secrets
kubectl apply -f kubernetes-secrets/secrets/

# 输出示例:
# secret/shop-recycle-account-secret created
# secret/shop-recycle-payment-web-secret created
# ...

3.3 验证 Secret 创建

# 列出所有 Secrets
kubectl get secrets -n production | grep shop-recycle

# 输出示例:
# NAME                                  TYPE      DATA   AGE
# shop-recycle-account-secret           Opaque    6      2m
# shop-recycle-payment-web-secret       Opaque    11     2m
# ...

# 查看特定 Secret 的详细信息
kubectl describe secret shop-recycle-account-secret -n production

# 获取 Secret 的实际值(小心!包含敏感信息)
kubectl get secret shop-recycle-account-secret -o yaml -n production

步骤 4:应用 ConfigMap 到 Kubernetes

4.1 应用 ConfigMaps

# 应用所有 ConfigMaps
kubectl apply -f kubernetes-secrets/configmaps/

# 验证
kubectl get configmaps -n production | grep shop-recycle

步骤 5:更新 Pod/Deployment

5.1 创建引用 Secret 的 Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: shop-recycle-payment-web
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: shop-recycle-payment-web
  template:
    metadata:
      labels:
        app: shop-recycle-payment-web
    spec:
      containers:
      - name: payment-web
        image: registry.example.com/shop-recycle/payment-web:1.0.0
        ports:
        - containerPort: 8080
        
        # 从 Secret 读取敏感信息
        env:
        - name: SPRING_DATASOURCE_USERNAME
          valueFrom:
            secretKeyRef:
              name: shop-recycle-payment-web-secret
              key: username
        - name: SPRING_DATASOURCE_PASSWORD
          valueFrom:
            secretKeyRef:
              name: shop-recycle-payment-web-secret
              key: password
        - name: WECHAT_APP_ID
          valueFrom:
            secretKeyRef:
              name: shop-recycle-payment-web-secret
              key: wechat-app-id
        
        # 从 ConfigMap 读取非敏感配置
        envFrom:
        - configMapRef:
            name: shop-recycle-payment-web-configmap

5.2 应用 Deployment

# 应用 Deployment
kubectl apply -f deployment.yaml

# 检查 Pod 状态
kubectl get pods -n production -l app=shop-recycle-payment-web

# 查看 Pod 日志
kubectl logs -n production -l app=shop-recycle-payment-web --tail=50

验证清单

部署前检查

  • 所有 Secret 文件已编辑(没有 ${} 占位符)
  • 所有 YAML 文件通过了语法检查
  • 数据库连接信息已验证
  • WeChat API 凭证已验证
  • 备份了原始配置文件
  • 测试环境已验证配置

部署后验证

# 检查 Secret 是否正确创建
kubectl get secrets -n production
kubectl describe secret <secret-name> -n production

# 检查 ConfigMap 是否正确创建
kubectl get configmaps -n production
kubectl describe configmap <configmap-name> -n production

# 检查 Pod 是否能正确读取 Secret
kubectl exec -it <pod-name> -n production -- env | grep DB_

# 检查应用日志
kubectl logs -n production <pod-name>
kubectl logs -n production <pod-name> --previous  # 如果 Pod 已重启

# 检查 Pod 事件
kubectl describe pod <pod-name> -n production

# 运行健康检查
kubectl exec -it <pod-name> -n production -- curl http://localhost:8080/health

性能检查

# 检查 Pod 资源使用情况
kubectl top pods -n production

# 检查节点资源使用情况
kubectl top nodes

故障排查

问题 1:Secret 不能被读取

症状: Pod 无法访问环境变量

排查步骤:

# 1. 检查 Secret 是否存在
kubectl get secret <secret-name> -n production

# 2. 检查 Secret 内容
kubectl get secret <secret-name> -o yaml -n production

# 3. 检查 Pod 定义中的 Secret 引用
kubectl get pod <pod-name> -o yaml -n production | grep -A 10 "secretKeyRef"

# 4. 查看 Pod 日志
kubectl logs <pod-name> -n production

解决方案:

  • 确保 Secret 名称与 Deployment 中的引用一致
  • 确保 Secret 密钥名称与 Deployment 中的 key 一致
  • 确保 Secret 在相同的命名空间中

问题 2:ConfigMap 更新不生效

症状: 应用仍使用旧配置

排查步骤:

# 1. 检查 ConfigMap 是否已更新
kubectl get configmap <name> -o yaml -n production

# 2. 检查 Pod 挂载点
kubectl exec <pod-name> -n production -- cat /etc/config/app.properties

# 3. 查看 Pod 的挂载卷
kubectl describe pod <pod-name> -n production | grep -A 5 "Mounts"

解决方案:

  • ConfigMap 更改后需要重新启动 Pod
  • 使用以下命令强制重启: bash kubectl rollout restart deployment/<deployment-name> -n production

问题 3:权限被拒绝

症状: Error: secrets is forbidden

排查步骤:

# 1. 检查当前用户权限
kubectl auth can-i get secrets --as=<user>

# 2. 检查 Role 和 RoleBinding
kubectl get role -n production
kubectl get rolebinding -n production

解决方案:

  • 确保用户有正确的 RBAC 权限
  • 应用正确的 Role 和 RoleBinding

问题 4:Secret 数据损坏或丢失

症状: 数据不完整或无法解码

排查步骤:

# 1. 检查 Secret 原始数据
kubectl get secret <name> -o json -n production | jq .data

# 2. 尝试解码 Base64
echo "<base64-string>" | base64 -d

解决方案:

  • 从备份恢复 Secret
  • 重新创建 Secret

维护操作

定期任务

周任务

# 每周备份所有 Secrets
kubectl get secrets -n production -o yaml > backup-secrets-$(date +%Y%m%d).yaml

# 检查 Secret 访问审计日志
kubectl get events -n production | grep secret

月任务

# 月度安全审计
# 1. 检查所有 Secrets 的所有权
kubectl get secrets -n production -o wide

# 2. 检查过期的凭证
kubectl describe secret -n production

# 3. 更新任何过期的凭证

更新操作

更新单个 Secret

# 方法 1:直接编辑
kubectl edit secret <secret-name> -n production

# 方法 2:使用 kubectl set
kubectl create secret generic <secret-name> \
  --from-literal=key=newvalue \
  --dry-run=client -o yaml | kubectl apply -f -

# 方法 3:删除并重新创建
kubectl delete secret <secret-name> -n production
kubectl apply -f <secret-file>.yaml

更新 Secret 后重启 Pod

# 强制重启 Deployment 中的所有 Pod
kubectl rollout restart deployment/<deployment-name> -n production

# 检查重启状态
kubectl rollout status deployment/<deployment-name> -n production

轮换操作

实施 Secret 轮换

# 1. 创建新的 Secret(新版本)
kubectl create secret generic <secret-name>-v2 \
  --from-literal=... \
  -n production

# 2. 更新 Deployment 使用新 Secret
kubectl set env deployment/<deployment-name> \
  SECRET_VERSION=v2 \
  -n production

# 3. 重启 Pod
kubectl rollout restart deployment/<deployment-name> -n production

# 4. 验证新 Pod 使用新 Secret
kubectl logs -n production <new-pod-name>

# 5. 删除旧 Secret(确认无问题后)
kubectl delete secret <secret-name>-v1 -n production

监控操作

启用 Secret 访问审计

# 1. 查看最近的 Secret 访问
kubectl get events -n production --field-selector type=Normal

# 2. 搜索 Secret 相关事件
kubectl get events -n production | grep -i secret

# 3. 启用详细日志
kubectl logs -n kube-system -l component=apiserver | grep secret

恢复操作

从备份恢复 Secret

# 1. 列出备份文件
ls backup-secrets-*.yaml

# 2. 检查备份内容
cat backup-secrets-20240116.yaml | grep -A 5 "kind: Secret"

# 3. 恢复特定 Secret
kubectl apply -f backup-secrets-20240116.yaml

# 4. 验证恢复
kubectl get secrets -n production

安全最佳实践

1. 最小权限原则

# 只给应用必要的权限
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: secret-reader-limited
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get"]  # 只读权限,不允许列表、删除等
  resourceNames:  # 限制到特定 Secret
  - "shop-recycle-payment-web-secret"

2. Secret 加密

# 启用 etcd 加密
# 在 kube-apiserver 配置中添加:
--encryption-provider-config=/etc/kubernetes/encryption.yaml

3. 审计日志

# 启用 API 审计
--audit-log-path=/var/log/kubernetes/audit.log
--audit-log-maxage=30
--audit-log-maxbackup=3

4. 定期轮换

  • 数据库密码:每 90 天
  • API 密钥:每 180 天
  • Token:每 30 天

5. 备份和恢复

# 自动备份脚本
#!/bin/bash
for ns in production staging dev; do
  kubectl get secrets -n $ns -o yaml > /backup/secrets-$ns-$(date +%Y%m%d).yaml
  kubectl get configmaps -n $ns -o yaml > /backup/configmaps-$ns-$(date +%Y%m%d).yaml
done

常见命令参考

# Secret 操作
kubectl get secrets -n production
kubectl describe secret <name> -n production
kubectl delete secret <name> -n production
kubectl edit secret <name> -n production

# ConfigMap 操作
kubectl get configmaps -n production
kubectl describe configmap <name> -n production
kubectl create configmap <name> --from-file=/path
kubectl patch configmap <name> -p='{"data":{"key":"value"}}'

# Pod 操作
kubectl get pods -n production
kubectl logs -n production <pod-name>
kubectl exec -it <pod-name> -n production -- /bin/bash
kubectl env pod <pod-name> -n production

# Deployment 操作
kubectl get deployment -n production
kubectl rollout restart deployment/<name> -n production
kubectl rollout status deployment/<name> -n production
kubectl scale deployment/<name> --replicas=3 -n production

联系和支持

如有问题,请参考:


文档版本: 1.0
最后更新: 2026-01-16
适用版本: Kubernetes 1.19+