K8S-DEPLOYMENT-GUIDE.md 13 KB

Kubernetes 配置管理完整实施指南

📋 目录

  1. 快速开始
  2. 配置结构
  3. 分步部署
  4. 故障排查
  5. 最佳实践

🚀 快速开始

前置条件

  • Kubernetes 集群已就绪
  • kubectl 已配置
  • 有权访问 Secret
  • 了解基本的 K8S 概念(ConfigMap, Secret, Deployment)

生成的文件

d:\coding-area\devops\helm\
├── CONFIG-AND-SECRET-STRATEGY.md              # 配置策略分析文档
├── secret-templates-common.yaml               # 共享 Secret 模板(7 个)
├── service-configmap-deployment-template.yaml # 通用模板库
├── generate-k8s-manifests.sh                  # 自动生成脚本
└── conf/
    └── shop-recycle-[service]/
        └── conf/
            ├── application.yml                # 原始配置文件
            └── application.properties         # 原始配置文件

🗂️ 配置结构

Secret 分类

1. 公共 Secret(所有服务共用)

common-db-credentials - 数据库凭证

数据库用户名: root
数据库密码: Fxjxtdacf8f_a3d_202600104d6c_41
数据库主机: rm-bp19t90t7u8n5b0fh.mysql.rds.aliyuncs.com
数据库端口: 3306

使用服务: 26 个数据库服务

common-redis-credentials - Redis 凭证

Redis 密码: 3sm_redis
Redis 数据库: 15
Redis Sentinel Master: mymaster
Redis Sentinel 节点: redis.jxfx[1-3].com:27000

使用服务: 30+ 个服务(几乎所有)

common-rabbitmq-credentials - RabbitMQ 凭证

RabbitMQ 用户名: guest
RabbitMQ 密码: guest
RabbitMQ 主机: mq.bak.com
RabbitMQ 端口: 5672

使用服务: 20+ 个服务

wechat-credentials - 微信凭证

门店: store-app-id, store-app-secret
商户: merchant-app-id, merchant-app-secret
代卖: buy-app-id, buy-app-secret
AI宝: aibao-app-id, aibao-app-secret

使用服务: 5 个微信相关服务

nacos-credentials - Nacos 凭证

Nacos 用户名: nacos
Nacos 密码: nacos
Nacos 服务地址: nacos.bak.com:8848

使用服务: 所有服务

seata-credentials - Seata 凭证

Seata 用户名: nacos
Seata 密码: nacos
Seata 服务地址: nacos.bak.com:8848

使用服务: 2-3 个微服务

mongodb-credentials - MongoDB 凭证

MongoDB 用户名: root
MongoDB 密码: 123456
MongoDB 主机: mg.bak.com
MongoDB 端口: 27017
MongoDB 数据库: recycle

使用服务: 2-3 个微服务

ConfigMap 分类

[service-name]-config - 每个服务一个

application.yml       # 完整配置(敏感字段使用环境变量占位符)
application.properties # 简化配置

🔄 分步部署

第 1 步:创建 Secret

# 1. 编辑 secret-templates-common.yaml 替换实际的敏感信息
# 注意:文件中的 Base64 值需要改为实际值

# 2. 生成 Base64 编码的凭证(示例)
echo -n "root" | base64
# 输出: cm9vdA==

# 3. 部署所有共享 Secret
kubectl apply -f secret-templates-common.yaml

# 4. 验证
kubectl get secrets
kubectl describe secret common-db-credentials

第 2 步:为每个服务创建 ConfigMap

对于每个服务,创建一个 ConfigMap YAML:

# 示例:为 shop-recycle-payment 创建 ConfigMap
cat > shop-recycle-payment-configmap.yaml << 'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
  name: shop-recycle-payment-config
  namespace: default
  labels:
    app: shop-recycle-payment
    config-type: public
