docker - Gitlab CI runner 无法暴露嵌套 Docker 容器的端口

标签 docker gitlab docker-compose gitlab-ci

当使用 GitLab CI 以及 gitlab-ci-multi-runner 时,我无法让内部启动的 Docker 容器将其端口暴露给“主机”,即运行构建的 Docker 镜像。

我的 .gitlab-ci.yml 文件:

test:
  image: docker
  stage: test
  services:
    - docker:dind
  script:
    - APP_CONTAINER_ID=`docker run -d --privileged -p "9143:9143" appropriate/nc nc -l 9143`
    - netstat -a
    - docker exec $APP_CONTAINER_ID netstat -a
    - nc -v localhost 9143

我的命令:

gitlab-ci-multi-runner exec docker --docker-privileged test

输出:

$ netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 runner--project-1-concurrent-0:54664 docker:2375             TIME_WAIT
tcp        0      0 runner--project-1-concurrent-0:54666 docker:2375             TIME_WAIT
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node Path

$ docker exec $APP_CONTAINER_ID netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:9143            0.0.0.0:*               LISTEN
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node Path

$ nc -v localhost 9143
ERROR: Build failed: exit code 1
FATAL: exit code 1

我在这里做错了什么?

以下是原始问题 - 上面是一个更短、更易于测试的示例

我有一个监听端口 9143 的应用程序镜像。它的启动和配置是通过 docker-compose.yml 管理的,并且在我的本地机器上使用 docker-compose up 运行良好 - 我可以访问 localhost:9143 没有问题。

但是,当通过共享运行器在 GitLab CI(gitlab.com 版本)上运行时,端口似乎没有暴露。

我的.gitlab-ci.yml的相关部分:

test:
  image: craigotis/buildtools:v1
  stage: test
  script:
    - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN registry.gitlab.com/craigotis/myapp
    - docker-compose up -d
    - sleep 60 # a temporary hack to get the logs
    - docker-compose logs
    - docker-machine env
    - docker-compose port app 9143
    - netstat -a
    - docker-compose ps
    - /usr/local/bin/wait-for-it.sh -h localhost -p 9143 -t 60
    - cd mocha
    - npm i
    - npm test
    - docker-compose down

输出是:

$ docker-compose logs
...
app_1  | [Thread-1] INFO spark.webserver.SparkServer - == Spark has ignited ...
app_1  | [Thread-1] INFO spark.webserver.SparkServer - >> Listening on 0.0.0.0:9143
app_1  | [Thread-1] INFO org.eclipse.jetty.server.Server - jetty-9.0.z-SNAPSHOT
app_1  | [Thread-1] INFO org.eclipse.jetty.server.ServerConnector - Started ServerConnector@6919dc5{HTTP/1.1}{0.0.0.0:9143}
...

$ docker-compose port app 9143
0.0.0.0:9143

$ netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 runner-e11ae361-project-1925166-concurrent-0:53646 docker:2375             TIME_WAIT   
tcp        0      0 runner-e11ae361-project-1925166-concurrent-0:53644 docker:2375             TIME_WAIT   
tcp        0      0 runner-e11ae361-project-1925166-concurrent-0:53642 docker:2375             TIME_WAIT   
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags       Type       State         I-Node Path

$ docker-compose ps
stty: standard input: Not a tty
    Name                  Command               State                Ports               
----------------------------------------------------------------------------------------
my_app_1   wait-for-it.sh mysql_serve ...   Up      8080/tcp, 0.0.0.0:9143->9143/tcp 
mysql_server   docker-entrypoint.sh --cha ...   Up      3306/tcp     

$ /usr/local/bin/wait-for-it.sh -h localhost -p 9143 -t 60
wait-for-it.sh: waiting 60 seconds for localhost:9143
wait-for-it.sh: timeout occurred after waiting 60 seconds for localhost:9143

我的docker-compose.yml的内容:

version: '2'

networks:
    app_net:
        driver: bridge

services:
    app:
        image: registry.gitlab.com/craigotis/myapp:latest
        depends_on:
        - "db"
        networks:
        - app_net
        command: wait-for-it.sh mysql_server:3306 -t 60 -- java -jar /opt/app*.jar
        ports:
        - "9143:9143"

    db:
        image: mysql:latest
        networks:
        - app_net
        container_name: mysql_server
        environment:
        - MYSQL_ALLOW_EMPTY_PASSWORD=true

似乎好像我的应用程序容器正在监听 9143,并且它正确地暴露给了共享的 GitLab 运行器,但它似乎并没有真正暴露。它在我的本地机器上运行良好 - 是否需要一些特殊的解决方法/调整才能使这项工作在 GitLab 上运行的 Docker 容器中工作?

最佳答案

当使用 docker:dind 时,会创建一个容器,并在其中设置您的 docker-compose 容器。它将端口暴露给 docker:dind 容器中的 localhost。您无法从执行代码的环境中以 localhost 的身份访问它。

docker 的主机名已设置为您引用此 docker:dind 容器。您可以使用 cat/etc/hosts 进行检查。

您应该使用 docker:9143,而不是引用 localhost:9143

关于docker - Gitlab CI runner 无法暴露嵌套 Docker 容器的端口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41559660/

相关文章:

r - 用于工具包文档的 docker : `docker export` not including all layers?

asp.net-core - ASP.NET Core w/Tools for Docker EnvironmentName for Stage

android/busybox/termux 测试环境

linux - 从 GitLab 找到最近下载的 repo

docker - 如何使用Docker-Compose文件运行Phpmyadmin,Mysql和Apache Tomcat?

java - docker中无法连接springboot到mysql

Powershell使用正确的子目录路径从gitlab下载文件

angular - 本地 Angular 构建成功,但 Gitlab 运行器 Angular 构建失败

node.js - Docker-compose up 以代码 1 退出,但 docker-compose build 成功

docker - 没有手动命令的Docker服务未加入docker-compose中指定的网络