2017-01-10 8 views
13

При использовании GitLab CI, а также gitlab-ci-multi-runner, я не могу получить контейнеры Docker с внутренним запуском, чтобы выставить свои порты на «хост», который является Изображение Docker, в котором работает сборка.Gitlab CI runner не способен выставлять порты вложенных контейнеров 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 [email protected]{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, но на самом деле он не отображается. Он отлично работает на моей локальной машине - есть ли какое-то специальное обходное решение/tweak Мне нужно сделать эту работу внутри a Докер-контейнер, работающий на GitLab?

+0

на вашей локальной машине, на которой находится адрес хоста .. и что такое os на localmachine –

ответ

5

Offical gitab-ci on gitlab.com documentation относится к example of PostgreSQL

Its working CI не пытается подключиться к локальному, а к service name

services ключевого слово определяет только другую Docker изображение, которое запускается во время сборки и связан с изображением докера, которое определяет ключевое слово изображения. Это позволяет получить доступ к служебному изображению во время сборки.

Сервисный контейнер для MySQL будет доступен под именем хоста mysql.
Итак, для доступа к службе базы данных вам необходимо подключиться к узлу с именем mysql вместо сокета или localhost.

Вы можете проверить, если это применимо в вашем случае, и попытайтесь получить доступ к вашим услугам приложения в app:9143 вместо localhost:9143.

+0

Я использую 'services' в моем' .gitlab-ci.yml' для других вещей, таких как 'docker: dind '. Причина, по которой я хочу использовать 'docker-compose' для фазы тестирования, так это то, что оркестровку моего MySQL, приложения и других связанных изображений (в тестовой среде) не нужно дублировать в' docker-compose .yml' и '.gitlab-ci.yml'.У меня уже есть рабочий файл Compose, который я потратил некоторое время на совершенствование - и это работает на машинах разработчика (тогда как '.gitlab-ci.yml' бесполезно), поэтому я действительно хотел бы использовать его, если это возможно. –

+0

@CraigOtis Я согласен, но, просто для тестирования, вы могли бы проверить, работает ли использование имени службы лучше? – VonC

+0

Да, я абсолютно проверю и вернусь к вам. –

1

Обычно докер-машина не запускается на локальном хосте, а на хост-докере с другим IP-адресом. Попробуйте использовать docker-machine ip, чтобы получить IP-адрес вашего док-станции.

+0

Проблема не в том, что я определяю имя хоста, на котором он запущен, - это то, что он работает на 'localhost' с помощью Docker Compose или обычного Docker с' -p '. ..: ... "', или я настраиваю образ приложения для запуска в качестве службы: 'в конфигурации GitLab, когда он фактически запущен на GitLab CI, образ приложения недоступен - хотя он отлично работает мой локальный компьютер, и, кажется, начинает нормально (и остается работать) в соответствии с журналами приложений. –

+0

Возможно, я не буду следовать за вами (никогда не использовал GitLab CI), но я просто говорю, что, поскольку любой клиент-докер может быть настроен для работы с виртуальной машиной или любым другим удаленным докере-хостом (docker-machine env используется для установки DOCKER_HOST), возможно, что клиент Docker GitLab настроен на запуск с другого хоста, а не с localhost, и в этом случае контейнер создается и запускается, но на другом хосте с другим ip (и не будет доступен на localhost, которого вы ждете). Итак, просто интересно, пытались ли вы проверить это. –

+0

Спасибо Yoav, мой вопрос обновлен более простым примером. –

1

Ваш docker-compose.yml выглядит нормально.

Но я думаю, что есть ошибка в маршрутизации вашего IP-порта или порта. Как я могу видеть из общей информации ваше приложение работает на порт на ф 0.0.0.0 в 0.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 предложить:

Услуг ключевое слово определяет только другой Docker изображение, которое запускается во время сборки и связан с изображение докера, которое задает ключевое слово изображения. Это позволяет получить доступ к служебному изображению во время сборки.

служба контейнер для MySQL будет доступен под имя хостаmysql. Итак, для доступа к службе базы данных вам необходимо подключиться к узлу с именем mysql вместо сокета или localhost.

0

При использовании docker:dind создается контейнер, и в нем устанавливаются контейнеры-контейнеры для докеров. Он предоставляет порты в localhost в контейнере docker:dind. Вы не можете получить доступ к этому как localhost из среды, в которой выполняется ваш код.

Имя хоста docker - это установка для ссылки на этот контейнер docker:dind. Вы можете проверить, используя cat /etc/hosts.

Вместо ссылки localhost:9143 вы должны использовать docker:9143.