CI/CD 入门 — 用 GitLab CI 构建自动化部署流水线

📖 知识点简介

运维手工部署等于慢性自杀。CI/CD(持续集成/持续部署)将代码从提交到上线的流程自动化:

  • CI(Continuous Integration):每次代码提交自动触发构建、测试、代码扫描
  • CD(Continuous Deployment/Delivery):通过验证后自动部署到测试/预发布/生产环境

对运维来说,CI/CD 的意义不仅是"省去手动敲命令",更是标准化流程 ------每一次部署都有日志、可追溯、可回滚。GitLab CI 是自建运维体系中很受欢迎的选择:与 GitLab 深度集成,.gitlab-ci.yml 即配置,runner 可部署在任何机器上。


🔧 核心概念/配置整理

1. GitLab CI 核心概念

术语 说明
Pipeline 一次 CI/CD 执行的全流程,包含多个 Stage
Stage 阶段(如 build → test → deploy),顺序执行
Job 阶段内的具体任务,同 Stage 的 Job 并行执行
Runner 执行 Job 的 Agent,可注册到 GitLab
Artifact Job 产出的文件(如 jar 包),可传递到后续 Stage

2. .gitlab-ci.yml 基本结构

yaml 复制代码
stages:
  - build
  - test
  - deploy

# 变量(所有 Job 共享)
variables:
  DOCKER_IMAGE: registry.company.com/myapp
  DEPLOY_DIR: /opt/myapp

build-job:
  stage: build
  script:
    - docker build -t $DOCKER_IMAGE:$CI_COMMIT_SHORT_SHA .
    - docker push $DOCKER_IMAGE:$CI_COMMIT_SHORT_SHA
  only:
    - main

test-job:
  stage: test
  script:
    - docker run --rm $DOCKER_IMAGE:$CI_COMMIT_SHORT_SHA npm test
  only:
    - main

deploy-staging:
  stage: deploy
  script:
    - ansible-playbook -i inventory/staging deploy.yml
  environment:
    name: staging
  only:
    - main

deploy-production:
  stage: deploy
  script:
    - echo "Deploying to production..."
    - ansible-playbook -i inventory/prod deploy.yml
  environment:
    name: production
  when: manual          # 生产环境需要手动确认
  only:
    - main

3. 注册 GitLab Runner

bash 复制代码
# 安装 Runner
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
sudo yum install -y gitlab-runner

# 注册(需要 GitLab 项目的注册令牌)
sudo gitlab-runner register
# 输入 GitLab 实例 URL → https://gitlab.company.com
# 输入 Registration Token → 从项目 Settings → CI/CD → Runners 获取
# 输入描述 → prod-deploy-runner
# 选择执行器 → shell (简单场景) 或 docker

# 验证注册状态
sudo gitlab-runner list

4. 常用内置变量

yaml 复制代码
# 在 .gitlab-ci.yml 中可直接使用
$CI_COMMIT_SHORT_SHA    # 提交的短哈希(如 a1b2c3d)
$CI_COMMIT_REF_NAME     # 分支名(如 main, feature/xxx)
$CI_PIPELINE_ID         # Pipeline 唯一 ID
$CI_JOB_ID              # Job 唯一 ID
$CI_ENVIRONMENT_NAME    # 环境名称(staging / production)

🧪 实操示例:Docker 应用一键构建部署

场景:前后端分离项目,Push 到 main 分支后自动构建镜像并部署到测试服务器

yaml 复制代码
# .gitlab-ci.yml
stages:
  - build
  - test
  - deploy-staging

variables:
  REGISTRY: registry.company.com
  PROJECT: myapp
  TAG: $CI_COMMIT_SHORT_SHA

cache:
  paths:
    - node_modules/

before_script:
  - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $REGISTRY

build-frontend:
  stage: build
  script:
    - cd frontend
    - docker build -t $REGISTRY/$PROJECT/frontend:$TAG .
    - docker push $REGISTRY/$PROJECT/frontend:$TAG
  artifacts:
    paths:
      - frontend/dist/

build-backend:
  stage: build
  script:
    - cd backend
    - docker build -t $REGISTRY/$PROJECT/backend:$TAG .
    - docker push $REGISTRY/$PROJECT/backend:$TAG

