Pull to refresh
52.63
Visiology
Компания-разработчик российской BI-платформы

Проблемы при сборке Docker образов внутри Docker контейнеров на TeamCity

Reading time4 min
Views6.7K

Всем привет! В предыдущей статье я рассказал, как можно перевести TeamCity на работу по HTTPS. Сегодня я расскажу, с какими проблемами мы столкнулись и как их решали. Поехали!

Немного предыстории

TeamCity мы используем уже больше 7 лет, и в самом начале его использования мы даже не подозревали про Docker, поэтому сервер и агенты у нас крутились на какой-то виртуалке через скрипты. Но были проблемы: скрипты периодически глючили, виртуалка тоже, переезд виртуалки на другой компьютер вызывал кучу проблем, всевозможные непонятки с окружением при сборке новых версий приложения.... И при каждой такой проблеме процесс сборки вставал на полдня-день. Со временем мы стали собирать наше приложение в докере - это избавило нас от проблем окружения. А потом мы решили и TeamCity тоже засунуть в Docker для удобства администрирования.

Проблема 1: Выбор правильного образа для агента

С образом для сервера ошибиться невозможно, а вот с образом для агента очень даже. Тем более, что когда мы внедряли это решение, то документация была гораздо скуднее.

Если вы хотите использовать Docker для сборки своего приложения на агенте, то обязательно надо брать образ jetbrains/teamcity-agent:XXX-linux-sudo. Собственно, это и была наша первая проблема и потеря нескольких дней для "дебага". Потому что на версии без/с sudo это выглядит так

Образ без sudo и несоответствие требований для сборки
Образ без sudo и несоответствие требований для сборки
Правильный образ
Правильный образ

С версии 2020.1.1 JetBrains предоставляет уже готовые sudo образы, но когда переходили мы, готовых образов не было и нам пришлось собирать их самим по документации.

Проблема 2: Неправильный запуск

С запуском сервера ошибиться практически невозможно. Единственная проблема - это права на папки.

docker run -it --name teamcity-server-instance  \
    -v <path-to-data-directory>:/data/teamcity_server/datadir \
    -v <path-to-logs-directory>:/opt/teamcity/logs  \
    -p <port-on-host>:8111 \
    jetbrains/teamcity-server

Собственно, папкам <path-to-data-directory> и <path-to-logs-directory> надо выдать права sudo chown -R 1000:1000 <path>.

С агентами сложнее - нужно правильно "стартануть" докер внутри агента. Документация предлагает 2 опции на выбор (я опущу некоторые параметры):

  1. docker run -it -u 0 -v /var/run/docker.sock:/var/run/docker.sock jetbrains/teamcity-agent

  2. docker run -it --privileged -e DOCKER_IN_DOCKER=start jetbrains/teamcity-agent

В первом случае агент цепляется к докеру от хостовой машины со всеми вытекающими плюсами и минусами. На самом деле, плюсов то и нет кроме доступа с хостовой машины к собранным образам, но кому это может понадобиться я не представляю. А из минусов - появляется возможность "угробить" хостовый докер из билд агента, во втором случае такого нет. Но в любом случае документация настоятельно рекомендует помнить о возможных проблемах безопасности (почитать можно здесь и здесь), и действовать на "свой страх и риск", потому что билды смогут получить рутовые права к хостовой машине. Мы поигрались с первым вариантом и решили выбрать второй.

Проблема 3: Постепенное уменьшение свободного места

Эта проблема появилась не сразу, и причина долгое время была непонятна. Мы просто грохали докер контейнер агента, чистили вольюмы и запускали агент заново. На всё про всё уходило 20 минут. Поначалу это происходило раз в месяц, потом всё чаще и чаще... В итоге в какой-то момент это стало проявляться каждую неделю, а хуже всего, что это произошло прям во время сборки релиза уже ближе к концу сборки, наше терпение лопнуло и мы решили найти причину.

Причина оказалась довольно "банальной". Один из наших проектов запускает автотесты через docker-compose: поднимается контейнер приложения и контейнер с тестами, запросы летят к приложению, на выходе формируется отчёт. Отчёт получается довольно жирным и нам показалось удобным монтировать хостовую папку (папка в докер контейнере агента) в контейнер с тестами, чтобы отчёт сразу был доступен на хосте - это и была наша "ошибка". Оказалось, что вольюмы монтируются с правами root пользователя, а сервис билд агента TeamCity запускается от пользователя buildagent, поэтому при чистке он просто не мог удалить эти отчёты.

Решения три:

  1. Запускать контейнер билд агента с параметром -u, сервис внутри запускался из под root пользователя. Но это не безопасно.

  2. Не монтировать вольюм напрямую при запуске, а копировать нужные файлы из контейнера после его остановки.

  3. Внутри контейнера с отчётами поменять права у файлов.

Как быстрое временное решение, мы выбрали первый вариант.

Проблема 4: Недоступность сетевых ресурсов

Некоторые наши сборки используют пакеты, которые тянутся из внешних ресурсов. Например, различные npm и NuGet пакеты. И периодически были проблемы с сетевой доступностью - все запросы падали с 503 ошибкой. Эта проблема возникала спонтанно и уходила аналогично, но доставляла массу проблем, когда надо было срочно что-то собрать.

В итоге, вылечилось добавлением опции --network host при запуске билд агента.

Проблема 5: Недостаток предустановленных библиотек

По большому счёту это и не проблема, но всё же из коробки наш билд не собрался. Например, по-умолчанию не идёт библиотека jq для манипуляций с json. Мы сделали кастомный агент, в который добавили нужные нам библиотеки.

Что получилось?

Если собрать всё воедино, то получится что-то такое

docker run -dt \
  -u 0 \
  -e SERVER_URL="XXX" \
  --name teamcity-agent-instance \
  -v <conf_path>:/data/teamcity_agent/conf \
  --privileged -e DOCKER_IN_DOCKER=start \
  --restart=always \
  --log-driver=none \
  --network host \
  custom-agent-image:2021.2-linux-sudo

PS

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

А с какими проблемами сталкивались вы? Пишите решения в комментариях.

Tags:
Hubs:
Total votes 3: ↑2 and ↓1+2
Comments18

Articles

Information

Website
ru.visiology.su
Registered
Founded
Employees
51–100 employees
Location
Россия
Representative
Иван Вахмянин