参考示例 {id=demo}
源码 {id=source}
理论执行效率
shell > docker_sock > docker_host > using_docker_build > using_kaniko
| 分支 | 关键流程 | 优点 |
|---|---|---|
shell |
无需创建容器,直接使用宿主机的 docker 服务 | 可使用历史镜像、构建缓存 |
docker_sock |
使用 docker:cli 镜像 创建容器 时 挂载宿主机的 docker.sock,直接利用宿主机的 docker.sock 服务 |
可使用历史镜像、构建缓存 |
docker_host |
使用 docker:cli 镜像 创建容器 后,使用网络与 docker 服务进行通信 |
可使用历史镜像、构建缓存 |
using_docker_build |
使用 docker:cli 镜像 创建容器 后,再使用 docker:dind 镜像创建 docker 服务 |
不可使用历史镜像、构建缓存 |
using_kaniko |
使用 gcr.io/kaniko-project/executor 镜像 创建容器,模拟 docker 功能 |
不可使用历史镜像、构建缓存 |
修改 GitLab Runner 运行时用户 {id=service-running}
- 根据需要进行调整
# 查看当前runner用户
ps aux | grep gitlab-runner
# 删除gitlab-runner
sudo gitlab-runner uninstall
# 安装并设置--user(例如我想设置为root)
sudo gitlab-runner install --working-directory /home/gitlab-runner --user root
# 重启gitlab-runner
sudo service gitlab-runner restart
# 再次执行会发现--user的用户名已经更换成root了
ps aux | grep gitlab-runner
方案 1:使用 Docker-in-Docker 构建 Docker 镜像 {id=plan-1}
文档 {id=plan-1-docs}
- 极狐 GitLab:中文文档
介绍 {id=plan-1-intro}
在 Docker 中使用 Docker 镜像创建 Docker 容器,并在该容器内构建 Docker 镜像
- Docker 构建时的环境是一个独立的、隔离的 Docker 环境
- 需要 特权身份 运行 GitLab 流水线,
可能存在越权行为 - GitLab Runner 流水线 使用 Docker-in-Docker 执行时需要创建两个容器
- 使用
docker:cli创建一个 Docker 客户端容器,也就是流水线执行时的容器- 在早期相关文档介绍时,使用
docker:latest(最新版Docker命令行镜像)、
docker:26.1.1(指定版本的Docker命令行镜像)、
26.1.1-alpine3.19(指定版本的使用alpine为基础镜像的Docker命令行镜像) - 在比较新的相关文档介绍时,使用
docker:cli(最新版、最小化Docker命令行镜像)、
docker:26.1.1-cli(指定版本的、最小化Docker命令行镜像)、
docker:26.1.1-cli-alpine3.19(指定版本的、最小化使用alpine为基础镜像的Docker命令行镜像)
- 在早期相关文档介绍时,使用
- 使用
docker:dind创建一个 Docker 服务端容器,此容器需要使用 特权身份
运行- 在流水线中,使用关键字 services 来创建流水线执行时所需的服务
- GitLab Runner Docker 执行器 特权身份 配置,其他执行器配置雷同
# 配置文件位置:/etc/gitlab-runner/config.toml [[runners]] name = "lighthouse-docker" url = "https://jihulab.com/" ...省略 executor = "docker" [runners.docker] # 此处配置 privileged = true,让流水线使用特权身份执行 privileged = true ...省略
- 使用
- 支持 GitLab Runner 执行器:
docker、docker+machine、kubernetes等等 - 具体配置请参见 参考示例 的
using_docker_build分支 - 由于每次执行时,都是创建一个新的 docker 服务,因此无法使用历史镜像,如果基础镜像很大,每次构建都会重新拉取,影响构建速度
方案 2:使用 kaniko 构建 Docker 镜像 {id=plan-2}
文档 {id=plan-2-docs}
- 极狐 GitLab:中文文档
介绍 {id=plan-2-intro}
使用 gcr.io/kaniko-project/executor:debug 模拟 Docker 环境制作 Docker 镜像,无需特权身份运行
- Docker 构建时的环境是一个独立的、隔离的 Docker 环境
- 不需要 特权身份 运行 GitLab 流水线,不存在越权行为
- GitLab Runner 流水线 使用 kaniko 执行时只需要创建一个容器
- 支持 GitLab Runner 执行器:
docker、docker+machine、kubernetes等等 gcr.io/kaniko-project/executor:debug是最新版的镜像,推荐使用
具体版本(为了防止某天镜像进行不兼容更新造成异常)的kaniko镜像,
如:gcr.io/kaniko-project/executor:v1.21.0-debug,可访问
kaniko 仓库 仓库的
标签 来选择具体的版本- 由于国内可能无法访问
gcr.io域名,推荐大家使用作者个人镜像
xuxiaoweicomcn/kaniko-project-executor- 镜像标签名与原始标签保持一致即可
- 使用 GitLab 流水线 每周自动同步一次,镜像内容未做任何修改
- 具体配置请参见 参考示例 的
using_kaniko分支 - kaniko 无法使用历史镜像,如果基础镜像很大,每次构建都会重新拉取,影响构建速度
方案 3:使用 DOCKER_HOST 环境变量 指定现存的 Docker 服务 构建 Docker 镜像 {id=plan-3}
文档 {id=plan-3-docs}
介绍 {id=plan-3-intro}
执行 Docker 命令 时,Docker 命令行工具 会 检查 环境变量 DOCKER_HOST 是否存在,如果存在时,Docker 命令行工具会与之通信,
用于完成 Docker 执行的命令
- Docker 构建时的环境是一个已经存在的环境,非独立环境
- 不需要 特权身份 运行 GitLab 流水线,不存在越权行为
- 环境变量
DOCKER_HOST的示例:tcp://192.168.5.4:2375(即:http)、tcp://192.168.5.4:2376(即:https,需要配置证书才能使用) - 已安装的 Docker 服务,默认不开启远程调用的端口(即:默认不开启
2375、2376端口),如需开启,请参考下列配置:- 以下以 Docker 服务的宿主机的 IP 是
192.168.5.4为例,Docker 服务仅开启 监听2375、2376端口,不监听其他 IP
(防止云服务器意外暴露 Docker 端口时,被其他人恶意访问,导致信息泄露) - 编辑 Docker 服务
vim /lib/systemd/system/docker.service - 默认 Docker 服务
[Unit] ... 省略 [Service] Type=notify ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock ... 省略 [Install] ... 省略 - 修改 Docker 服务
[Unit] ... 省略 [Service] Type=notify # 此处配置 Docker 监听的 端口 对应的 IP 是服务器的 内网IP,当且仅当使用 192.168.5.4:2375 才能与 Docker 进行远程通信 # 强烈不建议此处配置为 tcp://0.0.0.0:2375,是为了防止云服务器意外暴露 Docker 端口时,被其他人使用 公网IP 恶意访问,导致信息泄露 # 强烈不建议此处配置为 tcp://公网IP:2375,是为了防止云服务器意外暴露 Docker 端口时,被其他人使用 公网IP 恶意访问,导致信息泄露 # 如需监听公网 IP,请使用云服务安全组、服务器防火墙限制 IP 访问 Docker 端口,用于提高安全性 ExecStart=/usr/bin/dockerd -H tcp://192.168.5.4:2375 -H unix:///var/run/docker.sock ... 省略 [Install] ... 省略
- 以下以 Docker 服务的宿主机的 IP 是
- 支持 GitLab Runner 执行器:
docker、docker+machine、kubernetes等等 - 具体配置请参见 参考示例 的
docker_host分支 - 可以使用历史镜像,基础镜像只会拉取一次,可有效提高构建速度
方案 4:使用宿主机 docker.sock 提供 Docker 服务 构建 Docker 镜像 {id=plan-4}
文档 {id=plan-4-docs}
介绍 {id=plan-4-intro}
执行 Docker 命令 时,Docker 命令行工具 会 检查 目录 /var/run/docker.sock、/run/docker.sock 是否存在,如果存在时,Docker
命令行工具会与之通信,用于完成 Docker 执行的命令
- Docker 构建时的环境是一个已经存在的环境,非独立环境
- 不需要 特权身份 运行 GitLab 流水线,不存在越权行为
- 需要在 GitLab Runner 执行器所在的宿主机安装 Docker 服务,并保持 Docker 正常运行
- 需要在 GitLab Runner 执行器配置文件(夹)路径挂载
- GitLab Runner Docker 执行器 文件(夹)路径挂载 配置,其他执行器配置雷同
# 配置文件位置:/etc/gitlab-runner/config.toml [[runners]] name = "lighthouse-docker" url = "https://jihulab.com/" ...省略 executor = "docker" [runners.docker] ...省略 volumes = ["/run/docker.sock:/run/docker.sock"] ...省略
- GitLab Runner Docker 执行器 文件(夹)路径挂载 配置,其他执行器配置雷同
- 支持 GitLab Runner 执行器:
docker、docker+machine、kubernetes等等 - 具体配置请参见 参考示例 的
docker_sock分支 - 可以使用历史镜像,基础镜像只会拉取一次,可有效提高构建速度
方案 5:使用 Shell 直接构建 Docker 镜像 {id=plan-5}
直接使用 Shell 执行器构建 Docker 镜像,无需镜像
- Docker 构建时的环境是一个已经存在的环境,非独立环境,在 GitLab Runner 执行器宿主机上直接执行
- 需要在 GitLab Runner 执行器所在的宿主机安装 Docker 服务,并保持 Docker 正常运行
- 需要 GitLab Runner 运行时用户可正常执行 Docker 命令
- 支持 GitLab Runner 执行器:
shell - 具体配置请参见 参考示例 的
shell分支 - 可以使用历史镜像,基础镜像只会拉取一次,可有效提高构建速度