GitLab CI/CD流水线搭建实战:自动化构建测试与容器镜像发布配置

GitLab CI/CD是内置在GitLab中的持续集成与持续交付系统,通过.gitlab-ci.yml文件定义流水线,配合GitLab Runner执行构建、测试、打包、部署任务。相比Jenkins,GitLab CI/CD与代码仓库深度集成,配置即代码,无需维护额外的插件生态。本文从Runner注册、Pipeline配置、Docker镜像构建发布三个层面,搭建一条完整的CI/CD流水线

GitLab Runner安装与注册

GitLab Runner是执行Pipeline任务的独立进程,可以安装在物理机、虚拟机或容器中。生产环境推荐使用Docker executor实现任务隔离。

# 安装GitLab Runner(Linux)
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
yum install -y gitlab-runner

# 注册Runner
gitlab-runner register
# 输入GitLab URL: https://gitlab.example.com/
# 输入Registration Token: 从GitLab项目Settings > CI/CD > Runners获取
# 输入Executor: docker
# 输入Default Image: alpine:latest

# 启动Runner
systemctl enable gitlab-runner
systemctl start gitlab-runner

# 验证注册状态
gitlab-runner verify

.gitlab-ci.yml基础结构与作业管理

Pipeline由stages(阶段)和jobs(作业)组成,同一stage内的job并行执行,不同stage按顺序串行执行。每个job必须属于一个stage,通过script字段定义执行的命令。

# .gitlab-ci.yml
stages:
  - build
  - test
  - package
  - deploy

variables:
  MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
  DOCKER_IMAGE: "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"

# 构建阶段
build-job:
  stage: build
  image: maven:3.9-eclipse-temurin-21
  script:
    - mvn clean compile -B
  artifacts:
    paths:
      - target/
    expire_in: 1 hour
  cache:
    key: maven-cache
    paths:
      - .m2/repository

# 测试阶段
test-job:
  stage: test
  image: maven:3.9-eclipse-temurin-21
  script:
    - mvn test -B
  artifacts:
    reports:
      junit: target/surefire-reports/TEST-*.xml
  needs:
    - build-job

条件触发与分支策略配置

生产环境影响较大,需要严格控制触发条件。通过rules和only/except控制不同分支的行为:

# 仅main分支触发部署
deploy-staging:
  stage: deploy
  image: alpine:latest
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      when: on_success
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      when: manual
  script:
    - echo "部署到预发布环境"
    - apk add --no-cache openssh-client
    - ssh -o StrictHostKeyChecking=no deploy@staging.example.com "cd /app && git pull && docker-compose up -d"

# 打Tag时触发生产部署
deploy-production:
  stage: deploy
  rules:
    - if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/'
      when: manual
  script:
    - echo "部署到生产环境: $CI_COMMIT_TAG"
  environment:
    name: production
    url: https://app.example.com

Docker镜像构建与推送GitLab Container Registry

GitLab内置Container Registry,配合DinD(Docker in Docker)在CI中构建并推送镜像:

package-docker:
  stage: package
  image: docker:24-dind
  services:
    - docker:24-dind
  variables:
    DOCKER_TLS_CERTDIR: "/certs"
  before_script:
    - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
  script:
    # 多阶段构建
    - docker build -t "$DOCKER_IMAGE" -t "$CI_REGISTRY_IMAGE:latest" .
    # 安全扫描
    - docker run --rm aquasec/trivy image --exit-code 1 --severity HIGH,CRITICAL "$DOCKER_IMAGE"
    # 推送镜像
    - docker push "$DOCKER_IMAGE"
    - docker push "$CI_REGISTRY_IMAGE:latest"
  after_script:
    - docker logout "$CI_REGISTRY"
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'

对应的Dockerfile示例:

FROM maven:3.9-eclipse-temurin-21 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline -B
COPY src/ ./src/
RUN mvn clean package -DskipTests -B

FROM eclipse-temurin:21-jre-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
RUN chown -R appuser:appgroup /app
USER appuser
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:8080/actuator/health || exit 1
ENTRYPOINT ["java", "-jar", "app.jar"]

环境变量与敏感信息管理

数据库密码、API Key等敏感信息通过GitLab CI/CD Variables管理,分为项目级、组级和实例级:

# 在GitLab项目Settings > CI/CD > Variables中配置:
# DB_PASSWORD (masked, protected)
# DEPLOY_SSH_KEY (file类型,私钥内容)
# SLACK_WEBHOOK_URL (masked)

deploy-job:
  stage: deploy
  image: alpine:latest
  variables:
    DB_HOST: "prod-db.example.com"
  before_script:
    - chmod 600 "$DEPLOY_SSH_KEY"
  script:
    - scp -i "$DEPLOY_SSH_KEY" -o StrictHostKeyChecking=no docker-compose.yml deploy@prod.example.com:/app/
    - ssh -i "$DEPLOY_SSH_KEY" deploy@prod.example.com "cd /app && export DB_PASSWORD='$DB_PASSWORD' && docker-compose pull && docker-compose up -d"
  after_script:
    - rm -f "$DEPLOY_SSH_KEY"

流水线缓存与构建产物优化

合理使用cache和artifacts能显著提升Pipeline执行速度。cache用于跨Pipeline共享依赖(如Maven仓库、npm modules),artifacts用于在job之间传递构建产物:

# 全局缓存配置
default:
  cache:
    key:
      files:
        - pom.xml
      prefix: "maven-$CI_COMMIT_REF_SLUG"
    paths:
      - .m2/repository
    policy: pull-push

# 测试job只需拉取缓存
test-job:
  cache:
    key:
      files:
        - pom.xml
      prefix: "maven-$CI_COMMIT_REF_SLUG"
    paths:
      - .m2/repository
    policy: pull

Pipeline通知与失败告警

notify-failure:
  stage: .post
  image: curlimages/curl:latest
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push"'
      when: on_failure
  script:
    - |
      curl -X POST -H 'Content-type: application/json' \
        --data "{\"text\":\"Pipeline失败: $CI_PROJECT_NAME - $CI_COMMIT_BRANCH\n提交: $CI_COMMIT_MESSAGE\n链接: $CI_PIPELINE_URL\"}" \
        "$SLACK_WEBHOOK_URL"

notify-success:
  stage: .post
  image: curlimages/curl:latest
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      when: on_success
  script:
    - |
      curl -X POST -H 'Content-type: application/json' \
        --data "{\"text\":\"部署成功: $CI_PROJECT_NAME @ $CI_COMMIT_SHORT_SHA\"}" \
        "$SLACK_WEBHOOK_URL"

GitLab CI/CD的核心优势在于配置即代码,.gitlab-ci.yml随代码版本管理,Pipeline定义与代码变更自然关联。结合Docker executor实现构建环境隔离,配合Container Registry打通镜像构建到部署的完整链路。对于多环境部署,使用environment管理部署目标,通过rules精确控制触发条件,实现从代码提交到生产发布的全自动化。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/gitlabcicd-liu-shui-xian-da-jian-shi-zhan-zi-dong-hua-gou/

(0)
小编小编
上一篇 3小时前
下一篇 3小时前

相关推荐