test-backend:
  stage: test
  script:
    - docker run --rm $REGISTRY/$PROJECT/backend:$TAG pytest
  needs:
    - build-backend

deploy-staging:
  stage: deploy-staging
  script:
    - ssh deploy@staging-server "
        docker pull $REGISTRY/$PROJECT/frontend:$TAG &&
        docker pull $REGISTRY/$PROJECT/backend:$TAG &&
        docker-compose -f /opt/$PROJECT/docker-compose.yml up -d
      "
  environment:
    name: staging
    url: https://staging.company.com
  only:
    - main

配套:在部署目标服务器上提前准备

bash 复制代码
# 部署服务器需要:
# 1. 安装 Docker + docker-compose
# 2. 创建 deploy 用户
useradd -m deploy
usermod -aG docker deploy

# 3. 配置 SSH 免密(GitLab Runner 所在机器生成密钥)
ssh-keygen -t ed25519
ssh-copy-id deploy@staging-server

# 4. 在 GitLab 项目 Settings → CI/CD → Variables 中设置:
# CI_REGISTRY_USER --- 镜像仓库账号
# CI_REGISTRY_PASSWORD --- 镜像仓库密码

快速验证流水线

bash 复制代码
# 本地调试 .gitlab-ci.yml(需要安装 gitlab-ci-local)
# 或使用 GitLab 自带的 CI Lint
# 项目 → CI/CD → Editor → CI Lint

⚠️ 常见坑点/注意事项

1. Runner 安全风险

  • shell 执行器 :Runner 直接在宿主机执行脚本,权限极高。生产环境建议用 docker 执行器,每次 Job 运行在隔离容器中
  • 不要在公共仓库暴露 CI_REGISTRY_PASSWORD 等敏感变量,务必使用 GitLab 的 Settings → CI/CD → Variables(masked 标记)

2. 部署密钥管理

yaml 复制代码
# ❌ 错误:在 yml 中硬编码密钥
script:
  - sshpass -p '123456' ssh user@server deploy.sh

# ✅ 正确:使用 SSH 密钥 + GitLab Variables
# 在 CI Variables 中添加 SSH_PRIVATE_KEY(Type: File)
before_script:
  - eval $(ssh-agent -s)
  - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
  - mkdir -p ~/.ssh
  - chmod 700 ~/.ssh

3. 流水线速度优化

  • 利用 cache 缓存依赖(npm、pip、maven)
  • needs 控制 Job 依赖,避免等待不相关的 Job
  • 合理设置 only/except,避免每次 push 都跑全量流水线

4. 回滚策略

每一次 CD 部署成功后,建议将上一版本保留为 Docker Tag(如 stable),方便快速回退:

yaml 复制代码
deploy-production:
  script:
    - docker tag $REGISTRY/$PROJECT:$TAG $REGISTRY/$PROJECT:stable
    - docker push $REGISTRY/$PROJECT:stable
    - # 执行部署
  # 回滚时只需 docker pull 回 stable 标签

5. 环境隔离

  • 始终区分 stagingproduction 环境
  • 生产环境部署推荐加 when: manual + 审批人配置
  • 每个环境使用独立的 Variables,不要在流水线中混用

一句话总结:CI/CD 把"人肉运维"变成"代码运维"------配置即文档,流水线即流程,每一次部署都有据可查。

相关推荐
沸点小助手1 小时前
6月沸点活动获奖名单公示|本周互动话题上新🎊
前端·后端
远航_1 小时前
git submodule
前端·后端·github
狂师1 小时前
测试工程师的AI 技能库:推荐5个让你效率翻倍的Skills
前端·后端·测试
CodeSheep1 小时前
DeepSeek正式官宣摇人,夯!
前端·后端·程序员
亦暖筑序2 小时前
Java 8老系统AI Workflow实战:把一次性AI对话升级成可恢复工作流
java·后端
血小溅2 小时前
飞书 CLI 集成基础教程
后端
ihgry2 小时前
SpringBoot+Redis限流
后端
晚安code2 小时前
Nacos 注解全解析:7 个核心注解 + 5 个生产踩坑清单(2026 实测)
后端
wei_shuo2 小时前
KES 备份恢复与数据灾备实战:物理备份、逻辑备份与PITR完全指南
后端