CI на базе Docker
28.01.2016 Хрусталев Юрий
Требования
● Аддитивность процесса
● Поддержка более 5 версий ОС
● Сборка .deb/.rpm пакетов
● Возможность добавлять новые билды
● Недорогая поддержки
● Работа с jenkins
● Более одного хоста под билдер
Требования +
● Декларация зависимостей
● Версионированность
● Использование в разработке
○ у нас люди не только под centos сидят
○ мы не флексибл, есть люди с osx
Пробуем VM
● Виртуализация на уровне хоста
● N VM под каждую систему
● Свой IP, ssh, довольно просто портить
● Быстрое замусоривание
○ Никто не ведет лог изменений
○ Теряется связь с реальностью
● Нельзя запускать локально
Пробеум LXC
● Виртуализация на уровне ядра
● Обвязка скриптов для жизненного цикла
● Контейнер живет только во время исполнения
● Нельзя запускать локально
● wiki в 10 экранов описания
● puppet для синхронизации
Jenkins
Server A - debian 7
● foo
● bar
● baz
Server A - debian 8
● foo
● bar
● baz
Server A - centos 7
● foo
● bar
● baz
Server B - centos 7
● alfa
● beta
Server B Deps - centos 7
● boost
● thrift
Server A Deps - debian 8
● boost
● nodejs
● ruby
Надводные камни
● Все еще не версионируем
● Не знаем что установлено на той или иной машине
○ Точнее не уверенны
○ Мало кто хочет этим заниматься
○ Люди уже не любят .deb/.rpm (и в чем-то они правы)
● Считаем дни до падения билдера, чтобы начать все заново
● Эксплуатируется не квалифицированным персоналом
○ Все у кого ключ есть, от уборщицы до талисмана команды
Чем усугубили
Build the world
Build
Server A
Build
Server D
Build
Server C
Deb7
Build
Server C
Deb8
> touch readme.md
> git add readme.md
> git commit -m ‘42’
> git push
> ..
> ..
> ?
Результат
● Собрать маленький пакет -
собираешь все
● Собрать старый бранч -
собирается не все
● Добавляешь новую ОС - привет
проблемы выше
● Хочется взять и переписать
● Проходной двор
Docker
Как это выглядит?
● Хранится в Git
● Описывается Dockerfile
● Храним описание образов
● Конфигурацию jenkins
● Используем makefile
○ make build
○ make package-thing
○ make jenkins-sync
Преимущества
● Работает более-менее везде одинаково
● Можно использовать для разработки
● Легко собрать
● Легко версионировать
● Кеширование образов
Проблемы
● Нет хуков на выполнение команд до/после run
● Образ stateless
○ UID пользователя
● Нет хардлинков host/docker
● Сложности с пробросом переменных окружения
● Сложность с монтированием
○ UID хоста и контейнера разные в общем случае
○ решаемо очередным makefile-ом
Пример
project_repo/ (git)
|- app1/
| |- src/
| |- test/
|- app2/
|- ...
|- builders/ (git submodule)
|- server-type-A/
|- server-type-B/
|- Dockerfile
|- image_files/
| |- config.conf
|- jenkins/
|- app1.xml
|- app2.xml
|- server-A.xml
Пример
cd /path/to/image
# построить
docker 
--build-arg HOST_UID=$(HOST_UID) 
-t myimage .
# собрать пакет
docker run -it --rm 
-v `pwd`/../../:/repo 
-v $(CACHE_DIR):/cache 
-w /repo/program 
-e CXX=clang++ 
-e DEBUG=1 
myimage /bin/bash -c './package && ./test'
Пример
FROM debian:jessie
# apt
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get upgrade -y 
&& apt-get install --no-install-recommends -y 
build-essential
# pip
RUN pip install -U pip
ENV XDG_CACHE_HOME /cache/pip
# user
ARG HOST_UID
ARG HOST_GID
RUN (getent group ${HOST_GID} || groupadd -g ${HOST_GID} hostgroup) 
&& adduser --disabled-password --gecos '' worker --uid ${HOST_UID} --
gid ${HOST_GID}
USER worker
Что дальше?
● Заменить .deb на контейнеры
● Деплоить docker-ом
● Не знать горя и бед
● Технология не идеально,
○ но работает!
Вопросы?