Docker + Jenkins + DinD + Selenium Grid

whirlwind

TDD infected, paranoid
Имеется дженкинс под докером. Например такой кампауз

Код:
version: "3"
services:

  selenium-hub:
    image: selenium/hub:3.141.59-zinc
    container_name: selenium-hub
    ports:
      - "4444:4444"

  chrome:
    image: selenium/node-chrome:3.141.59-zinc
    volumes:
      - /dev/shm:/dev/shm
    depends_on:
      - selenium-hub
    environment:
      - HUB_HOST=selenium-hub
      - HUB_PORT=4444

  firefox:
    image: selenium/node-firefox:3.141.59-zinc
    volumes:
      - /dev/shm:/dev/shm
    depends_on:
      - selenium-hub
    environment:
      - HUB_HOST=selenium-hub
      - HUB_PORT=4444

  jenkins-docker:
    image: docker:dind
    container_name: docker
    privileged: true
    environment:
      - DOCKER_TLS_CERTDIR=/certs
    volumes:
      - jenkins-docker-certs:/certs/client
      - jenkins-data:/var/jenkins_home

  jenkins:
    image: jenkinsci/blueocean
    privileged: true
    environment:
      - DOCKER_HOST=tcp://docker:2376
      - DOCKER_CERT_PATH=/certs/client
      - DOCKER_TLS_VERIFY=1
      - TZ=Europe/Moscow
      - JAVA_OPTS=-Xmx1024m -Xms256m -XX:MaxPermSize=256m
    volumes:
      - jenkins-docker-certs:/certs/client:ro
      - jenkins-data:/var/jenkins_home
    ports:
      - "8080:8080"
      - "50000:50000"
    user: "0"

networks:
  default:
    external:
      name: jenkins

volumes:
  jenkins-docker-certs:
    external: true
  jenkins-data:
    external: true
Требуется натравить задачу, запускаемую из jenkins-docker, на selenium-hub. Сейчас работает через задницу. Имена этой сетки в дочернем докере естесно не резолвятся. Но можно прописать IP хаба в Jenkinsfile вручную, предварительно посмотрев network после запуска. Или можно извратиться с sh getent. Или с EnvInject. В теории можно сюда же поднять dns и натравить на него jenkins-docker через agent args в Jenkinsfile. Но я подозреваю, что есть более правильный способ. Ну как бы естественным кажется типовой кейс: есть отдельно поднятый селениум грид с кучей нодов и вообще отдельно администрируемый, и отдельные jenkins таски для юзания кластера грида. Как по-нормальному подружить все это дело?
 

WMix

герр M:)ller
Партнер клуба
Если я правильно понимаю у тебя в докере докер, который разворачивает аппликацию, внутри этого докера конечно бегает webserver. Осталось этот порт заэкспозить из внутреннего докер чтоб снаружи (внутри первого докер) на него обращаться
 

whirlwind

TDD infected, paranoid
Не совсем про это.
Вот условная схема сетевых уровней:

1) Internet
2) Jenkins network (jenkins + docker + selenium hub + selenium nodes + proxy + стабы/фейки + прочие сервисы тестлабы)
3) сетка которая создается докером сверху

Все, что работает на уровне 2, резолвит все, что на уровнях 2 и 1. На уровне 3 резолвятся имена только только из 3 и 1. При необходимости обратиться к какому либо сервису с уровня 3 на уровень 2 возникает проблема разрешения имени сервиса. Маршрутизация 3->2 работает нормально. Но только по айпишкам. Я знаю как это решить - ценой отхода от декларативного Jenkinsfile, прописыванием в сеттинге мастера или добавлением dns сервера. Но кажется я делаю что то не так.
 

WMix

герр M:)ller
Партнер клуба
Мне кажется тебе имя знать нет необходимости, или оно известно заранее (если во 2м уровне несколько аппликаций внутри докера, имя генерится).
если всего одна аппликация, то достаточно заэкспозить 80 порт, просто замаппить и прописать хост если вебсервис только на него отвечает.
 

WMix

герр M:)ller
Партнер клуба
Аппликацию которую тестим jenkins грузит? Как он это делает? git pull, docker build или зачем там докер?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
что-то тут напутано
тут надо сделать два разных стека, и они отлично могут общаться через общую сетку
это ж вопрос в service locator, сторонний dns тут не особо поможет, проще ip захардкодить

мне только compose не нравится, он неполноценный
я с jenkins-docker не работал, можно ему прописать параметры run - байндить в стек или хотя бы в сеть?
 

whirlwind

TDD infected, paranoid
Аппликацию которую тестим jenkins грузит? Как он это делает? git pull, docker build или зачем там докер?
И то и другое. Докер там что бы создать окружение, нужное для сборки-тестирования. Ноды не универсальны, а контейнеры да. По этому собирается под докером. Дженкинс подцепляет докерфайл и собирает образ. Адрес хаба нужен во вложенном докере что бы сделать new RemoteWebDriver(hub_url, capabilities)

