Использование 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" — название тега это название системы с полной версией, список тегов можно посмотреть на специальной странице в вики
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 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, херить сервера неплохо бы уметь перед завтраком, как вынос мусора ;)

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