Gitlab ci/cd .gitlab-ci.yml问题集

Gitlab ci/cd .gitlab-ci.yml问题集

1、以下是gitlab-ci中的一部分,能够正常build,当把这一行 - name: docker:27-dind 修改为 - name: registry:5000/docker:27-dind后,镜像可以正常的PULL,但是当运行到这一行时: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY 日志显示https登录失败,为什么改了这一行配置(理论会跳过https登录,因为配置了insecure),会影响 docker login的行为呢?

build:
stage: build
tags: [dev-dind]
image: registry:5000/docker:27
services:
 name: docker:27-dind
entrypoint: ["sh", "-c", "echo '172.17.23.110 registry' >> /etc/hosts && exec dockerd-entrypoint.sh $@", "--"]
command:
 --insecure-registry
 172.17.23.110:5050
 --insecure-registry
 registry:5000
 --bip=10.42.0.1/16
 --registry-mirror
 https://docker.m.daocloud.io
 --registry-mirror
 https://registry.docker-cn.com
 --registry-mirror
 https://mirror.ccs.tencentyun.com
variables:
DOCKER_BUILDKIT: "0"
DOCKER_TLS_CERTDIR: ""
script:
 echo "DOCKER_HOST=$DOCKER_HOST"
 echo "CI_REGISTRY=$CI_REGISTRY"
 docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
 docker build -t $IMAGE_TAG -t $IMAGE_LATEST .
 docker push $IMAGE_TAG
 docker push $IMAGE_LATEST
only:
 main 

原因分析:

docker:27-dind
  → Runner 检测到这是 DinD 镜像(匹配 docker:*dind 模式)
  → 自动设置 alias = docker
  → DOCKER_HOST=tcp://docker:2375 能解析到 DinD 容器
  → docker login 能连上 daemon → 拿到 insecure 列表 → HTTP 回退 ✅

registry:5000/docker:27-dind
  → 镜像名带了仓库前缀
  → Runner 的 DinD 检测模式可能没匹配上
  → 或匹配上了但推导出的网络别名不是 docker
  → DOCKER_HOST=tcp://docker:2375 里的 docker 解析不到 DinD 容器
  → docker login 连不上 daemon → 拿不到 insecure 列表 → 默认 HTTPS → 失败 ❌

验证:

services:
  - name: registry:5000/docker:27-dind
    alias: docker                              # ← 加这行
    entrypoint: ["sh", "-c", "echo '172.17.23.110 registry' >> /etc/hosts && exec dockerd-entrypoint.sh $@", "--"]
    command:
      - --insecure-registry
      - 172.17.23.110:5050
      ...

GitLab Runner 在启动 job 时强制设置 DOCKER_HOST,它的逻辑是:

1. 检测到 DinD 服务
2. 从服务镜像名推导出网络别名
   - docker:27-dind → 推导出 "docker"
   - registry:5000/docker:27-dind → 可能推导出别的
3. 设置 DOCKER_HOST=tcp://<推导的别名>:2375
4. 这个值会覆盖 variables 里的同名变量

alias 的作用就是控制这个别名

services:
  - name: registry:5000/docker:27-dind
    alias: docker    # ← 告诉 Runner:这个服务的网络别名就叫 docker

Runner 看到 alias: docker 后:

  1. 在 Docker 网络里给 service 容器注册别名 docker
  2. 设置 DOCKER_HOST=tcp://docker:2375(用 alias 值)
  3. job 容器里 docker 这个主机名就能解析到 DinD 容器

2、 runner config.toml中增加这个配置的用途是什么:extra_hosts = [“registry:172.17.23.110”]

extra_hosts 的作用

[runners.docker]
  extra_hosts = ["registry:172.17.23.110"]

等价于在 每个 job 容器和 service 容器/etc/hosts 里自动加一行:

172.17.23.110  registry

为什么需要它

在第一问的文件中 DinD entrypoint 里有这行:

entrypoint: ["sh", "-c", "echo '172.17.23.110 registry' >> /etc/hosts && exec dockerd-entrypoint.sh $@", "--"]

这个 entrypoint 是手动往 DinD 容器/etc/hostsregistry 的解析。

但 job 容器(docker:27)里没有这条记录。如果 job 容器里需要解析 registry(比如 Dockerfile 里 FROM registry:5000/xxx),就解析不了。

extra_hosts 让 Runner 在创建容器时自动写入 hosts 记录,不用手动 echo:

                 手动 echo(只管 DinD 容器)
                 ┌─────────────────────┐
                 │ DinD 容器            │
                 │ /etc/hosts:         │
                 │ 172.17.23.110 registry ✅
                 └─────────────────────┘

extra_hosts(job 容器和 service 容器都有)
                 ┌─────────────────────┐
                 │ Job 容器             │
                 │ /etc/hosts:         │
                 │ 172.17.23.110 registry ✅
                 ├─────────────────────┤
                 │ Service 容器         │
                 │ /etc/hosts:         │
                 │ 172.17.23.110 registry ✅
                 └─────────────────────┘

有了 extra_hosts 就可以去掉 entrypoint 覆盖

# 之前(需要手动 echo + 覆盖 entrypoint)
services:
  - name: registry:5000/docker:27-dind
    entrypoint: ["sh", "-c", "echo '172.17.23.110 registry' >> /etc/hosts && exec dockerd-entrypoint.sh $@", "--"]
    command: [...]

# 之后(extra_hosts 已在 config.toml 配好,不需要 echo 了)
services:
  - name: registry:5000/docker:27-dind
    alias: docker
    command: [...]   # 直接传给原始 dockerd-entrypoint.sh,不需要覆盖 entrypoint

extra_hosts 就是让 Runner 自动往所有容器里写 /etc/hosts 条目,替代你在 entrypoint 里手动 echo 的做法。