Docker 构建故障排除
错误:docker: Cannot connect to the Docker daemon at tcp://docker:2375
当您使用 Docker-in-Docker v19.03 或更高版本时,此错误很常见:
docker: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?此错误发生是因为 Docker 自动启用了 TLS。
- 如果是您第一次设置,请参阅 使用 Docker 镜像的 Docker 执行器。
- 如果您是从 v18.09 或更早版本升级,请参阅 升级指南。
当尝试在 Kubernetes 执行器 中访问 Docker-in-Docker 服务时,如果该服务尚未完全启动,也可能发生此错误。更详细的解释,请参阅 issue 27215。
Docker no such host 错误
您可能会收到以下错误:
docker: error during connect: Post https://docker:2376/v1.40/containers/create: dial tcp: lookup docker on x.x.x.x:53: no such host。
当服务的镜像名称 包含注册表主机名 时,可能会出现此问题。例如:
default:
image: docker:24.0.5
services:
- registry.hub.docker.com/library/docker:24.0.5-dind服务的 主机名派生自完整的镜像名称。
但是,期望的是较短的服务主机名 docker。
为了允许服务解析和访问,为服务名称 docker 添加一个明确的别名:
default:
image: docker:24.0.5
services:
- name: registry.hub.docker.com/library/docker:24.0.5-dind
alias: docker错误:Cannot connect to the Docker daemon at unix:///var/run/docker.sock
当尝试运行 docker 命令访问 dind 服务时,您可能会收到以下错误:
$ docker ps
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?确保您的作业已定义了这些环境变量:
DOCKER_HOSTDOCKER_TLS_CERTDIR(可选)DOCKER_TLS_VERIFY(可选)
您可能还想更新提供 Docker 客户端的镜像。例如,docker/compose 镜像已过时,应该替换为 docker。
如 runner issue 30944 中所述,如果您的作业之前依赖于已弃用的
Docker --link 参数派生的环境变量,
例如 DOCKER_PORT_2375_TCP,则可能发生此错误。如果出现以下情况,您的作业将因此错误而失败:
- 您的 CI/CD 镜像依赖于旧变量,例如
DOCKER_PORT_2375_TCP。 - runner 功能标志
FF_NETWORK_PER_BUILD设置为true。 DOCKER_HOST未明确设置。
错误:unauthorized: incorrect username or password
当您使用已弃用的变量 CI_BUILD_TOKEN 时,会出现此错误:
Error response from daemon: Get "https://registry-1.docker.io/v2/": unauthorized: incorrect username or password为防止用户收到此错误,您应该:
- 使用 CI_JOB_TOKEN 替代。
- 从
gitlab-ci-token/CI_BUILD_TOKEN更改为$CI_REGISTRY_USER/$CI_REGISTRY_PASSWORD。
连接错误:no such host
当 dind 服务启动失败时,会出现此错误:
error during connect: Post "https://docker:2376/v1.24/auth": dial tcp: lookup docker on 127.0.0.11:53: no such host检查作业日志中是否出现 mount: permission denied (are you root?)。
例如:
Service container logs:
2023-08-01T16:04:09.541703572Z Certificate request self-signature ok
2023-08-01T16:04:09.541770852Z subject=CN = docker:dind server
2023-08-01T16:04:09.556183222Z /certs/server/cert.pem: OK
2023-08-01T16:04:10.641128729Z Certificate request self-signature ok
2023-08-01T16:04:10.641173149Z subject=CN = docker:dind client
2023-08-01T16:04:10.656089908Z /certs/client/cert.pem: OK
2023-08-01T16:04:10.659571093Z ip: can't find device 'ip_tables'
2023-08-01T16:04:10.660872131Z modprobe: can't change directory to '/lib/modules': No such file or directory
2023-08-01T16:04:10.664620455Z mount: permission denied (are you root?)
2023-08-01T16:04:10.664692175Z Could not mount /sys/kernel/security.
2023-08-01T16:04:10.664703615Z AppArmor detection and --privileged mode might break.
2023-08-01T16:04:10.665952353Z mount: permission denied (are you root?)这表明 GitLab Runner 没有权限启动 dind 服务:
- 检查
config.toml中是否设置了privileged = true。 - 确保 CI 作业有正确的 Runner 标签来使用这些 特权运行器。
错误:cgroups: cgroup mountpoint does not exist: unknown
Docker Engine 20.10 引入了一个已知的兼容性问题。
当主机使用 Docker Engine 20.10 或更高版本时,版本低于 20.10 的 docker:dind 服务
无法按预期工作。
虽然服务本身可以正常启动,但尝试构建容器镜像会导致错误:
cgroups: cgroup mountpoint does not exist: unknown要解决此问题,将 docker:dind 容器更新到至少 20.10.x 版本,
例如 docker:24.0.5-dind。
相反的配置(docker:24.0.5-dind 服务和主机上版本为
19.06.x 或更早的 Docker Engine)可以正常工作。最佳策略是您应该
经常测试并将作业环境版本更新到最新版本。这会带来新功能、改进的安全性,并且
对于这个特定情况,使运行器主机上的底层 Docker Engine 升级对作业透明。
错误:failed to verify certificate: x509: certificate signed by unknown authority
当在 Docker-in-Docker 环境中执行 docker build 或 docker pull 等 Docker 命令时,如果使用自定义或私有证书(例如 Zscaler 证书),可能会出现此错误:
error pulling image configuration: download failed after attempts=6: tls: failed to verify certificate: x509: certificate signed by unknown authority此错误发生是因为 Docker-in-Docker 环境中的 Docker 命令 使用两个独立的容器:
- 构建容器 运行 Docker 客户端 (
/usr/bin/docker) 并执行您的作业脚本命令。 - 服务容器(通常命名为
svc)运行处理大多数 Docker 命令的 Docker 守护进程。
当您的组织使用自定义证书时,两个容器都需要这些证书。 如果两个容器中没有正确的证书配置,连接到外部 注册表或服务的 Docker 操作将因证书错误而失败。
要解决此问题:
-
将您的根证书存储为名为
CA_CERTIFICATE的 CI/CD 变量。 证书应采用以下格式:-----BEGIN CERTIFICATE----- (certificate content) -----END CERTIFICATE----- -
配置您的管道在启动 Docker 守护进程之前,在服务容器中安装证书。例如:
image_build: stage: build image: name: docker:19.03 variables: DOCKER_HOST: tcp://localhost:2375 DOCKER_TLS_CERTDIR: "" CA_CERTIFICATE: "$CA_CERTIFICATE" services: - name: docker:19.03-dind command: - /bin/sh - -c - | echo "$CA_CERTIFICATE" > /usr/local/share/ca-certificates/custom-ca.crt && \ update-ca-certificates && \ dockerd-entrypoint.sh || exit script: - docker info - docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD $DOCKER_REGISTRY - docker build -t "${DOCKER_REGISTRY}/my-app:${CI_COMMIT_REF_NAME}" . - docker push "${DOCKER_REGISTRY}/my-app:${CI_COMMIT_REF_NAME}"