web-dev-qa-db-ja.com

Gitlab CIランナーがネストされたDockerコンテナーのポートを公開できない

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

seemsアプリケーションコンテナが9143をリッスンしているようで、共有GitLabランナーに適切に公開されていますが、実際には公開されていないようです。それは私のローカルマシンでうまく動作します-この作業を行う必要がある特別な回避策/調整がありますかinsideGitLabで実行されているDockerコンテナですか?

20
Craig Otis

公式の gitlab.comドキュメントのgitab-ciPostgreSQLの例 を指します

動作中のCI はlocalhostに接続しようとせず、むしろ サービス名

servicesキーワードは、ビルド中に実行され、imageキーワードが定義するdockerイメージにリンクされる別のdockerイメージのみを定義します。これにより、ビルド時にサービスイメージにアクセスできます。

MySQLのサービスコンテナには、ホスト名mysqlでアクセスできます。
したがって、データベースサービスにアクセスするには、ソケットまたはmysqlではなくlocalhostという名前のホストに接続する必要があります。

これがあなたのケースに当てはまるかどうかを確認し、app:9143 の代わりに localhost:9143

6
VonC

docker:dindを使用すると、コンテナが作成され、Docker構成コンテナがその中にセットアップされます。 docker:dindコンテナー内のlocalhostにポートを公開します。コードが実行されている環境からlocalhostとしてこれにアクセスすることはできません。

このdocker:dindコンテナを参照するために、dockerというホスト名が設定されています。 cat /etc/hostsを使用して確認できます。

localhost:9143を参照する代わりに、docker:9143を使用する必要があります。

6
Jason Prawn

あなたのdocker-compose.ymlは大丈夫のようです。

しかし、IPまたはポートのルーティングにエラーがあると思います。共有情報からわかるように、アプリはport914 on ip .0.0. as0.0で実行されています.0.0:9143

localhost:9143としてアクセスし、127.0.0.1:9143として解釈できます。

this によると。

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 [〜#〜]

または、サービスを使用して、サービス名で documentation のように実行できます:

servicesキーワードは、ビルド中に実行され、imageキーワードが定義するdockerイメージにリンクされる別のdockerイメージのみを定義します。これにより、ビルド時にサービスイメージにアクセスできます。

MySQLのサービスコンテナは、hostnamemysqlでアクセスできます。したがって、データベースサービスにアクセスするには、ソケットまたはlocalhostではなく、mysqlという名前のホストに接続する必要があります。

2
Rohit Dhiman

通常、Dockerマシンはlocalhostでは実行されませんが、他のIPアドレスを持つdockerホストで実行されます。 docker-machine ipを使用して、DockerホストIPを取得してください。

1
Yoav Aharoni