配置 Docker-in-Docker
Docker-in-Docker (dind)
means:
- 你应该注册一个
Docker executor
或Kubernetes executor
- 执行器(executor)使用 docker 镜像运行你的 CI/CD jobs
参考 Docker-in-Docker with TLS disabled in the Docker executor
身份认证
shell
docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
CI_REGISTRY_USER
、CI_REGISTRY_PASSWORD
和 CI_REGISTRY
都是 CI/CD 变量
参考:Authenticate with the Container Registry
Gitlab Runner 配置
[root@localhost test]# cat /etc/gitlab-runner/config.toml
[[runners]]
....
[runners.docker]
tls_verify = false
privileged = true
image = "docker:20.10.16"
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache"]
shm_size = 0
extra_hosts = ["registry.gitlab.example.com:your-gitlab-instance-host"]
构建并推送镜像到镜像库
[root@localhost opt]# cat .gitlab-ci.yml
stages:
- build
build-image:
stage: build
image: docker:20.10.16
services:
- name: docker:20.10.16-dind
command: ["--insecure-registry", "registry.gitlab.example.com"]
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
before_script:
- docker info
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build --pull -t $IMAGE_TAG .
- docker push $IMAGE_TAG
使用镜像库的镜像
[root@localhost opt]# cat .gitlab-ci.yml
stages:
- test
# before_script: docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
format:
stage: test
image: registry.gitlab.example.com/group/project:tag
variables:
CGO_ENABLED: 1
script:
- go fmt $(go list ./... | grep -v /vendor/)
- go vet $(go list ./... | grep -v /vendor/)
- go test -race $(go list ./... | grep -v /vendor/)
Troubleshooting
docker: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?
原因是 Docker daemon 启动失败,请检查 docker executor 是否配置正确,是否配置 CI/CD 变量 DOCKER_HOST
和 DOCKER_TLS_CERTDIR
参考 Docker-in-Docker with TLS disabled in the Docker executor
Error response from daemon: Get "https://registry.gitlab.example.com/v2/": dial tcp: lookup registry.gitlab.example.com on 192.168.40.190:53: no such host
原因是在 job 执行中使用了 docker-in-docker(dind)
方式运行一个 Docker daemon
,这个 docker daemon
没有使用宿主机的 /etc/hosts
文件,而是使用了默认的 DNS
服务器来解析所需的域名。因此,当尝试登陆registry.gitlab.example.com
时,DNS
无法解析这个名字,导致了错误
解决方法:为 Docker runner
添加额外的 hosts
映射
[[runners]]
....
[runners.docker]
....
extra_hosts = ["registry.gitlab.example.com:your-gitlab-instance-host"]
Error response from daemon: Get "https://registry.gitlab.example.com/v2/": x509: certificate is not valid for any names, but wanted to match registry.gitlab.example.com
原因是 Docker daemon
无法验证镜像仓库自签的 SSL 证书
解决方法:把这个镜像仓库添加到 dind service
的 insecure-registries
列表中
通过挂载配置文件的方式
[root@localhost opt]# cat /opt/daemon.json
{
"insecure-registries": ["registry.gitlab.example.com"]
}
[root@localhost opt]# cat /etc/gitlab-runner/config.toml
[[runners]]
....
[runners.docker]
....
volumes = ["/opt/daemon.json:/etc/docker/daemon.json:ro"]
通过 GitLab Runner
配置的方式
[[runners]]
...
executor = "docker"
[runners.docker]
...
privileged = true
[[runners.docker.services]]
name = "docker:20.10.16-dind"
command = ["--insecure-registry", "registry.gitlab.example.com"]
通过 CLI flag
的方式
[root@localhost opt]# cat .gitlab-ci.yml
build-image:
stage: build
image: docker:20.10.16
services:
- name: docker:20.10.16-dind
command: ["--insecure-registry", "registry.gitlab.example.com"]
补充:在 CLI 中使用容器镜像库
shell
# 登录
docker login registry.gitlab.example.com
# 构建镜像
docker build -t registry.gitlab.example.com/group/project .
# 推送镜像
docker push registry.gitlab.example.com/group/project
参考文档
Build and push container images to the Container Registry
Use Docker to build Docker images