data:
  application.yml: |
    server:
      port: 1218
    spring:
      application:
        name: shop-recycle-payment-service
      datasource:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://${DB_HOST}:3306/shop_recycle_payment?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=CTT
        username: ${DB_USERNAME}
        password: ${DB_PASSWORD}
        hikari:
          connection-timeout: 30000
          maximum-pool-size: 10
          minimum-idle: 1
      redis:
        sentinel:
          master: mymaster
          nodes:
            - redis.jxfx1.com:27000
            - redis.jxfx2.com:27000
            - redis.jxfx3.com:27000
        password: ${REDIS_PASSWORD}
        database: ${REDIS_DATABASE:15}
      rabbitmq:
        host: mq.bak.com
        port: 5672
        username: ${RABBITMQ_USERNAME}
        password: ${RABBITMQ_PASSWORD}
        virtualHost: shop-recycle-msg
      cloud:
        nacos:
          discovery:
            server-addr: nacos.bak.com:8848
            service: shop-recycle-payment-service
            weight: 1
  application.properties: |
    spring.application.name=shop-recycle-payment
    spring.protocol.name=spring
    server.port=1218
EOF

# 部署 ConfigMap
kubectl apply -f shop-recycle-payment-configmap.yaml

自动化方法:使用脚本

# 使用提供的脚本生成所有服务
bash generate-k8s-manifests.sh

第 3 步:创建 Deployment

# 为每个服务创建 Deployment

cat > shop-recycle-payment-deployment.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: shop-recycle-payment
  namespace: default
  labels:
    app: shop-recycle-payment
    service-type: backend
spec:
  replicas: 2  # 开发环境改为 1
  selector:
    matchLabels:
      app: shop-recycle-payment
  template:
    metadata:
      labels:
        app: shop-recycle-payment
    spec:
      containers:
      - name: shop-recycle-payment
        image: shop-recycle-payment:1.0.0  # 修改为实际镜像
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 1218
        
        # ConfigMap 中的所有配置都作为环境变量注入
        envFrom:
        - configMapRef:
            name: shop-recycle-payment-config
        
        # Secret 中的敏感信息通过环境变量注入
        env:
        - name: JAVA_OPTS
          value: "-Djava.awt.headless=true -Djava.net.preferIPv4Stack=true -Xss256k -XX:+DisableExplicitGC"
        - name: TZ
          value: "Asia/Shanghai"
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: common-db-credentials
              key: db-username
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: common-db-credentials
              key: db-password
        - name: DB_HOST
          valueFrom:
            secretKeyRef:
              name: common-db-credentials
              key: db-host
        - name: REDIS_PASSWORD
          valueFrom:
            secretKeyRef:
              name: common-redis-credentials
              key: redis-password
        - name: RABBITMQ_USERNAME
          valueFrom:
            secretKeyRef:
              name: common-rabbitmq-credentials
              key: rabbitmq-username
        - name: RABBITMQ_PASSWORD
          valueFrom:
            secretKeyRef:
              name: common-rabbitmq-credentials
              key: rabbitmq-password
        
        volumeMounts:
        - name: config-volume
          mountPath: /app/conf
          readOnly: true
        
        resources:
          requests:
            cpu: 250m
            memory: 512Mi
          limits:
            cpu: 1000m
            memory: 1024Mi
        
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 1218
          initialDelaySeconds: 30
          periodSeconds: 10
        
        livenessProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 1218
          initialDelaySeconds: 60
          periodSeconds: 15
      
      volumes:
      - name: config-volume
        configMap:
          name: shop-recycle-payment-config
EOF

# 部署
kubectl apply -f shop-recycle-payment-deployment.yaml

第 4 步:创建 Service

cat > shop-recycle-payment-service.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
  name: shop-recycle-payment
  namespace: default
  labels:
    app: shop-recycle-payment
spec:
  type: ClusterIP
  selector:
    app: shop-recycle-payment
  ports:
  - name: http
    port: 1218
    targetPort: 1218
    protocol: TCP
EOF

kubectl apply -f shop-recycle-payment-service.yaml

第 5 步:批量部署所有 34 个服务

# 如果已经生成了所有文件
kubectl apply -f k8s-manifests/secrets/
kubectl apply -f k8s-manifests/configmaps/
kubectl apply -f k8s-manifests/deployments/
kubectl apply -f k8s-manifests/services/

🔍 验证部署

# 1. 查看所有 Secret
kubectl get secrets | grep -E "common-|wechat-"

# 2. 查看所有 ConfigMap
kubectl get configmaps | grep shop-recycle

# 3. 查看所有 Deployment
kubectl get deployments | grep shop-recycle

