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/