Gitlab自动化部署SpringBoot项目

ragnar 1年前 ⋅ 359 阅读

1 环境信息

  • 管理节点:Gitlab version: 16.3
  • 资源节点:
    • Gitlab-Runner version:latest
    • Docker version: 24.0.5

.gitlab-ci.yml keyword reference

2 步骤

  • 确认有 runners 可以执行你的作业。
  • 创建一个 .gitlab-ci.yml 文件在项目的根目录下。这个文件定义了 CI/CD 作业。

3 安装 Gitlab Runner

官方文档:https://docs.gitlab.com/runner/

3.1 Docker方式

# 拉取镜像(最新版本)
docker pull gitlab/gitlab-runner

# 运行容器
## 开启 8093 端口用于 session_server 
## 挂载卷,用于容器存储路径:/etc/gitlab-runner
docker run -d -p 8093:8093 \
-v /home/docker/gitlab-runner:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
--name gitlab-runner01 --restart always \
gitlab/gitlab-runner

3.2 安装包方式

Linux: https://docs.gitlab.com/runner/install/linux-repository.html

(略)
国内下载资源会比较慢

4 Runner 的注册

进入容器:

docker exec -it gitlab-runner01 /bin/bash

命令行注册:

gitlab-runner register \
--url http://www.ragnar.website/ \
--registration-token REGISTER_TOKEN

然后就是根据提示逐项输入。runners 那里,我们选择Docker

REGISTER_TOKEN 来自管理节点是生成的(如下图): gitlab-runner_注册token生成.png

最终生成 Gitlab Runner 的配置文件 config.toml
【文件在容器的 /etc/gitlab-runner 目录下。gitlab-runner 将以此与其管理节点连接】

concurrent = 1
check_interval = 0
shutdown_timeout = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "pro"
  url = "http://your_gitlab_host"
  id = 14
  token = "REGISTER_TOKEN"
  token_obtained_at = 2023-11-19T08:09:46Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "docker"
  [runners.cache]
    MaxUploadedArchiveSize = 0
  [runners.docker]
    tls_verify = false
    image = "docker:stable"
    privileged = true
    services_privileged = true
    allowed_privileged_services = ["docker.io/library/docker:*-dind-rootless", "docker.io/library/docker:dind-rootless", "docker:*-dind-rootless", "docker:dind-rootless"]
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = true
    volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
    shm_size = 0
    network_mtu = 0

5 配置CI/CD的 .gitlab-ci.yml 文件

官方文档:https://docs.gitlab.com/ee/ci/yaml/

只供参考

variables:
  MAVEN_CONFIG: "$CI_PROJECT_DIR/.m2"

services:
  - docker:24.0.5-dind # 默认镜像

stages:          # List of stages for jobs, and their order of execution
  - build
  - deploy

# 构建阶段:把项目打成 jar 包
build-job:
  stage: build
  only:
    - master # 表示只适合用 master 分支
  image: maven:3.5.4-jdk-8 # 选择合适的镜像(环境)去执行
  before_script:
    - mkdir $HOME/.m2
  script:
    - echo "Compiling the code..."
    - mvn clean package -Dmaven.test.skip=true
    - echo "Compile complete."
  artifacts:
    paths:
      - target/your_app.jar
  cache:
    paths:
      - $HOME/.m2/repository
      
# 部署阶段:构建docker镜像并部署
deploy-job:      # This job runs in the deploy stage.
  stage: deploy  # It only runs when *both* jobs in the test stage complete successfully.
  only:
    - master # 表示只适合用 master 分支
  environment: production
  image: docker
  script:
    - docker info
    - echo "Deploying application..."
    - echo "..."
    - version=$(date +%Y%m%d%H%M%S)
    - docker build -t your_app:${version} .
    - echo "..."
    - echo "Docker image successfully builded"
    - echo "..."
    - if [ -n $(docker ps -q -f "name=^your_app$") ];
    - then
    - docker stop your_app
    - docker rm your_app
    - fi
    - docker run -id --restart=always --name=your_app -p 8080:8080 your_app:${version}
    - echo "..."
    - echo "Application successfully deployed."
  when: manual  # manual 手动执行任务

只要提交commit合并到master分支,就能触发CI。管理节点(gitlab)一般会根据标签stage向对应的资源节点(gitlab-runner)推送打包部署的任务。

附上一个原理图(来自官网的) gitlab-runner_执行流程.png PS:上图的 Executor 在本文中是一个docker容器。也就是会创建一个docker容器去执行这个打包部署的任务。

6 什么是 Docker in Docker?

Docker in Docker (DIND) 是指在一个Docker容器中运行另一个Docker容器的概念。这种技术允许用户在一个Docker容器中创建和管理其他Docker容器, 使得在容器内部可以进行Docker相关操作,包括构建、运行和管理镜像以及启动和停止容器等。

对于GitLab来说,DIND可以用于在GitLab Runner容器内部创建和管理其他容器。GitLab Runner负责在GitLab CI/CD流水线中执行构建、测试和部署任务, 而DIND可以为每个job(任务)创建一个隔离的Docker环境,以确保任务在可靠且一致的环境中运行。这种方式能够提供更好的隔离性和环境一致性, 并且可以大大简化任务配置和管理的复杂性。

7 遇到问题

  • 作业已阻塞,因为该项目没有分配任何可用Runner,但已经有在线的 Runner 的。

    • 原因:注册 Runner 时,都没有勾选“运行未标记的作业”选项(默认)。但 JOB 是要用 stage 去配置对应标记的 Runner,所以会导致新创建的无标记的作业没有 Runner 去执行。
    • 解决:有 Runner 勾选上该选项即可。
  • ERROR: Failed to remove network for build

    • 原因:用的 docker 方式,但没有把宿主机的 docker.sock 挂载到容器上。
    • 解决:把 /var/run/docker.sock 目录挂载上即可【windows也是 /var/run/docker.sock 目录】
  • fatal: unable to access 'http://www.ragnar.website/rollo/vikingship-blog.git/': SSL certificate problem: unable to get local issuer certificate

    • 原因:端口问题。gitlab的流水线的作业在拉取代码时的URL没办法定置,家庭宽带的80端口被封。
    • 解决:修改 gitlab 的配置文件 gitlab.rb 指定两项配置,把端口改为 9000:
      -> external_url 'http:www.ragnar.website:9000'
      -> nginx['listen_port'] = 9000
  • gitlab-runner 的 executor 选择的是 docker,明明在 gitlab-runner 所在的环境安装了 jdk 和 maven,但作业执行时还是报: mvn 命令不存在、java 命令不存在等报错。

    • 原因: 这个 executer 就是起一个 docker 容器来执行。即选择的 docker 镜像有 maven 和 jdk 等就可以直接拿来用,否则就得先安装相关的软件;
    • 解决: 在 .gitlab-ci.yml 文件中声明 executor 所用的镜像: image: maven:3.5.4-jdk-8
  • 每次执行时,maven 每次都得从远端的 maven 仓库下载一批相同的jar包,导致每次 build 的耗时都很长。如何能复用这些jar包?

  • 构建 docker 镜像时报错: /bin/bash: line 149: docker: command not found

  • docker 容器正常运行后,如何切换新老容器的流量?

其它方案

  • gitlab + jenkins 自动化部署

参考

官网文档 https://docs.gitlab.com/ee/ci/yaml/

CSDN: gitlab CI/CD自动化部署

51cto: 基于gitlab-ci实现maven及docker缓存的配置

CSDN:Gitlab CI配置文件job的script中执行if、for等


全部评论: 0

    我有话说:

    目录