Пользователь
0,0
рейтинг
30 октября 2013 в 23:19

Разработка → Использование Docker-контейнеров как Jenkins-нод

Эта статья описывает использование контейнеров docker как отдельные ноды для системы непрерывной интеграции, в данном случае jenkins. Кому лень читать tl; dr
Для сборки нашего проекта в RPM и DEB пакеты мы используем Jenkins, на что выделена специальная машина.

Сначала мы собирали наш проект только для CentOS 6. Далее добавилась поддержка CentOS 5, и оказалось что зависимости от конкретных версий библиотек не дают работать тем же бинарникам под разными версиями CentOS, понадобилась сборка разных RPM. Это было решено добавлением в jenkins ноды с CentOS 5, которой служила виртуалка на VirtualBox. Потом добавилась поддержка Suse, а потом и Debian.

Количество оперативной памяти не резиновое, а использование виртуальных машин только для сборки это явный оверхед, и было решено переписать скрипты используя Docker.


Используя Jenkins для непрерывной интеграции можно подключить ноды с нужными операционками и назначить задачи на них, тут есть несколько вариантов:
  • Арендовать инстансы/компьютеры и использовать их как ноды
  • Использовать стандартную виртуализацию (гипервизор)
  • Контейнеры (lxc, jail etc)

Преимущества контейнеров перед виртуальными машинами очевидны в данном случае (оперативная память общая, динамически-меняющаяся, большое количество поднятых контейнеров не тормозит систему в отличии от виртуальных машин), а Docker добавляет к ним такие важные моменты как:

  • Для сборки проекта запускается собственно скрипт сборки, и больше ничего. Тогда как при использовании виртуальной машины будут запущены все системные процессы и демоны, что отъедает ресурсы хоста.
  • «Дешевое» создание большого количества независимых клонов машин — иногда для сборки проекта нужна изолированная среда для сборки.


Docker как нода в jenkins



Для jenkins-слейва нам нужны:
  1. Java
  2. Точка входа — ssh
  3. Инструменты для сборки


Точка входа нужна для запуска процесса в docker-е и сохранении файловой системы внутри сессии сборки (LXC использует процесс init, но нам вся система ни к чему). Так как jenkins-у все равно понадобится SSH для общения с нодой, этот демон и будет точкой входа.

Для сборки машины Docker предлагает использовать Dockerfile-файлы с инструкциями по сборке машины.

В этом репозитории: https://github.com/antigluk/docker-jenkins-slave сейчас доступны правила сборки для 
  • CentOS 5
  • CentOS 6
  • Suse 12
  • Debian 6


Пулл-реквесты с новыми системами, и исправлениями в скриптах приветствуются:)

Сборка и использование



Предполагается, что у вас установлен Docker и Jenkins

1) Установите в Jenkins Swarm Plugin (он позволяет слейвам добавляться в Jenkins автоматически используя API)
2)  $ git clone git@github.com:antigluk/docker-jenkins-slave.git; cd docker-jenkins-slave
3) Перейдите в папку с правилами для нужной системы
    $ cd centos6
4)  $ sudo bash build.sh


Когда соберется образ, вы сможете добавлять сколько угодно нод данного типа:

    sudo bash add_slave.sh SlaveName


После выполнения этой команды вы должны увидеть новую ноду на Jenkins-e.

Теперь, для использования новой ноды достаточно указать в тегах для сборки нужной задачи «docker-tagname" — название тега это название системы с полной версией, список тегов можно посмотреть на специальной странице в вики
Роман @Antigluk
карма
129,7
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (16)

  • 0
    Chroot позволит Вам запускать разные версии Centos на одном сервере.
    • 0
      Да, тоже вариант. Но chroot не позволит запустить какое угодно количество независимых нод, нужно будет копировать полностью файловую систему
    • 0
      Chroot завсегда проиграет Docker-у и по удобству использования, и по всем остальным параметрам.
      • +1
        не могли бы вы более детально ответить?
        • 0
          Например, в chroot нету контроля над происходящим внутри через cgroups
        • +1
          Прошу прощения, не увидел вашего ответа.

          * Чтобы пользоваться chroot нужно его сперва собрать, причем воспроизводимо.
          * Если свои чруты обновляем а не только держим, то приходится как-то отдельно заморачиваться с воспроизводимостью и их версионированием.
          * Если держать много чрутов, размер их будет дублироваться.
          * Если держать много чрутов, возникнет проблема их учитывать, а также сервисы, которые запускаются в них.
          * Для сервисов, которые работают в чруте нужно держать отдельную дополнительную о том как все работает, либо выдумывать (и поддерживать!) стандартизацию
          * Процессы в чрутах слушают те же самые порты, что и хост, т.е. теоретически возможна ситуация, когда процесс из чрута запустившись раньше системного сервиса откроет его порт и не даст ему запуститься, или будет мешать аналогичному процессу в другом чруте (например, если держать 2 апача в разных чрутах).
          * Если не ошибаюсь, /proc в чруте общий с хостом (либо его вообще нет), т.е. root из чрута может производить атаку по сервисам вне чрута — там, где /proc используется в чруте.
          * Наверное несколько субъективно, но всякий раз, когда я сталкивался с чрутами (некоторые системные сервисы в дистрах уже упакованы в чруты), это было сопряжено с каким-нибудь гемором — или конфиги туда криво копируются, или библиотеку хочется туда прокинуть, но хз как это сделать правильно или еще что-нибудь такое подобное, но довольно тупое.
          * Опять таки субъективно — создавать чруты мне хотелось раза полтора или меньше, а вот docker при случае буду использовать — как раз по вышеприведенным организационным причинам.

          Если подумать, можно еще что-нибудь придумать — это сходу за 5мин придумалось.

          Из плюсов чрута назову, что он работает вообще где угодно, т.е. ему не нужно x64, lxc и дополнительных пакетов.

  • 0
    А вы действительно решили выложить в публичный доступ SSH-ключи, или просто забыли их добавить в gitignore например?
    • 0
      Это тестовые ключи, они нигде не используются
  • 0
    Еще бы docker не поломался со вчерашним релизом.
    • 0
      А что с ним? Я вчера обновлялся, вроде как все работает
      • 0
        Я пытаюсь сделать docker run или docker build, и через несколько секунд вижу:

        Error build: The container failed to start due to timed out.
        


        Хотя на 0.6.4 этот же Dockerfile отрабатывал без проблем.
        • 0
          Не используйте 13.10, используйте 13.04. Думаю проблема у вас в этом.
          • +1
            Да это 13.10. Легко сказать, похерь сервер потому что не та версия. Ссылка на issue в репозитории и решение.
            • 0
              Сервера на 13.10, конечно, сурово держать. Не-LTS версии начиная с 13.04 поддерживаются в течение всего 9 месяцев после выхода (или в течение 3х месяцев после выхода следующей версии).

              13.10 превратится в тыкву уже к лету.
              • 0
                Да, на 100% согласен. Поэтому на нём только staging сервер, который в принципе не жалко, но и переделывать, все сначала не хочется, когда все и так хорошо работает.
            • +1
              Дык, конец 2013, херить сервера неплохо бы уметь перед завтраком, как вынос мусора ;)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.