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_RATE从0提升至10,观察部署标签变化:
kubectl -n app-uat get pod -l app=app -o jsonpath='{.items[0].metadata.labels.gray}'
3. 故障演练:将DB_HOST设为错误地址,发布后通过健康检查检测失败并手动回滚到上一个IMAGE_TAG。 -
关键落地要点总结
- 参数集中管理(表/配置中心),模板统一复用
- 渲染前校验、部署后健康检查形成闭环
- 凭据注入统一通过 Jenkins Credentials,避免明文
- 同步记录“参数版本 + 模板版本 + 制品版本”,支撑可追溯与回滚