что-то тут напутано
тут надо сделать два разных стека, и они отлично могут общаться через общую сетку
это ж вопрос в service locator, сторонний dns тут не особо поможет, проще ip захардкодить

мне только compose не нравится, он неполноценный
я с jenkins-docker не работал, можно ему прописать параметры run - байндить в стек или хотя бы в сеть?
Этот кейс конкретно про интеграционные и приемочные тесты. Наверное к ним можно присобачить некий сервис локатор, но я так не делал.

Сейчас захардкожен список пропертей окружения на уровне дженкинса. Они пропихиваются в докер, а там их код тестировщика подцепляет. dns внутри докеровской сетки похоже тупо на shared hosts сделан. Как во вложенный докер сетку прокинуть, если это возможно, то я не знаю. Внутрь можно прокинуть айпишки через переменные окружения. И тут варианты. Либо в каждой джобе сетапить, либо извращаться скриптовать навроде getent ahost selenium-hub xxx | awk etc... Все это не выглядит нормальным. Вот я и спрашиваю, может есть получше варианты.

Я думал сделать универсальный compose на тестовую лабу. А для сборки/тестирования наделать джобов для дженкинса и все это в репоз. На любую тачку ставшь докер и одной командой подымаешь лабу. Ну и дальше работаешь без всякого гемора: хочешь из IDE в тестах коннектишься к хабу, хочешь при сборке тесты коннектятся. Конечно можно свой композ на каждый кейс, но это будет типа dll hell только в yaml формате. Склоняюсь все таки отказываться от декларативного формата дженкинса и делать скриптовые вставки.
 

WMix

герр M:)ller
Партнер клуба
Селениум он же тупо браузер, тебе просто в 80 порт постучать надо (представь что дженкинс развернут тупо на машину с докером, просто экспозишь порт и просто его мапишь)
Если сам дженкинс разворачивает приложение, то он и назначает хосты
 

whirlwind

TDD infected, paranoid
Мне надо не селениум в контейнер впустить, а из контейнера до хаба достучаться. По постоянному имени, а не переменной айпишке. И эта попаболь актуальна для любой комбинации сервиса тестлабы и контейнера из вложенного докера. Из контейнера апликуху наружу открыть это понятно что экспозом порта.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
И то и другое. Докер там что бы создать окружение, нужное для сборки-тестирования. Ноды не универсальны, а контейнеры да. По этому собирается под докером. Дженкинс подцепляет докерфайл и собирает образ. Адрес хаба нужен во вложенном докере что бы сделать new RemoteWebDriver(hub_url, capabilities)
Этот кейс конкретно про интеграционные и приемочные тесты.
это все понятно

Наверное к ним можно присобачить некий сервис локатор, но я так не делал.
он уже есть в compose, ты им и пользуешься, в compose он устроен на встроенном dns,
тебе надо или прописать сервис в твой service locator сети, которую создает jenkins, или использовать общий SL в обоих окружениях

dns внутри докеровской сетки похоже тупо на shared hosts сделан.
нет, можно много чего сделать, даже указать каждому контейнеру свой ip

Как во вложенный докер сетку прокинуть, если это возможно, то я не знаю.
обычно параметрами при создании контейнера https://docs.docker.com/engine/reference/run/#network-settings
`docker run --network=jenkins` - если сервис selenium-hub тоже в этой сети, контейнер его увидит

второй вариант - прописать существующий контейнер в сеть https://docs.docker.com/engine/reference/commandline/network_connect/
не похоже, что это твой случай

вопрос в том, можешь ли ты в jenkins задать параметры docker run при запуске котейнера

Внутрь можно прокинуть айпишки через переменные окружения.
не согласен, снаружи ты в NAT-сетку докера по ip не зайдешь
эта задача решается через доступ к сети

Либо в каждой джобе сетапить, либо извращаться скриптовать навроде getent ahost selenium-hub xxx | awk etc... Все это не выглядит нормальным. Вот я и спрашиваю, может есть получше варианты.

Я думал сделать универсальный compose на тестовую лабу. А для сборки/тестирования наделать джобов для дженкинса и все это в репоз. На любую тачку ставшь докер и одной командой подымаешь лабу. Ну и дальше работаешь без всякого гемора: хочешь из IDE в тестах коннектишься к хабу, хочешь при сборке тесты коннектятся. Конечно можно свой композ на каждый кейс, но это будет типа dll hell только в yaml формате. Склоняюсь все таки отказываться от декларативного формата дженкинса и делать скриптовые вставки.
тут я просто запутался, ничего такого делать не надо
 
Сверху