You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GitLab流水线中配置按需Kubernetes部署用于CD人工验收?

你的思路完全可行,绝非理想化!这是预发布验收的标准实践

你的想法其实是CI/CD流程里预发布环境动态部署+人工审批的典型场景,很多团队都在实际落地,完全不是空想。我来给你拆解具体的实现路径和注意事项:

核心逻辑梳理

咱们的目标是:

  • 每个GitLab流水线触发时,自动创建一个独立的临时K8s部署(带唯一访问域名)
  • 暂停流水线,等待人工验收(验收人员通过专属URI访问应用)
  • 验收通过/不通过后,自动销毁这个临时部署;或者超时自动清理,避免资源浪费

具体落地步骤

1. GitLab CI 流水线阶段配置

首先把流水线拆分成几个关键阶段,下面是简化版的配置示例:

stages:
  - build
  - deploy-preview
  - manual-approval
  - destroy-preview
  - deploy-production

# 构建镜像(你已有成熟流程,这里略过细节)
build-job:
  stage: build
  script:
    - docker build -t my-app:${CI_PIPELINE_ID} .
    - docker push my-registry/my-app:${CI_PIPELINE_ID}

# 部署临时预览环境
deploy-preview:
  stage: deploy-preview
  image: bitnami/kubectl:latest
  script:
    # 创建专属Namespace(资源隔离更彻底,可选)
    - kubectl create namespace preview-${CI_PIPELINE_ID} || true
    # 部署应用:用CI_PIPELINE_ID做唯一标识,确保每个流水线资源独立
    - kubectl -n preview-${CI_PIPELINE_ID} apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-preview
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app-preview
  template:
    metadata:
      labels:
        app: my-app-preview
    spec:
      containers:
      - name: my-app
        image: my-registry/my-app:${CI_PIPELINE_ID}
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-app-preview-svc
spec:
  selector:
    app: my-app-preview
  ports:
  - port: 80
    targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-preview-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: pipeline-${CI_PIPELINE_ID}.git.mydomain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-app-preview-svc
            port:
              number: 80
EOF
  # 绑定GitLab环境,方便后续管理和查看
  environment:
    name: preview/${CI_PIPELINE_ID}
    url: https://pipeline-${CI_PIPELINE_ID}.git.mydomain.com
    on_stop: destroy-preview

# 人工验收环节:必须手动触发才能继续流程
manual-approval:
  stage: manual-approval
  script:
    - echo "请访问 ${CI_ENVIRONMENT_URL} 进行验收,完成后点击继续/拒绝"
  when: manual
  allow_failure: false # 设置为false时,必须验收通过才能进入后续生产部署阶段

# 销毁临时预览环境(自动触发:验收通过后,或环境超时)
destroy-preview:
  stage: destroy-preview
  image: bitnami/kubectl:latest
  script:
    - kubectl delete namespace preview-${CI_PIPELINE_ID} || true
  environment:
    name: preview/${CI_PIPELINE_ID}
    action: stop
  when: manual # 也可设为always,不管验收结果都销毁;或用GitLab环境过期自动触发

2. 实现“仅访问时启动”的资源优化

如果想让临时部署平时休眠(副本数为0),有访问请求时再自动启动,可以用KEDA(Kubernetes Event-driven Autoscaling):

  • 给Deployment配置最小副本数为0,最大为1
  • 用KEDA的HTTP触发器(基于Ingress请求数),有请求时自动扩容到1个副本
  • 空闲一段时间后自动缩容回0,彻底节省集群资源

3. 集群选择:同一集群VS不同集群

  • 同一集群:更推荐,操作简单,资源利用率高。用Namespace隔离每个预览环境,销毁时直接删除Namespace即可,干净利落。
  • 不同集群:适合隔离性要求极高的场景(比如测试环境和生产集群完全物理隔离),但需要额外配置跨集群的Kubectl权限,运维成本更高。

4. 关键前置准备

  • 泛域名解析:把*.git.mydomain.com解析到K8s Ingress Controller的公网IP,确保每个流水线的专属域名能正常访问。
  • GitLab Runner权限:确保Runner所在的ServiceAccount拥有K8s的Namespace创建/删除、Deployment/Ingress管理权限。
  • 环境过期配置:在GitLab项目的「Settings > CI/CD > Environments」里设置预览环境的过期时间(比如7天),即使忘记手动销毁,GitLab也会自动清理资源。

类似实践参考

很多大厂和开源项目都在用这种模式:

  • GitLab官方的Review Apps功能就是这个思路的官方实现(你可以直接用官方功能,减少自定义配置)
  • 比如GitLab自身的产品迭代,每个Merge Request都会生成临时预览环境,供产品/测试验收

内容的提问来源于stack exchange,提问作者Jan Richter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:15:58