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 后:
- 在 Docker 网络里给 service 容器注册别名
docker - 设置
DOCKER_HOST=tcp://docker:2375(用 alias 值) - 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/hosts 写 registry 的解析。
但 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 的做法。