# 4. 查看 Pod 状态
kubectl get pods | grep shop-recycle

# 5. 查看特定服务的日志
kubectl logs -l app=shop-recycle-payment -f

# 6. 验证环境变量是否正确注入
kubectl exec -it shop-recycle-payment-xxxx -- env | grep DB_

# 7. 验证 ConfigMap 挂载
kubectl exec -it shop-recycle-payment-xxxx -- ls -la /app/conf/
kubectl exec -it shop-recycle-payment-xxxx -- cat /app/conf/application.yml

# 8. 测试服务健康
kubectl port-forward svc/shop-recycle-payment 1218:1218
curl http://localhost:1218/actuator/health

🐛 故障排查

问题 1:Pod 无法启动(CrashLoopBackOff)

# 查看日志
kubectl logs shop-recycle-payment-xxxx

# 常见原因:
# 1. Secret 不存在
kubectl get secret common-db-credentials

# 2. ConfigMap 不存在
kubectl get configmap shop-recycle-payment-config

# 3. 环境变量引用错误
kubectl describe pod shop-recycle-payment-xxxx

问题 2:无法连接数据库

# 1. 验证 DB 凭证
kubectl get secret common-db-credentials -o yaml

# 2. 验证应用是否收到凭证
kubectl exec -it pod_name -- env | grep DB_

# 3. 测试数据库连接
kubectl run -it mysql-client --image=mysql:8.0 -- /bin/bash
mysql -h rm-bp19t90t7u8n5b0fh.mysql.rds.aliyuncs.com -u root -p

问题 3:ConfigMap 修改后 Pod 未更新

# ConfigMap 修改不会自动重启 Pod,需要手动重启
kubectl rollout restart deployment shop-recycle-payment

# 或删除 Pod 强制重建
kubectl delete pods -l app=shop-recycle-payment

问题 4:Secret 无权限访问

# 检查 RBAC 权限
kubectl auth can-i get secrets --as=system:serviceaccount:default:default

# 需要配置 RBAC
kubectl create rolebinding read-secrets --clusterrole=view --serviceaccount=default:default

🏆 最佳实践

1. Secret 管理

推荐:

# 使用 External Secrets Operator 从 HashiCorp Vault 同步
# 使用 sealed-secrets 加密存储在 Git
# 使用 RBAC 限制 Secret 访问
# 定期轮换密码

不推荐:

# 不要将密码保存在 ConfigMap
# 不要提交密码到 Git(包括 Base64 编码)
# 不要用明文存储在磁盘

2. ConfigMap 管理

推荐:

# 将配置文件版本化
# 使用 Kustomize 管理多环境配置
# 保持配置不超过 1MB
# 为 ConfigMap 添加版本标签

不推荐:

# 不要修改 ConfigMap 期望立即生效
# 不要在 ConfigMap 中存储敏感信息

3. 环境隔离

# 为不同环境创建不同的 Namespace
kubectl create namespace dev
kubectl create namespace staging
kubectl create namespace prod

# 在每个 Namespace 中创建 Secret
kubectl apply -f secret-dev.yaml -n dev
kubectl apply -f secret-prod.yaml -n prod

4. 监控和日志

# 添加指标收集
# 配置日志聚合(ELK、Loki)
# 设置告警
# 监控 Secret 访问

# 示例:使用 Prometheus 监控
# 添加到 Deployment 的 annotations
annotations:
  prometheus.io/scrape: "true"
  prometheus.io/port: "1218"
  prometheus.io/path: "/actuator/prometheus"

5. 发布流程

# 1. 开发环境
kubectl apply -f config/dev/ -n dev

# 2. 测试环境
kubectl apply -f config/staging/ -n staging

# 3. 生产环境(使用 GitOps)
# 通过 ArgoCD 或 Flux 自动部署

📚 相关资源


✅ 清单

  • 编辑 secret-templates-common.yaml 替换实际凭证
  • 创建所有 Secret
  • 为每个服务生成 ConfigMap
  • 为每个服务生成 Deployment
  • 为每个服务生成 Service
  • 验证所有资源已创建
  • 测试应用连接
  • 配置 RBAC 权限
  • 设置监控告警
  • 记录部署文档