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 的配置文件 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)推送打包部署的任务。
附上一个原理图(来自官网的) 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/
51cto: 基于gitlab-ci实现maven及docker缓存的配置
CSDN:Gitlab CI配置文件job的script中执行if、for等
注意:本文归作者所有,未经作者允许,不得转载