CI/CD是围绕代码变更建立的可重复、可验证、可回滚的交付节奏,核心为每次提交触发自动化构建测试并通过后自动部署,全程无人工干预。

持续集成(CI)与持续部署(CD)不是工具堆砌,而是围绕代码变更建立的一套可重复、可验证、可回滚的交付节奏。核心在于:每次提交触发自动化构建与测试,通过后自动进入预发布或生产环境,中间不依赖人工干预。
CI/CD 流程的关键节点拆解
一个典型的 Linux DevOps 项目 CI/CD 流程包含以下不可跳过的环节:
- 代码拉取(Git Hook 或 Webhook 触发):推荐用 GitLab CI / GitHub Actions 原生集成,避免自建轮询;分支策略建议 main 为稳定发布分支,develop 为集成分支,feature/* 用于并行开发
-
环境准备(容器化优先):使用 Docker 构建轻量一致的构建环境,例如 Node.js 项目用
node:18-alpine,Python 项目用python:3.11-slim;避免“在我机器上能跑”的问题 -
构建与静态检查:执行
npm install && npm run build或pip install -r requirements.txt && python setup.py sdist,同时加入 ESLint、mypy、shellcheck 等扫描,失败即终止流程 - 自动化测试分层执行:单元测试(快,本地可运行)→ 集成测试(依赖 DB/API Mock)→ 端到端测试(如 Cypress / Selenium),任一环节失败,不进入下一阶段
- 制品归档与镜像推送:构建产物(tar 包 / wheel 文件 / Docker 镜像)统一上传至私有仓库(Nexus / Harbor),打上 Git commit SHA 和语义化标签(如 v1.2.0-rc1)
- 部署策略按环境分级:dev 环境直接覆盖部署;staging 环境做蓝绿或金丝雀验证;production 环境强制需审批(可通过 CI 工具配置 manual job)+ 健康检查(curl 检查 /actuator/health 或 readiness probe)
Linux 下常用 CI/CD 工具链组合
在真实服务器环境落地时,应优先选择轻量、易维护、权限可控的方案:
-
自托管 Runner + Shell 脚本驱动:适合中小团队。用 GitLab Runner 注册到内网 Linux 主机,配合
.gitlab-ci.yml调用本地 shell 脚本完成构建部署,所有操作日志可审计,无需暴露 API Token 到公有云 -
Jenkins Pipeline(Declarative):适合已有 Jenkins 基础的团队。用 Jenkinsfile 定义 stage(build/test/deploy),配合 SSH Plugin 或 Kubernetes Plugin 实现跨主机部署;注意关闭 Script Security Sandbox 中高危函数(如
sh 'rm -rf /') -
GitHub Actions Self-hosted Runner:适合 GitHub 托管代码但需内网部署的场景。将 runner 部署在企业 Linux 服务器上,通过
runs-on: self-hosted调度任务,敏感凭证存于 GitHub Secrets,不落盘
部署安全与可观测性加固要点
CI/CD 流水线本身是攻击面,上线前必须检查:
- 最小权限原则:Runner 运行用户禁止 root,部署目标机器仅开放必要端口(如 22/80/443),SSH 使用密钥+证书登录,禁用密码认证
-
制品完整性校验:Docker 镜像启用
cosign sign签名,部署脚本中用cosign verify校验;二进制包发布前生成 SHA256SUMS 并 GPG 签名 - 部署后自动巡检:用 Ansible 或 curl + jq 检查服务端口、响应状态码、关键日志关键词(如 “started”、“ready”);失败自动告警(邮件 / 钉钉 / Webhook)并尝试回滚(调用上一版镜像或备份 tar 包)
- 日志与追踪对齐:CI 日志保留至少 90 天;每个部署 job 输出唯一 trace_id,关联应用日志(ELK)和链路追踪(Jaeger / OpenTelemetry)
从零搭建一个可运行的 CI/CD 示例(GitLab CI)
以 Python Flask 应用为例,在项目根目录创建 .gitlab-ci.yml:
stages: - test - build - deploytest: stage: test image: python:3.11-slim before_script:
- pip install pytest pytest-cov script:
- pytest tests/ --cov=app --cov-report=term-missing artifacts: paths: [htmlcov/] expire_in: 1 week
build: stage: build image: docker:stable services: [docker:dind] before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
deploy-staging: stage: deploy image: alpine:latest before_script:
- apk add openssh-client script:
- ssh -o StrictHostKeyChecking=no $STAGING_USER@$STAGING_HOST "docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA && docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA $CI_REGISTRY_IMAGE:staging && docker-compose -f docker-compose.staging.yml up -d" only:
- develop
该配置实现:提交到 develop 分支 → 自动测试 → 构建并推镜像 → 部署到预发服务器。所有敏感变量(
$STAGING_USER、$CI_REGISTRY_PASSWORD)在 GitLab 项目 Settings → CI/CD → Variables 中加密配置。










