yml services entrypoint dind compose docker gitlab docker-compose gitlab-ci

services - gitlab runner docker



El corredor de Gitlab CI no puede exponer los puertos de los contenedores Docker anidados (4)

Al usar la docker:dind cree que se crea un contenedor y los contenedores de composición de la ventana acoplable se configuran dentro de él. Expone los puertos a localhost dentro de la docker:dind container. No puede acceder a esto como localhost desde el entorno en el que se ejecuta su código.

Se ha configurado un nombre de host de la docker para que haga referencia a esta docker:dind contenedor de docker:dind . Puede verificar usando cat /etc/hosts .

En lugar de hacer referencia a localhost:9143 , debe utilizar la docker:9143 .

Al usar GitLab CI, así como el gitlab-ci-multi-runner , no puedo hacer que los contenedores de Docker iniciados internamente expongan sus puertos al "host", que es la imagen de Docker en la que se está ejecutando la compilación.

Mi archivo .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

Mi orden:

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

La salida:

$ 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

¿Qué estoy haciendo mal aquí?

La pregunta original sigue: el ejemplo anterior es más corto y fácil de probar.

Tengo una imagen de aplicación que escucha en el puerto 9143 . Su inicio y configuración se gestionan a través de docker-compose.yml , y funciona muy bien en mi máquina local con docker-compose up . Puedo acceder a localhost:9143 sin problemas.

Sin embargo, cuando se ejecuta en GitLab CI (la versión gitlab.com ) a través de un corredor compartido, el puerto no parece estar expuesto.

La parte relevante de mi .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

La salida es:

$ 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

El contenido de mi 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

Parece que mi contenedor de aplicaciones está escuchando en 9143 , y está expuesto correctamente al corredor de GitLab compartido, pero no parece estar realmente expuesto. Funciona bien en mi máquina local. ¿Hay alguna solución / ajuste especial que necesito para que esto funcione dentro de un contenedor Docker que se ejecuta en GitLab?


La documentación oficial de gitab-ci en gitlab.com se refiere al ejemplo de PostgreSQL

Su CI de trabajo no intenta conectarse a localhost, sino al nombre del servicio

La palabra clave de services define solo otra imagen de ventana acoplable que se ejecuta durante su compilación y está vinculada a la imagen de ventana acoplable que define la palabra clave de imagen. Esto le permite acceder a la imagen de servicio durante el tiempo de construcción.

El contenedor de servicios para MySQL será accesible bajo el nombre de host mysql .
Entonces, para acceder a su servicio de base de datos, debe conectarse al host llamado mysql lugar de a un socket o localhost .

Puede verificar si esto se aplica en su caso e intentar acceder a su servicio de app:9143 en la app:9143 lugar de localhost:9143 .


Por lo general, una máquina acoplable no se ejecuta en localhost, sino en un host acoplador con alguna otra dirección IP. Trate de usar docker-machine ip para obtener su ip de host docker.


Tu docker-compose.yml parece estar bien.

Pero creo que hay un error en tu ip o enrutamiento de puertos. Como puedo ver en su información compartida, su aplicación se está ejecutando en el puerto 9143 en ip 0.0.0.0 como 0.0.0.0:9143 .

y lo está accediendo como localhost:9143 , que puede interpretarse como 127.0.0.1:9143 .

Según 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).

¿Puedes intentar ejecutar tu aplicación en 127.0.0.1:9143 luego compartir el resultado?

ACTUALIZAR

o puede usar el servicio para ejecutarlo por nombre de servicio como la documentación sugiere:

La palabra clave de servicios define solo otra imagen de ventana acoplable que se ejecuta durante su compilación y está vinculada a la imagen de ventana acoplable que define la palabra clave de imagen. Esto le permite acceder a la imagen de servicio durante el tiempo de construcción.

El contenedor de servicios para MySQL será accesible bajo el nombre de host mysql . Entonces, para acceder a su servicio de base de datos, debe conectarse al host llamado mysql en lugar de a un socket o localhost .