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

排错清单(常见问题与命令)#

  1. 部署失败/超时
    - 检查滚动状态
    bash kubectl -n app-prod rollout status deploy/app --timeout=60s kubectl -n app-prod describe deploy/app
  2. 配置未生效
    - 检查配置是否写入正确命名空间
    bash curl -s 'http://nacos.example.com:8848/nacos/v1/cs/configs?dataId=app.yaml&group=DEFAULT_GROUP&tenant=prod'
  3. 访问被拒绝
    - 检查NetworkPolicy规则
    bash kubectl -n app-prod get networkpolicy kubectl -n app-prod describe networkpolicy deny-cross-ns
  4. 制品版本混乱
    - 列出镜像标签并核对
    bash curl -s 'http://registry.example.com/v2/app/tags/list'

练习#

  1. 在K8s中创建app-devapp-prod命名空间,并通过NetworkPolicy阻断dev访问prod。
  2. 用Jenkins参数化流水线实现“dev自动部署、prod需审批”的发布流程。
  3. 使用Nacos分别创建dev/prod命名空间,发布不同的app.yaml配置并验证。
  4. 设计镜像标签规范,要求能从标签中识别环境与版本(如prod-1.2.3)。