- Docker 执行器工作流
- 支持的配置
- 使用 Docker 执行器
- 配置镜像和 Services
- 定义
.gitlab-ci.yml
中的镜像和服务 - 定义
config.toml
中的镜像和服务 - 定义私有镜像库中的镜像
- 网络配置
- 限制 Docker 镜像和服务
- 访问服务主机名
- 配置服务
- 在 RAM 中挂载目录
- 在服务中构建目录
- 指定 Docker driver 操作
- 为容器构建和缓存配置目录
- 持久化存储
- IPC 模式
- 特权模式
- 配置 Docker 入口点(ENTRYPOINT)
- 使用 Podman 运行 Docker 命令
- 指定运行作业的用户
- 配置 Runner 如何拉取镜像
- 重试失败的拉取
- Docker vs Docker-SSH(Docker+Machine vs Docker-SSH+Machine)(已移除)
- 使用 Windows 容器
- 原生 Step Runner 的集成
Docker 执行器
极狐GitLab Runner 使用 Docker 执行器在 Docker 镜像上运行作业。
您可以使用 Docker 执行器来:
- 为每个作业保持相同的构建环境。
- 使用相同的镜像在本地测试命令,而无需在 CI 服务器中运行作业。
Docker 执行器使用 Docker Engine 在单独和隔离的容器中运行每个作业。要连接到 Docker 引擎,执行器使用:
- 您在
.gitlab-ci.yml
中定义的镜像和服务。 - 您在
config.toml
中定义的配置。
前提条件:
Docker 执行器工作流
Docker 执行器使用基于 Alpine Linux 的特殊 Docker 镜像,该镜像包含运行准备、作业前和作业后步骤的工具。
Docker 执行器将作业分为几个步骤:
- 准备:创建并启动服务。
- 作业前:克隆、恢复缓存,并从前面的阶段下载产物。 在特殊的 Docker 镜像上运行。
- 作业中:在您为 Runner 配置的 Docker 镜像中运行您的构建。
- 作业后:创建缓存,上传产物到极狐GitLab。运行在特殊的 Docker 镜像上。
支持的配置
Docker 执行器支持以下配置。
对于已知的 Windows 问题和其他要求,请使用 Windows 容器。
Runner 安装在 | 执行器 | 容器运行 |
---|---|---|
Windows | docker-windows |
Windows |
Windows | docker |
Linux |
Linux | docker |
Linux |
不支持以下配置:
Runner 安装在 | 执行器 | 容器运行 |
---|---|---|
Linux | docker-windows |
Linux |
Linux | docker |
Windows |
Linux | docker-windows |
Windows |
Windows | docker |
Windows |
Windows | docker-windows |
Linux |
1.13.0
;
Windows 服务器上需要更高版本以识别 Windows 服务器版本。使用 Docker 执行器
要使用 Docker 执行器,请在 config.toml
中将 Docker 定义为执行器。
以下示例显示了定义为执行器的 Docker 和示例配置。有关这些值的更多信息,请参阅高级配置
concurrent = 4
[[runners]]
name = "myRunner"
url = "https://gitlab.com/ci"
token = "......"
executor = "docker"
[runners.docker]
tls_verify = true
image = "my.registry.tld:5000/alpine:latest"
privileged = false
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = [
"/cache",
]
shm_size = 0
allowed_pull_policies = ["always", "if-not-present"]
allowed_images = ["my.registry.tld:5000/*:*"]
allowed_services = ["my.registry.tld:5000/*:*"]
[runners.docker.volume_driver_ops]
"size" = "50G"
配置镜像和 Services
先决条件:
- 运行作业的镜像必须在其操作系统
PATH
中有一个 working shell。支持的 shell 为:- 对于 Linux:
sh
bash
- PowerShell Core (
pwsh
)。引入于 13.9。
- 对于 Windows
- PowerShell (
powershell
) - PowerShell Core (
pwsh
)。引入于 13.6。
- PowerShell (
- 对于 Linux:
要配置 Docker 执行器,您可以在 .gitlab-ci.yml
和 config. toml
中定义 Docker 镜像和 services。
使用以下关键字:
-
image
:Runner 用来运行作业的 Docker 镜像的名称。- 输入来自本地 Docker Engine 的镜像,或 Docker Hub 中的任何镜像。 有关详细信息,请参阅 Docker 文档。
- 要定义镜像版本,请使用冒号 (
:
) 添加标签。如果您不指定标签,Docker 使用latest
作为版本。
-
services
:创建另一个容器并链接到image
的其他镜像。有关 services 类型的更多信息,请参阅 Services。
定义 .gitlab-ci.yml
中的镜像和服务
定义 Runner 用于所有作业的镜像和在构建期间使用的服务列表。
示例:
image: ruby:2.7
services:
- postgres:9.3
before_script:
- bundle install
test:
script:
- bundle exec rake spec
要为每个作业定义不同的镜像和服务:
before_script:
- bundle install
test:2.6:
image: ruby:2.6
services:
- postgres:9.3
script:
- bundle exec rake spec
test:2.7:
image: ruby:2.7
services:
- postgres:9.4
script:
- bundle exec rake spec
如果您没有在 .gitlab-ci.yml
中定义 image
,Runner 将使用 config.toml
中定义的 image
。
定义 config.toml
中的镜像和服务
要向 Runner 运行的所有作业添加镜像和服务,请更新 config.toml
中的 [runners.docker]
。
如果您没有在 .gitlab-ci.yml
中定义 image
,Runner 将使用 config.toml
中定义的镜像。
示例:
[runners.docker]
image = "ruby:2.7"
[[runners.docker.services]]
name = "mysql:latest"
alias = "db"
[[runners.docker.services]]
name = "redis:latest"
alias = "cache"
这个示例使用表格阵列语法。
定义私有镜像库中的镜像
先决条件:
- 要从私有镜像库访问镜像,您必须验证极狐GitLab Runner。
要从私有镜像库定义镜像,请在 .gitlab-ci.yml
中提供镜像库名称和镜像。
示例:
image: my.registry.tld:5000/namepace/image:tag
在此示例中,极狐GitLab Runner 在镜像库 my.registry.tld:5000
中搜索镜像 namespace/image:tag
。
网络配置
您必须配置网络以将服务连接到 CI/CD 作业。
要配置网络,您可以:
- 推荐。配置 Runner 为每个作业创建网络。
- 定义容器链接。容器链接是 Docker 的遗留功能。
为每个作业创建网络
您可以配置 Runner 为每个作业创建一个网络。
当您启用此网络模式时,Runner 会为每个作业创建并使用一个用户定义的 Docker 桥接网络。 Docker 环境变量不在容器之间共享。更多关于用户定义的桥接网络信息,请参见 Docker 文档。
要使用此网络模式,请在功能标志中启用 FF_NETWORK_PER_BUILD
或在 config.toml
中启用环境变量。
不要设置 network_mode
。
示例:
[[runners]]
(...)
executor = "docker"
environment = ["FF_NETWORK_PER_BUILD = 1"]
或:
[[runners]]
(...)
executor = "docker"
[runners.feature_flags]
FF_NETWORK_PER_BUILD = true
要设置默认的 Docker 地址池,请在 dockerd
中使用 default-address-pool
。
如果已在网络中使用了 CIDR 范围,Docker 网络可能与主机上的其他网络冲突,包括其他 Docker 网络。
此功能仅在 Docker daemon 配置为启用 IPv6 时有效。
要启用 IPv6 支持,请在 Docker 配置中将 enable_ipv6
设置为 true
。
有关详细信息,请参阅 Docker 文档。
Runner 使用 build
别名来解析作业容器。
Runner 如何为每个作业创建网络
作业开始时,Runner:
- 创建桥接网络,类似于 Docker 命令
docker network create <network>
。 - 将服务和容器连接到桥接网络。
- 在作业结束时删除网络。
运行作业的容器和运行服务的容器解析彼此的主机名和别名。 这个功能由 Docker 提供。
使用容器链接配置网络
您可以配置使用 Docker 遗留容器链接和默认 Docker bridge
的网络模式将作业容器与服务进行连接。
如果未启用 FF_NETWORK_PER_BUILD
,这种网络模式是默认的。
要配置网络,请在 config.toml
文件中指定网络模式:
-
bridge
:使用桥接网络。默认。 -
host
:在容器内使用主机的网络栈。 -
none
:没有网络。不建议。
示例:
[[runners]]
(...)
executor = "docker"
[runners.docker]
network_mode = "bridge"
如果您使用任何其他 network_mode
值,这些被视为构建容器连接的现存 Docker 网络的名称。
在名称解析期间,Docker 会使用服务容器主机名和别名更新目录中的 /etc/hosts
文件。
然而,服务容器不能解析容器名称。
要解析容器名称,您必须为每个作业创建一个网络。
链接的容器共享它们的环境变量。
覆盖创建网络的 MTU
在有些环境下,诸如 OpenStack 的虚拟机,自定义 MTU 是有必要的。Docker 守护进程在 docker.json 文件中并不包含 MTUS。您可以在您的 config.toml
文件中将 network_mtu
设为任意有效值,以便 Docker 守护进程可以使用正确的 MTU 创建新的网络。您还必须启用 FF_NETWORK_PER_BUILD
以使覆盖生效。
以下配置将每个作业的创建网络的 MTU 设置为 1402
。您需要确保将此值调整到符合您的实际环境所需。
[[runners]]
(...)
executor = "docker"
[runners.docker]
network_mtu = 1402
[runners.feature_flags]
FF_NETWORK_PER_BUILD = true
限制 Docker 镜像和服务
要限制 Docker 镜像和服务,请在 allowed_images
和 allowed_services
参数中指定通配符模式。
例如,仅允许您的私有 Docker 镜像库的镜像:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
allowed_images = ["my.registry.tld:5000/*:*"]
allowed_services = ["my.registry.tld:5000/*:*"]
要限制您的私有 Docker 镜像库的镜像列表:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
allowed_images = ["my.registry.tld:5000/ruby:*", "my.registry.tld:5000/node:*"]
allowed_services = ["postgres:9.4", "postgres:latest"]
访问服务主机名
要访问服务主机名,请将服务添加到 .gitlab-ci.yml
中的 services
中。
例如,要使用 Wordpress 实例来测试 API 与您的应用程序的集成,请使用 tutum/wordpress 作为服务镜像:
services:
- tutum/wordpress:latest
当作业运行时,tutum/wordpress
服务启动。您可以从主机名为 tutum__wordpress
和 tutum-wordpress
的构建容器进行访问。
除了指定的服务别名之外,Runner 还将服务镜像的名称作为别名分配给服务容器。您可以使用这些别名中的任何一个。
Runner 使用以下规则根据镜像名称创建别名:
- 删除
:
之后的所有内容。 - 对于第一个别名,将斜杠 (
/
) 替换为双下划线 (__
)。 - 对于第二个别名,将斜杠 (
/
) 替换为单破折号 (-
)。
如果您使用私有服务镜像,则 Runner 会剥离任何指定的端口并应用规则。
服务 registry.gitlab-wp.com:4999/tutum/wordpress
会生成主机名 registry.gitlab-wp.com__tutum__wordpress
和 registry.gitlab-wp.com-tutum-wordpress
。
配置服务
要更改数据库名称或设置账户名称,您可以为服务定义环境变量。
当 Runner 传递变量时:
- 变量传递给所有容器。Runner 无法将变量传递给特定容器。
- 安全变量被传递到构建容器。
有关配置变量的更多信息,请参阅相应的 Docker Hub 页面中提供的镜像文档。
在 RAM 中挂载目录
您可以使用 tmpfs
选项在 RAM 中挂载目录。如果有很多 I/O 相关的工作,例如数据库,测试所需的时间会缩短。
如果您在 Runner 配置中使用 tmpfs
和 services_tmpfs
选项,
您可以指定多个路径,每个路径都有自己的选项。有关详细信息,请参阅
Docker 文档。
例如,要在 RAM 中挂载官方 MySQL 容器的数据目录,配置 config.toml
:
[runners.docker]
# For the main container
[runners.docker.tmpfs]
"/var/lib/mysql" = "rw,noexec"
# For services
[runners.docker.services_tmpfs]
"/var/lib/mysql" = "rw,noexec"
在服务中构建目录
极狐GitLab Runner 将 /builds
目录挂载到所有共享服务。
有关使用不同服务的更多信息,请参阅:
极狐GitLab Runner 如何执行服务健康检查
引入多个端口检查于极狐GitLab 16.0。
服务启动后,极狐GitLab Runner 等待服务响应。Docker 执行器尝试打开服务容器中暴露的服务端口的 TCP 连接。
- 在 15.11 及更早版本中,仅检查第一个暴露的端口。
- 在 16.0 及更高版本中,检查前 20 个暴露的端口。
HEALTHCHECK_TCP_PORT
服务变量可用于对特定端口进行健康检查:
job:
services:
- name: mongo
variables:
HEALTHCHECK_TCP_PORT: "27017"
要查看实现方式,请使用健康检查 Go 命令。
指定 Docker driver 操作
当您为构建创建卷时,指定提供给 Docker 卷驱动程序的参数。
例如,除了所有其他特定于驱动程序的选项之外,您还可以使用这些参数来限制每个构建运行的空间。
以下示例显示了 config.toml
,其中每个构建可以使用的限制设置为 50GB。
[runners.docker]
[runners.docker.volume_driver_ops]
"size" = "50G"
为容器构建和缓存配置目录
要定义数据在容器中的存储位置,请配置 config.toml
的 [[runners]]
部分中的 /builds
和 /cache
目录。
如果修改 /cache
存储路径,要将路径标记为永久,您必须在 config.toml
中的 [runners.docker]
部分下的 volumes = ["/my/cache/"]
中进行定义。
默认情况下,Docker 执行器将构建和缓存存储在以下目录中:
- 在
/builds/<namespace>/<project-name>
中构建 - 在容器内的
/cache
中缓存。
清理 Docker 缓存
引入于极狐GitLab Runner 13.9。
使用 clear-docker-cache
移除 Runner 创建的未使用的容器和卷。
对于选项列表,使用 help
选项运行脚本:
clear-docker-cache help
默认选项是 prune-volumes
,它会删除所有未使用的容器(悬挂和未引用的)和卷。
要有效地管理缓存存储,您应该:
- 定期运行带有
cron
的clear-docker-cache
(例如,每周一次)。 - 回收磁盘空间时,维护缓存中最近的容器以提高性能。
清理 Docker 构建镜像
clear-docker-cache
脚本不会移除 Docker 镜像,因为极狐GitLab Runner 没对其打标签。
要清理 Docker 构建镜像:
-
确认可以回收哪些磁盘空间:
clear-docker-cache space Show docker disk usage ---------------------- TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 14 9 1.306GB 545.8MB (41%) Containers 19 18 115kB 0B (0%) Local Volumes 0 0 0B 0B Build Cache 0 0 0B 0B
-
要删除所有未使用的容器、网络、镜像(悬挂和未引用)和未打标签的卷,请运行
docker system prune
。
持久化存储
Docker 执行器在运行容器时提供持久化存储。
所有 volumes =
下定义的目录在构建间都是持久的。
volumes
指令支持以下存储类型:
- 对于动态存储,使用
<path>
。<path>
在项目的同一个并发作业的后续运行中是持久的。 数据附属于自定义缓存卷:runner-<short-token>-project-<id>-concurrent-<concurrency-id>-cache-<md5-of-path>
。 - 对于主机绑定存储,使用
<host-path>:<path>[:<mode>]
。<path>
在主机系统上绑定到<host-path>
。可选的<mode>
指定存储是只读或读写(默认)。
构建的持久化存储
如果您使 /builds
目录成为主机绑定存储,您的构建存储在:
/builds/<short-token>/<concurrent-id>/<namespace>/<project-name>
,其中:
-
<short-token>
是 Runner 的令牌(前 8 个字母)的缩写版本。 -
<concurrent-id>
是一个独特的数字,识别在项目的上下文中的特定 Runner 的本地作业 ID。
IPC 模式
Docker 执行器支持与其他位置共享容器的 IPC 命名空间。
这会映射到 docker run --ipc
标志。
更多内容,请参见 Docker 文档中的 IPC 设置。
特权模式
Docker 执行器支持很多允许构建容器的微调的选项。
其中一个选项是privileged
模式。
通过特权模式使用 Docker-in-Docker
配置的 privileged
标记被传递到构建容器和所有
服务,因此允许容易地使用 Docker-in-Docker 方法。
首先,配置您的 Runner (config.toml
) 在 privileged
模式下运行:
[[runners]]
executor = "docker"
[runners.docker]
privileged = true
然后,让您的构建脚本 (.gitlab-ci.yml
) 使用 Docker-in-Docker
容器:
image: docker:git
services:
- docker:dind
build:
script:
- docker build -t my-image .
- docker push my-image
您可能需要为 Docker in Docker 配置 TLS 或禁用 TLS 以避免发生如下错误:
Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?
在受限特权模式下使用无根 Docker-in-Docker
在此版本中,仅允许 Docker-in-Docker 无根镜像作为服务在特权模式下运行。
services_privileged
和 allowed_privileged_services
配置参数限制允许在特权模式下运行的容器。
要在受限特权模式下使用无根 Docker-in-Docker:
-
在
config.toml
中,配置 Runner 使用services_privileged
和allowed_privileged_services
:[[runners]] executor = "docker" [runners.docker] services_privileged = true allowed_privileged_services = [docker.io/library/docker:*-dind-rootless, docker.io/library/docker:dind-rootless, docker:*-dind-rootless, docker:*-dind-rootless]
-
在
.gitlab-ci.yml
中,编辑构建脚本以使用 Docker-in-Docker 无根容器:image: docker:git services: - docker:dind-rootless build: script: - docker build -t my-image . - docker push my-image
只有您在 allowed_privileged_services
中列出的 Docker-in-Docker 无根镜像才允许在特权模式下运行。
用于作业和服务的所有其他容器都以非特权模式运行。
因为它们以非 root 身份运行,所以与 Docker-in-Docker rootless 或 Buildkit rootless 等特权模式镜像一起使用几乎是安全的。
有关安全问题的更多信息,请参阅 Docker 执行器的安全风险。
配置 Docker 入口点(ENTRYPOINT)
默认情况下,Docker 执行器不会覆盖 Docker 镜像的 ENTRYPOINT
并将 sh
或 bash
作为 COMMAND
进行传递以启动运行作业脚本的容器。
为确保作业可以运行,其 Docker 镜像必须:
- 提供
sh
或bash
。 - 定义一个
ENTRYPOINT
,在将sh
/bash
作为参数进行传递时启动 shell。
Docker 执行器使用与以下命令等效的命令运行作业的容器:
docker run <image> sh -c "echo 'It works!'" # or bash
如果您的 Docker 镜像不支持此机制,您可以在项目配置中覆盖镜像的入口点,如下所示:
# Equivalent of
# docker run --entrypoint "" <image> sh -c "echo 'It works!'"
image:
name: my-image
entrypoint: [""]
有关详细信息,请参阅覆盖镜像的入口点和 CMD 和 ENTRYPOINT 如何在 Docker 中交互。
作业脚本作为 ENTRYPOINT
您可以使用 ENTRYPOINT
创建一个在自定义环境或安全模式下运行构建脚本的 Docker 镜像。
例如,您可以创建一个使用 ENTRYPOINT
但不执行构建脚本的 Docker 镜像。
相反,Docker 镜像执行一组预定义的命令,从您的目录构建 Docker 镜像。您以特权模式运行构建容器,并且确保 Runner 构建环境的安全。
-
创建新的 Dockerfile:
FROM docker:dind ADD / /entrypoint.sh ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]
-
创建被用作
ENTRYPOINT
的 Bash 脚本 (entrypoint.sh
):#!/bin/sh dind docker daemon --host=unix:///var/run/docker.sock \ --host=tcp://0.0.0.0:2375 \ --storage-driver=vf & docker build -t "$BUILD_IMAGE" . docker push "$BUILD_IMAGE"
-
将镜像推送到 Docker 镜像库。
-
以
privileged
模式运行 Docker 执行器。在config.toml
中定义:[[runners]] executor = "docker" [runners.docker] privileged = true
-
在您的项目中,使用以下
.gitlab-ci.yml
:variables: BUILD_IMAGE: my.image build: image: my/docker-build:image script: - Dummy Script
使用 Podman 运行 Docker 命令
引入于极狐GitLab 15.3。
如果您在 Linux 上安装了就GitLab Runner,您的作业可以使用 Podman 代替 Docker 作为 Docker 执行器中的容器运行时。
先决条件:
- Podman v4.2.0 或更高版本。
- 要使用 Podman 作为执行器运行服务,请启用
FF_NETWORK_PER_BUILD
功能标志。 Docker 容器链接 是旧版并且 Podman 不支持。对于创建网络别名的服务,您必须安装podman-plugins
软件包。
- 在您的 Linux 主机上,安装极狐GitLab Runner。如果您使用系统的包管理器安装了极狐GitLab Runner,它会自动创建一个
gitlab-runner
用户。 - 以运行极狐GitLab Runner 的用户身份登录。您必须以不绕过
pam_systemd
的方式处理。 您可以以正确的用户身份使用 SSH,因为这样您可以以该用户身份运行systemctl
。 - 确保您的系统满足 Rootless Podman 设置的先决条件。
具体来说,确保您的用户在
/etc/subuid
和/etc/subgid
拥有正确的条目。 - 在 Linux 主机上,安装 Podman。
-
启用并启动 Podman 套接字:
systemctl --user --now enable podman.socket
-
验证 Podman 套接字正在监听:
systemctl status --user podman.socket
- 复制
Listen
密钥中的套接字字符串,通过该密钥可以访问 Podman 的 API。 -
确保在极狐GitLab Runner 用户登出后,Podman 套接字仍然可用:
sudo loginctl enable-linger gitlab-runner
-
编辑极狐GitLab Runner
config.toml
文件并向[[runners.docker]]
部分中的服务器条目添加套接字值。例如:
[[runners]] name = "podman-test-runner-2022-06-07" url = "https://jihulab.com" token = "x-XxXXXXX-xxXxXxxxxx" executor = "docker" [runners.docker] host = "unix:///run/user/1012/podman/podman.sock" tls_verify = false image = "quay.io/podman/stable" privileged = true
使用 Podman 从 Dockerfile 构建容器镜像
下面的示例描述如何使用 Podman 构建容器镜像并将镜像推送到极狐GitLab 容器镜像库。Runner config.toml
中的默认容器镜像设置为 quay.io/podman/stable
,所以 CI 作业将默认使用该镜像来执行包含的命令。
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
before_script:
- podman login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
oci-container-build:
stage: build
script:
- podman build -t $IMAGE_TAG .
- podman push $IMAGE_TAG
when: manual
使用 Buildah 从 Dockerfile 构建容器镜像
下面的示例描述如何使用 Buildah 构建容器镜像并将镜像推送到极狐GitLab 容器镜像库。
image: quay.io/buildah/stable
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
before_script:
- buildah login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
oci-container-build:
stage: build
script:
- buildah bud -t $IMAGE_TAG .
- buildah push $IMAGE_TAG
when: manual
指定运行作业的用户
默认情况下,Runner 在容器内以 root
用户的身份运行作业。为了指定不同的、非根用户运行作业,使用 Docker 镜像的 Docker 文件中的 USER
指令。
FROM amazonlinux
RUN ["yum", "install", "-y", "nginx"]
RUN ["useradd", "www"]
USER "www"
CMD ["/bin/bash"]
当您使用 Docker 镜像执行作业,它作为特定用户运行:
build:
image: my/docker-build:image
script:
- whoami # www
配置 Runner 如何拉取镜像
在 config.toml
中配置拉取策略以定义 Runner 如何从镜像库拉取 Docker 镜像。您可以设置单个策略、策略列表或允许特定的拉取策略。
为 pull_policy
使用以下值:
-
always
:即使本地镜像存在也拉取镜像。默认。 -
if-not-present
:仅在本地版本不存在时拉取镜像。 -
never
: 从不拉取镜像,只使用本地镜像。
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
pull_policy = "always" # available: always, if-not-present, never
设置always
拉取策略
默认情况下打开的 always
选项总是在创建容器之前启动拉取。
此选项确保镜像是最新的,并且即使存在本地镜像,也可以防止您使用过期的镜像。
在以下情况下使用此拉取策略:
- Runner 必须始终拉取最新的镜像。
- Runner 公开可用,并配置为弹性伸缩或作为您的极狐GitLab 实例中的共享 Runner。
如果 Runner 必须使用本地存储的镜像,请勿使用此政策。
在 config.toml
中将 always
设置为 pull policy
:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
pull_policy = "always"
设置 if-not-present
拉取策略
当您将拉取策略设置为 if-not-present
时,Runner 首先检查是否存在本地镜像。
如果没有本地镜像,Runner 会从镜像库拉取镜像。
使用 if-not-present
策略:
- 使用本地镜像,但如果本地镜像不存在,也会拉取镜像。
- 减少 Runner 分析频繁和很少更新镜像的镜像层差异的时间。 在这种情况下,您必须定期从本地 Docker Engine 存储中手动删除镜像以强制更新镜像。
不要使用此政策:
- 对于共享 Runner,使用 Runner 的不同用户可能可以访问私有镜像。 有关安全问题的详细信息,请参阅使用带有 if-not-present 拉取策略的私有 Docker 镜像。
- 如果作业经常更新并且必须在最新的镜像版本中运行。 这可能会导致网络负载减少,会超过频繁删除本地镜像的价值。
在 config.toml 中设置 if-not-present
策略:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
pull_policy = "if-not-present"
设置 never
拉取策略
先决条件:
- 本地镜像必须包含已安装的 Docker 引擎和已用镜像的本地副本。
当您将拉取策略设置为 never
时,镜像拉取将被禁用。用户只能使用在运行 Runner 的 Docker 主机上手动拉取的镜像。
使用 never
拉取策略:
- 控制 Runner 用户使用的镜像。
- 对于专用于只能使用在任何镜像库中不公开可用的特定镜像的项目的私有 Runner。
不要对弹性伸缩的 Docker 执行器使用 never
拉取策略。
never
拉取策略仅在使用所选云提供商的预定义的云实例镜像时可用。
在 config.toml
中设置 never
策略:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
pull_policy = "if-not-present"
设置多个拉取策略
引入于极狐GitLab Runner 13.8。
如果拉取失败,您可以列出要执行的多个拉取策略。Runner 按照列出的顺序处理拉取策略,直到拉取尝试成功或列表耗尽。
例如,如果一个 Runner 使用 always
拉取策略并且镜像库不可用,您可以将 if-not-present
添加为使用本地缓存的 Docker 镜像的第二个拉取策略。
有关此拉取策略的安全影响,请参阅使用带有 if-not-present 拉取策略的私有 Docker 镜像。
要设置多个拉取策略,请将其作为列表添加到 config.toml
中:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
pull_policy = ["always", "if-not-present"]
允许 Docker 拉取策略
引入于极狐GitLab 15.1。
在 .gitlab-ci.yml
文件中,您可以指定拉取策略。该策略决定了 CI/CD 作业如何获取镜像。
要限制可以在 .gitlab-ci.yml
文件中使用的拉取策略,请使用 allowed_pull_policies
。
例如,要仅允许 always
和 if-not-present
拉取策略,请将其添加到 config.toml
中:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
allowed_pull_policies = ["always", "if-not-present"]
- 如果不指定
allowed_pull_policies
,则默认为pull_policy
关键字中的值。 - 如果不指定
pull_policy
,则默认为always
。 - 现有的
pull_policy
关键字不得包含未在allowed_pull_policies
中指定的拉取策略。如果包含,则作业返回错误。
镜像拉取错误信息
错误信息 | 描述 |
---|---|
Pulling docker image registry.tld/my/image:latest ... ERROR: Build failed: Error: image registry.tld/my/image:latest not found |
Runner 无法找到镜像。当设置了 always 拉取策略时显示。 |
Pulling docker image local_image:latest ... ERROR: Build failed: Error: image local_image:latest not found |
该镜像是本地构建的,不存在于任何公共或默认的 Docker 镜像库中。设置 always 拉取策略时显示。 |
Pulling docker image registry.tld/my/image:latest ... WARNING: Cannot pull the latest version of image registry.tld/my/image:latest : Error: image registry.tld/my/image:latest not found WARNING: Locally found image will be used instead. |
Runner 使用了本地镜像,没有拉取镜像。只有设置 always 拉取策略且版本为 1.8 及更早版本时显示。 |
Pulling docker image local_image:latest ... ERROR: Build failed: Error: image local_image:latest not found |
无法本地找到镜像。设置 never 拉取策略时显示。 |
WARNING: Failed to pull image with policy "always": Error response from daemon: received unexpected HTTP status: 502 Bad Gateway (docker.go:143:0s) Attempt #2: Trying "if-not-present" pull policy Using locally found image version due to "if-not-present" pull policy |
Runner 拉取镜像失败,尝试使用下一个列出的拉取策略拉取镜像。设置多个拉取策略时显示。 |
重试失败的拉取
要将 Runner 配置为重试失败的镜像拉取,请多次在 config.toml
中指定相同的策略。
例如,此配置会重试拉取一次:
[runners.docker]
pull_policy = ["always", "always"]
此设置类似于项目的 .gitlab-ci.yml
文件中的 retry
指令,但只有当 Docker 拉取最初失败时才会生效。
Docker vs Docker-SSH(Docker+Machine vs Docker-SSH+Machine)(已移除)
此功能移除于极狐GitLab 16.0。
使用 Windows 容器
引入于极狐GitLab Runner 11.11。
如果您想通过 Docker 执行器使用 Windows 容器,您需要注意以下有关限制、支持的 Windows 版本和配置 Windows Docker 执行器的内容。
Nanoserver 支持
引入于极狐GitLab Runner 13.6。
基于 Windows Helper 镜像中引入的对 PowerShell Core 的支持,现在可以为 Helper 镜像使用
nanoserver
变量。
Windows 上 Docker 执行器的限制
以下是通过 Docker 执行器使用 Windows 容器的限制:
- 不支持 Docker-in-Docker,因为 Docker 本身就不支持。
- 不支持交互式网页终端。
- 不支持主机设备加载。
-
docker-windows
执行器只有在极狐GitLab Runner 运行在 Windows 上时可以运行。 - 不支持 Windows 上的 Linux 容器, 因为仍处于实验阶段。
-
由于 Docker 限制,如果目的路径驱动字母不是
c:
,路径不支持于:这表明不支持
f:\\cache_dir
这样的值,但是支持f:
。 然而,支持c:
驱动上的目的路径(例如c:\\cache_dir
)。要配置 Docker daemon 保存镜像和容器的位置,请更新 Docker daemon 的
daemon.json
文件中的data-root
参数。有关详细信息,请参考使用配置文件配置 Docker。
支持的 Windows 版本
极狐GitLab Runner 支持以下 Windows 版本,它们遵循支持 Windows 生命周期:
- Windows Server 2022 LTSC (21H2)
- Windows Server 2019 LTSC (1809)
对于未来的 Windows 服务器版本,我们拥有未来版本支持政策。
您只可以基于与运行 Docker Daemon 相同的 OS 版本运行容器。
例如,可以使用以下 Windows Server
Core
镜像:
mcr.microsoft.com/windows/servercore:ltsc2022
mcr.microsoft.com/windows/servercore:ltsc2022-amd64
mcr.microsoft.com/windows/servercore:1809
mcr.microsoft.com/windows/servercore:1809-amd64
mcr.microsoft.com/windows/servercore:ltsc2019
支持的 Docker 版本
运行极狐GitLab Runner 的 Windows 服务器必须运行近期版本的 Docker, 因为 Runner 使用 Docker 探测运行的 Windows 服务器的版本。
不与极狐GitLab Runner 一起工作的 Docker 的一个已知版本是 Docker 17.06
,
因为 Docker 没有识别出 Windows 服务器的版本,导致以下错误:
unsupported Windows Version: Windows Server Datacenter
配置 Windows Docker 执行器
以下是配置简单 Docker 执行器运行 Windows 的例子。
[[runners]]
name = "windows-docker-2019"
url = "https://jihulab.com/"
token = "xxxxxxx"
executor = "docker-windows"
[runners.docker]
image = "mcr.microsoft.com/windows/servercore:1809_amd64"
volumes = ["c:\\cache"]
其他 Docker 执行器的配置选项,请参见高级配置部分。
Services
在极狐GitLab Runner 12.9 及更高版本中,您可以为每个作业开启网络从而使用 Services。
原生 Step Runner 的集成
- 自极狐GitLab 17.6.0 引入,并使用功能开关
FF_USE_NATIVE_STEPS
,该开关默认禁用。
Docker 执行器支持通过使用 step-runner
提供的 gRPC
API 来原生运行 CI/CD 步骤。
如要开启此执行模式,您必须使用 run
关键字指定 CI/CD 作业,而不是使用传统的 script
关键字。此外,您必须启用 FF_USE_NATIVE_STEPS
功能开关。您可以在作业或流水线级别启用此功能开关。
step job:
stage: test
variables:
FF_USE_NATIVE_STEPS: true
image:
name: registry.gitlab.com/gitlab-org/step-runner:v0
run:
- name: step1
script: pwd
- name: step2
script: env
- name: step3
script: ls -Rlah --ignore .git ../
已知问题
- 构建镜像必须在
$PATH
包含step-runner
二进制文件。要实现这一点,您可以:- 创建您自己的自定义构建镜像并在其中包含
step-runner
二进制文件。 -
使用
registry.gitlab.com/gitlab-org/step-runner:v0
镜像,如果它包含运行作业所需的依赖项。这是一个临时的解决方法。在将来,runner 会将
step-runner
二进制文件注入任何构建镜像中。
- 创建您自己的自定义构建镜像并在其中包含
- 运行一个步骤,该步骤运行 Docker 容器必须符合传统
scripts
的相同配置参数和约束。例如,您必须使用 Docker-in-Docker。 - 此执行模式目前还不不支持
Github Actions
。