18.5.6 多环境部署实践:参数化与模板化

多环境部署实践的核心是“参数化与模板化”,将环境差异抽象为变量,部署流程抽象为模板,实现一次设计、多处复用与可回滚。本节给出原理草图、参数清单、模板渲染、Jenkins落地、排错与练习。

  • 原理草图(参数 → 模板渲染 → 部署)
文章图片
  • 参数化清单示例(环境参数表)
# /ops/params/env.csv
env,namespace,replicas,image_tag,db_host,redis_host,gray_rate
dev,app-dev,1,dev-20240101,10.0.1.10,10.0.1.20,0
test,app-test,2,test-20240101,10.0.2.10,10.0.2.20,0
stage,app-stage,3,rc-20240101,10.0.3.10,10.0.3.20,10
prod,app-prod,5,release-20240101,10.0.4.10,10.0.4.20,20
  • 模板化配置示例(以 Kubernetes Deployment 为例)
# /ops/templates/deploy.yaml.tpl
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
  namespace: ${NAMESPACE}
spec:
  replicas: ${REPLICAS}
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
        gray: "${GRAY_RATE}"
    spec:
      containers:
        - name: app
          image: registry.example.com/app:${IMAGE_TAG}
          env:
            - name: DB_HOST
              value: "${DB_HOST}"
            - name: REDIS_HOST
              value: "${REDIS_HOST}"
  • 渲染与部署命令(envsubst + kubectl)
# 1) 安装渲染工具(Ubuntu)
sudo apt-get update && sudo apt-get install -y gettext

# 2) 读取参数并导出为环境变量(示例:prod)
export NAMESPACE=app-prod
export REPLICAS=5
export IMAGE_TAG=release-20240101
export DB_HOST=10.0.4.10
export REDIS_HOST=10.0.4.20
export GRAY_RATE=20

# 3) 渲染模板并校验
envsubst < /ops/templates/deploy.yaml.tpl > /ops/rendered/deploy.yaml
kubectl apply --dry-run=client -f /ops/rendered/deploy.yaml

# 4) 部署并检查
kubectl apply -f /ops/rendered/deploy.yaml
kubectl -n app-prod rollout status deploy/app
  • Jenkins Pipeline 参数化与模板化示例(含凭据注入)
# Jenkinsfile
pipeline {
  agent any
  parameters {
    choice(name: 'ENV', choices: ['dev','test','stage','prod'], description: '部署环境')
    string(name: 'IMAGE_TAG', defaultValue: 'release-20240101', description: '镜像Tag')
    string(name: 'GRAY_RATE', defaultValue: '0', description: '灰度比例')
  }
  environment {
    PARAMS_FILE = "/ops/params/env.csv"
  }
  stages {
    stage('Load Params') {
      steps {
        sh '''
          set -e
          # 读取CSV行并导出变量
          line=$(awk -F, -v env="$ENV" 'NR>1 && $1==env {print $0}' $PARAMS_FILE)
          [ -n "$line" ] || { echo "ENV not found"; exit 1; }
          export NAMESPACE=$(echo $line | cut -d, -f2)
          export REPLICAS=$(echo $line | cut -d, -f3)
          export DB_HOST=$(echo $line | cut -d, -f5)
          export REDIS_HOST=$(echo $line | cut -d, -f6)
          echo "NAMESPACE=$NAMESPACE REPLICAS=$REPLICAS DB_HOST=$DB_HOST REDIS_HOST=$REDIS_HOST"
        '''
      }
    }
    stage('Render & Deploy') {
      steps {
        withCredentials([string(credentialsId: 'kubeconfig-prod', variable: 'KUBECONFIG')]) {
          sh '''
            export IMAGE_TAG=$IMAGE_TAG
            export GRAY_RATE=$GRAY_RATE
            envsubst < /ops/templates/deploy.yaml.tpl > /ops/rendered/deploy.yaml
            kubectl apply --dry-run=client -f /ops/rendered/deploy.yaml
            kubectl apply -f /ops/rendered/deploy.yaml
            kubectl -n $NAMESPACE rollout status deploy/app
          '''
        }
      }
    }
  }
}
  • Helm/Kustomize 模板化示例(以 Helm 为例)
# values-prod.yaml
replicaCount: 5
image:
  repository: registry.example.com/app
  tag: release-20240101
env:
  DB_HOST: 10.0.4.10
  REDIS_HOST: 10.0.4.20
grayRate: 20

# 安装与升级
helm upgrade --install app ./chart -n app-prod -f values-prod.yaml
  • 安装与工具准备
  • envsubst(文本模板渲染):sudo apt-get install -y gettext
  • yq(YAML处理,参数校验与修改):sudo apt-get install -y yq
  • helm(K8s模板管理):
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
helm version
  • 排错清单与命令(常见问题 → 诊断命令)
  • 参数未生效(变量未导出)
    • 检查:env | grep -E 'NAMESPACE|REPLICAS|IMAGE_TAG'
  • 模板渲染失败(占位符未替换)
    • 检查:grep -n '${' /ops/rendered/deploy.yaml
  • 发布未滚动(镜像Tag未变更)
    • 检查:kubectl -n app-prod get deploy app -o=jsonpath='{.spec.template.spec.containers[0].image}'
  • 权限不足(kubeconfig/凭据问题)
    • 检查:kubectl auth can-i apply -n app-prod --list
  • 目标环境未隔离(误用命名空间)

    • 检查:kubectl config view --minify
  • 命令解释(关键命令说明)

  • envsubst:将模板中的 ${VAR} 按当前环境变量替换生成配置
  • kubectl apply --dry-run=client:本地校验资源清单,不实际创建
  • kubectl rollout status:持续检查滚动发布状态并等待完成

  • 练习(可操作)
    1. 新增 uat 环境行到 env.csv,通过 Jenkins 参数化发布到 app-uat 命名空间。
    2. 将 GRAY_RATE0 提升至 10,观察部署标签变化:
    kubectl -n app-uat get pod -l app=app -o jsonpath='{.items[0].metadata.labels.gray}'
    3. 故障演练:将 DB_HOST 设为错误地址,发布后通过健康检查检测失败并手动回滚到上一个 IMAGE_TAG

  • 关键落地要点总结

  • 参数集中管理(表/配置中心),模板统一复用
  • 渲染前校验、部署后健康检查形成闭环
  • 凭据注入统一通过 Jenkins Credentials,避免明文
  • 同步记录“参数版本 + 模板版本 + 制品版本”,支撑可追溯与回滚