1. 环境准备与基础配置

1.1 组件版本要求与兼容性验证

在开始配置CI/CD流水线前,需要确保各组件版本匹配。我推荐使用以下经过实际验证的稳定版本组合:

  • GitLab 14.9+(CE/EE均可)
  • GitLab Runner 13.12+(配置Docker执行器)
  • Docker 20.10.24+(需支持BuildKit)
  • Harbor 2.5.3+(必须启用HTTPS)

重要提示:Runner主机需要预先安装docker-compose插件,否则多阶段构建可能失败。可通过 docker-compose version 命令验证。

对于自签名证书的Harbor仓库,需要将CA证书放置到Runner节点的以下目录:

# 证书路径模板(根据实际Harbor地址修改)
/etc/docker/certs.d/[Harbor主机]:[端口]/ca.crt

1.2 凭据安全存储最佳实践

在GitLab中配置以下CI/CD变量(建议设置为Masked和Protected):

变量名 示例值 安全等级 说明
HARBOR_USER robot$springboot-push Masked+Protected Harbor机器人账户
HARBOR_PASS xxxxxx Masked+Protected 对应token
DOCKER_HOST unix:///var/run/docker.sock - 固定值无需保护

建议使用Harbor的机器人账户而非个人账号,权限范围限定为指定项目推送权限。在Harbor中创建机器人账户的路径:

项目管理 → 机器人账户 → 新建机器人

2. 多阶段Dockerfile优化

2.1 典型Spring Boot容器化方案

这是我经过多个生产项目验证的Dockerfile模板:

# 第一阶段:构建
FROM maven:3.8.6-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml .
# 利用依赖缓存层
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

# 第二阶段:运行时
FROM eclipse-temurin:17-jre-jammy
RUN useradd -ms /bin/bash spring
USER spring
WORKDIR /app
COPY --from=build --chown=spring:spring /app/target/*.jar app.jar
# 非标准端口需与application.yml一致
EXPOSE 48087
ENTRYPOINT ["java","-jar","app.jar"]

2.2 构建参数动态注入技巧

通过 --build-arg 将构建信息打入镜像,便于后续审计:

docker build \
  --build-arg BUILD_TIME=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
  --build-arg GIT_COMMIT=$CI_COMMIT_SHORT_SHA \
  -t $IMAGE_TAG .

对应的Dockerfile需要添加ARG声明:

ARG BUILD_TIME
ARG GIT_COMMIT
LABEL org.opencontainers.image.created=$BUILD_TIME \
      org.opencontainers.image.revision=$GIT_COMMIT

3. GitLab CI流水线深度配置

3.1 阶段划分与缓存策略

完整的.gitlab-ci.yml应包含以下核心阶段:

stages:
  - build
  - push
  - deploy  # 可选部署阶段

缓存配置采用两级加速方案:

# Maven本地仓库缓存
cache:
  key: maven-$CI_COMMIT_REF_SLUG
  paths:
    - .m2/repository
    - target/*.jar

# Docker构建缓存(需BuildKit)
variables:
  DOCKER_BUILDKIT: "1"

3.2 分支策略与镜像标签规范

采用分支/标签区分环境的最佳实践:

build-test:
  only:
    - main
  script:
    - export IMAGE_TAG="test-${CI_COMMIT_SHORT_SHA}"

build-prod:
  only:
    - tags
  script:
    # 验证标签格式必须为vX.Y.Z
    - '[ "$CI_COMMIT_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]'
    - export IMAGE_TAG="$CI_COMMIT_TAG"

推荐标签命名规则:

  • 测试环境:test-<commit_sha> + test-latest
  • 生产环境:vX.Y.Z(语义化版本) + prod-latest
  • 缓存镜像: -cache

4. Harbor推送的进阶配置

4.1 自签名证书问题排查

当出现x509证书错误时,按以下步骤排查:

  1. 确认CA证书路径正确
  2. 检查证书链完整性:
    openssl verify -CAfile /etc/docker/certs.d/harbor.example.com/ca.crt \
      harbor.example.com.crt
    
  3. 在Runner作业中临时添加信任:
    before_script:
      - mkdir -p /usr/local/share/ca-certificates
      - cp $HARBOR_CA /usr/local/share/ca-certificates/
      - update-ca-certificates
    

4.2 镜像清理与存储优化

推荐在after_script中添加以下清理命令:

after_script:
  - docker rmi $REGISTRY/$PROJECT/$IMAGE_NAME:$IMAGE_TAG || true
  - docker system prune -f --filter "until=24h"

在Harbor中配置自动清理策略:

项目配置 → 存储配额 → 设置保留策略(如:保留最近5个prod版本)

5. 生产级流水线增强方案

5.1 安全扫描集成

在push阶段后添加安全扫描:

scan-image:
  stage: push
  needs: ["push-prod"]
  image: aquasec/trivy:latest
  script:
    - trivy image --exit-code 1 --severity CRITICAL \
      $REGISTRY/$PROJECT/$IMAGE_NAME:$IMAGE_TAG

5.2 部署联动配置示例

对于Kubernetes环境,添加部署阶段:

deploy-prod:
  stage: deploy
  image: bitnami/kubectl:latest
  script:
    - kubectl set image deployment/springboot-app \
      container=$REGISTRY/$PROJECT/$IMAGE_NAME:$IMAGE_TAG
  only:
    - tags

对于传统主机部署,使用SSH方案:

.deploy-ssh: &deploy-ssh
  image: alpine:3.16
  before_script:
    - apk add --no-cache openssh-client
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | ssh-add -
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh

deploy-uat:
  <<: *deploy-ssh
  script:
    - ssh deploy@server01 "docker pull $IMAGE_TAG && docker-compose up -d"

6. 性能调优与问题诊断

6.1 构建加速实测数据

通过以下优化手段可将构建时间缩短60%以上:

  1. BuildKit内联缓存:减少50%重复构建时间
  2. 依赖缓存镜像:节省Maven下载时间(约30秒)
  3. 并行测试执行:配置maven-surefire-plugin
<!-- pom.xml配置示例 -->
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <forkCount>3</forkCount>
    <reuseForks>true</reuseForks>
  </configuration>
</plugin>

6.2 常见错误排查指南

问题1:Docker连接被拒绝
Cannot connect to the Docker daemon at unix:///var/run/docker.sock

解决方案:

  1. 确认Runner有docker.sock访问权限
  2. 在.gitlab-ci.yml中添加:
    variables:
      DOCKER_HOST: unix:///var/run/docker.sock
    
问题2:Harbor推送权限不足
denied: requested access to the resource is denied

检查清单:

  1. 机器人账户是否有项目推送权限
  2. 镜像路径是否匹配Harbor项目名
  3. CI变量是否设置为Protected(仅保护分支可用)
问题3:BuildKit缓存失效

现象:二次构建未利用缓存 调试命令:

docker build --progress=plain 2>&1 | grep 'using cache'

确保构建参数包含:

--build-arg BUILDKIT_INLINE_CACHE=1 \
--cache-from $CACHE_IMAGE

在实际项目中,建议先搭建测试流水线验证各环节,再逐步应用到生产环境。我曾在一个电商项目中通过这套方案将部署频率从每周1次提升到每日10+次,且未出现版本混乱问题。关键点在于严格的标签策略和Harbor的镜像保留规则配合。

更多推荐