LinuxDevOps项目实战教程_持续集成持续部署流程解析

13次阅读

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

LinuxDevOps项目实战教程_持续集成持续部署流程解析

持续集成(CI)与持续部署(CD)不是工具砌,而是围绕代码变更建立的一套可重复、可验证、可回滚的交付节奏。核心在于:每次提交触发自动化构建与测试,通过后自动进入预发布或生产环境,中间不依赖人工干预。

CI/CD 流程的关键节点拆解

一个典型的 linux devops 项目 CI/CD 流程包含以下不可跳过的环节:

  • 代码拉取(git Hook 或 Webhook 触发):推荐用 gitlab CI / github Actions 原生集成,避免自建轮询;分支策略建议 main 为稳定发布分支,develop 为集成分支,feature/* 用于并行开发
  • 环境准备(容器化优先):使用 docker 构建轻量一致的构建环境,例如 node.js 项目用 node:18-alpinepython 项目用 python:3.11-slim;避免“在我机器上能跑”的问题
  • 构建与静态检查:执行 npm install && npm run buildpip 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   - deploy 

test: 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 中加密配置。

text=ZqhQzanResources