GitLab CI 使用 Docker in Docker 无法访问 services 的坑
2019 12 26 02:12 PM 562次查看
.gitlab-ci.yml
配置时,发现一个域名无法解析的问题,部分配置如下:variables:
MYSQL_DATABASE: test
MYSQL_ROOT_PASSWORD: test
test:
stage: test
services:
- mysql:5.7
- redis:4
script:
- apk update && apk add mysql-client
- mysql -h mysql -u root -ptest < init.sql
- docker build -t test .
- docker run -t test pytest tests
在执行
mysql -h mysql -u root -ptest < init.sql
的时候,代码顺利地通过了;但在执行 docker run -t test pytest tests
的时候,却会报解析不了 mysql
的异常。以我所知,Docker in Docker(dind) 实际上是调用宿主机的 Docker 进程,因此我尝试分析了一下原因:
假设宿主机叫
ci
,在执行 test
job 时,它会先启动 mysql
和 redis
这两个服务。这两个服务是运行在容器里的,ci
知道它们的 IP,但并不修改自己的域名解析。接着
ci
再启动一个容器(假设叫 container1
),加载 dind 镜像,向 /etc/hosts
注入 mysql
和 redis
这两个域名的 IP,然后执行 script
里的代码。因此,container1
是能解析 mysql
和 redis
这两个域名的。然后
container1
在执行 docker run -t test pytest tests
的时候,实际上是调用 ci
的 Docker 来启动一个新容器(假设叫 container2
)。然而 ci
并不会向 container2
注入这个两域名,container2
也无法通过桥接的网络来解析它们,于是就报错了。虽然我不知道 GitLab CI 是否有标准的解决方案,但至少我手动注入域名是可以解决的:
script:
- apk update && apk add mysql-client
- mysql -h mysql -u root -ptest < init.sql
- mysql=`grep mysql /etc/hosts | awk '{print $1}'`
- redis=`grep redis /etc/hosts | awk '{print $1}'`
- docker build -t test .
- docker run --add-host mysql:$mysql --add-host redis:$redis -t test pytest tests
0条评论 你不来一发么↓