Help us learn about your current experience with the documentation. Take the survey.

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。

当尝试在 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_HOST
  • DOCKER_TLS_CERTDIR(可选)
  • DOCKER_TLS_VERIFY(可选)

您可能还想更新提供 Docker 客户端的镜像。例如,docker/compose 镜像已过时,应该替换为 docker

runner issue 30944 中所述,如果您的作业之前依赖于已弃用的 Docker --link 参数派生的环境变量, 例如 DOCKER_PORT_2375_TCP,则可能发生此错误。如果出现以下情况,您的作业将因此错误而失败:

错误: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 服务:

  1. 检查 config.toml 中是否设置了 privileged = true
  2. 确保 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 builddocker 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 操作将因证书错误而失败。

要解决此问题:

  1. 将您的根证书存储为名为 CA_CERTIFICATECI/CD 变量。 证书应采用以下格式:

    -----BEGIN CERTIFICATE-----
    (certificate content)
    -----END CERTIFICATE-----
  2. 配置您的管道在启动 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}"