18.5.2 环境分层与隔离:开发、测试、预发、生产
环境分层与隔离是CD流程的基础,通过清晰的阶段划分降低变更风险、提升交付质量,并保证问题可追踪与可回滚。常见分层包括开发、测试、预发与生产四类环境,每一层的目标、约束与治理策略不同,需要在流程、资源与权限上进行系统性隔离与管理。
以下为环境分层与隔离的原理草图(以Jenkins驱动多环境部署为例):
环境分层关键目标与隔离策略#
- 开发环境:强调快速迭代,允许频繁变更;用脱敏数据与最小权限
- 测试环境:强调可复现与稳定;与生产架构一致,自动化测试覆盖
- 预发环境:强调全量演练;与生产“镜像一致”,开启灰度验证
- 生产环境:强调稳定与安全;最小变更原则,严格权限与审计
隔离方式建议:
- 基础设施:不同VPC/子网、K8s命名空间、独立集群
- 配置:配置中心按环境分组,密钥与配置禁止跨环境引用
- 制品:制品仓库按环境/分支隔离,并标注版本
- 数据:严格权限与脱敏策略,开发/测试禁止直连生产
Jenkins多环境流水线示例(参数化+审批+回滚)#
下面示例以Jenkins Declarative Pipeline为例,区分dev/test/staging/prod,包含审批节点与回滚策略:
// Jenkinsfile
pipeline {
agent any
parameters {
choice(name: 'ENV', choices: ['dev', 'test', 'staging', 'prod'], description: '部署环境')
string(name: 'IMAGE_TAG', defaultValue: 'v1.0.0', description: '镜像/制品版本')
}
stages {
stage('拉取制品') {
steps {
sh '''
echo "拉取制品 ${IMAGE_TAG}"
docker pull registry.example.com/app:${IMAGE_TAG}
'''
}
}
stage('环境审批') {
when { expression { params.ENV == 'prod' || params.ENV == 'staging' } }
steps {
input message: "确认发布到 ${params.ENV} ?", ok: "确认"
}
}
stage('部署') {
steps {
sh '''
echo "部署到 ${ENV}"
kubectl -n app-${ENV} set image deploy/app app=registry.example.com/app:${IMAGE_TAG}
kubectl -n app-${ENV} rollout status deploy/app --timeout=120s
'''
}
}
}
post {
failure {
sh '''
echo "部署失败,执行回滚"
kubectl -n app-${ENV} rollout undo deploy/app
'''
}
}
}
关键命令解释:
- kubectl -n app-${ENV} set image:按环境命名空间更新镜像
- rollout status:等待滚动发布完成,超时触发失败
- rollout undo:发生失败时回滚到上一版本
K8s命名空间与网络隔离示例#
以命名空间+NetworkPolicy实现环境隔离(dev不能访问prod服务):
# 创建命名空间
kubectl create ns app-dev
kubectl create ns app-test
kubectl create ns app-staging
kubectl create ns app-prod
# 创建NetworkPolicy(禁止跨命名空间访问)
cat > /tmp/np-deny-cross-ns.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-cross-ns
namespace: app-prod
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}
EOF
kubectl apply -f /tmp/np-deny-cross-ns.yaml
预期效果:
- app-prod 只允许本命名空间内访问
- dev/test/staging 不再能直接访问 prod 的服务
配置中心环境分组示例(Nacos)#
将不同环境配置隔离为独立的命名空间:
# 创建命名空间示例(使用nacos api)
curl -X POST 'http://nacos.example.com:8848/nacos/v1/console/namespaces' \
-d 'customNamespaceId=dev&namespaceName=dev'
curl -X POST 'http://nacos.example.com:8848/nacos/v1/console/namespaces' \
-d 'customNamespaceId=prod&namespaceName=prod'
配置发布时指定命名空间:
curl -X POST 'http://nacos.example.com:8848/nacos/v1/cs/configs' \
-d 'dataId=app.yaml&group=DEFAULT_GROUP&content=server.port=8080&tenant=dev'
制品仓库隔离示例(Docker Registry)#
按环境标签区分镜像版本,避免混用:
# dev 流水线发布
docker tag app:build-123 registry.example.com/app:dev-1.2.3
docker push registry.example.com/app:dev-1.2.3
# prod 流水线发布
docker tag app:build-123 registry.example.com/app:prod-1.2.3
docker push registry.example.com/app:prod-1.2.3
排错清单(常见问题与命令)#
- 部署失败/超时
- 检查滚动状态
bash kubectl -n app-prod rollout status deploy/app --timeout=60s kubectl -n app-prod describe deploy/app - 配置未生效
- 检查配置是否写入正确命名空间
bash curl -s 'http://nacos.example.com:8848/nacos/v1/cs/configs?dataId=app.yaml&group=DEFAULT_GROUP&tenant=prod' - 访问被拒绝
- 检查NetworkPolicy规则
bash kubectl -n app-prod get networkpolicy kubectl -n app-prod describe networkpolicy deny-cross-ns - 制品版本混乱
- 列出镜像标签并核对
bash curl -s 'http://registry.example.com/v2/app/tags/list'
练习#
- 在K8s中创建
app-dev和app-prod命名空间,并通过NetworkPolicy阻断dev访问prod。 - 用Jenkins参数化流水线实现“dev自动部署、prod需审批”的发布流程。
- 使用Nacos分别创建dev/prod命名空间,发布不同的
app.yaml配置并验证。 - 设计镜像标签规范,要求能从标签中识别环境与版本(如
prod-1.2.3)。