Gitlab CI runner不能公开嵌套的Docker容器的端口

当使用GitLab CI以及gitlab-ci-multi-runner ,我无法获得内部启动的Docker容器,以将其端口暴露给“主机”,这是运行构build的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 

我在这里做错了什么?

原来的问题跟随 – 上面是一个更短,更容易testing的例子

我有一个应用程序的图像,监听端口9143 。 它的启动和configuration是通过docker-compose.ymlpipe理的,并且在我的本地机器上用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容器内部工作?

gitlab.com文档中的官方gitab-ci是指PostgreSQL的例子

它的工作CI不会尝试连接到本地主机,而是连接到服务名称

services关键字定义了另一个在构build期间运行的docker镜像,并链接到image关键字定义的docker镜像。 这允许您在构build期间访问服务映像。

MySQL的服务容器可以在主机名mysql下访问。
所以,为了访问你的数据库服务,你必须连接到名为mysql的主机,而不是socket或localhost

你可以检查这是否适用于你的情况,并尝试在app:9143而不是localhost:9143访问你的应用程序服务。

docker-compose.yml似乎没问题。

但我认为你的IP或端口路由有错误。 从我的共享信息中可以看到,您的应用程序正在0.0.0.0:9143的 ip 0.0.0.0上的端口 9143上运行。

并且您正在以localhost:9143身份访问它,可以将其解释为127.0.0.1:9143

据此。

 127.0.0.1 is the loopback address (also known as localhost). 0.0.0.0 is a non-routable meta-address used to designate an invalid, unknown, or non-applicable target (a 'no particular address' place holder). 

你可以尝试在127.0.0.1:9143上运行你的应用程序,然后分享结果。

UPDATE

或者您可以使用服务来按照服务名称运行它,如文档所示:

services关键字定义了另一个在构build期间运行的docker镜像,并链接到image关键字定义的docker镜像。 这允许您在构build期间访问服务映像。

MySQL的服务容器可以在主机名 mysql下访问。 所以,为了访问你的数据库服务,你必须连接到名为mysql的主机,而不是socket或localhost

docker机器通常不会在本地主机上运行,​​而是在具有其他IP地址的docker主机上运行。 尝试使用docker-machine ip来获得您的docker主机ip。