Как стать автором
Обновить

Как протестировать образ для docker за полсекунды

Время на прочтение4 мин
Количество просмотров18K
Всего голосов 28: ↑27 и ↓1+26
Комментарии18

Комментарии 18

Что-то я не понял зачем это всё нужно. Вы что сомневаетесь в возможностях Dockerfile описать нужное состояние системы?
А что, Dockerfile уже позволяет описать нужное состояние системы? Мне почему-то казалось, что там описан порядок действий, а в какое состояние придет система после этих действий, докеру совершенно безразлично.
Dockerfile это не более чем сценарий, по которому образ будет собран. Все хорошо, когда образ состоит только из условно локальных файлов, но когда какой-то пакет ставится извне, то в какой-то момент после пересборки образ уже не будет работать как должен. Или же, например, nginx конфиг будет примонтирован в образ, чтобы сделать его хоть сколько-то полезным — с этого момента поведение nginx может измениться и он либо не на том порту запустится, либо не тот ответ, что нужно будет отдавать.

Таким образом, можно не только тестировать образ после каждой пересборки (например, push в gitlab, запуск CI для билда образа, базовые тесты и push в docker registry), но и тестировать образ в рамках како-то проекта. Мне видится такой сценарий и особенно полезным применением как раз было бы тестирование в рамках Gitlab CI после билда образа.

Это проверка того, что Dockerfile содержит последовательность команд, приводящую систему в нужное состояние. Как в юнит-тестировании кода проверяется, что модуль делает то, что от него ожидается, содержит последовательность инструкций, выдающую нужный результат.

Смысл докерфайла как раз в том чтобы собирать из раза в раз одинаковый образ, вне зависимости от внешних факторов. Если у вас докерфайл может собрать нерабочий образ (или работающий не так как задумано) — это не правильный докерфайл.

Смысл тестирования образа — это автоматическое определение правильный докерфайл или неправильный.

Ага, вот так понимаю :) Спасибо.

Откройте почти любой докерфайл — и вы обнаружите там кучу шелла. А теперь расскажите нам, с чего вы взяли, что на шелле пишут код без ошибок, и этот код не нужно тестировать?

Такими темпами, скоро нужно будет писать тесты для тестов…
они уже пишутся.
понятно, не массово
Отлично, постоянно от вашей команды статьи, которые как нельзя кстати попадаются)))
Пишите истчо, не останавливайтесь)
Есть несколько вопросов

1. Правильно ли я понял, что для запуска тестов у нас должен быть запущен и сам контейнер? Если да, то как запускать подобные тесты на CI. У нас например CI уже поднимает слейв ноды в докере, так что нет возможности запускать докер

2. С учетом философии докера: 1 контейнер — 1 процесс, в чем смысл таких проверок? Или мы просто проверяем, что наш единственный сервис был правильно установлен и были выставлены корректные права?

3. Как быть со случаем когда у нас микросервисная архитектура и по отдельности делать проверки особого смысла нет. Ну например, у нас есть два контейнера nginx и php-fpm. По отдельности мы их проверили, и там все было нормально. Но когда мы запустим их одновременно, то обнаружатся проблемы, например в nginx был указан не тот порт или путь к сокету php-fpm
2. Если у вас в баше стена текста для билда образа, декларативная проверка готового образа на формальное соответствие требованиям немного упростит жизнь.

3. Тестирование в связке и тестирование в изоляции — это разные уровни абстракции, со своими подходами, целями и пр. Тестирование в изоляции докер-инфраструктуры и логики приложения — тоже разные абстракции.
Если тестировать по отдельности смысла нет, не тестируйте. У всего есть бенефиты и косты. Рациональное и бережное отношение к ним, один из признаков профессионализма.
1. пробросьте сокет докера с хоста внутрь контейнеризированого дженкис слейва, будет «докер-в-докере».
-v /var/run/docker.sock:/var/run/docker.sock

Подробнее в последней секции.
Ну это не вариант, ибо в таком случае я получаю доступ ко всем контейнерам. Или я что то упускаю?
Для запуска докера в докере просто нужен контейнер с докером, запущенный в привилегированном режиме (--privileged): https://hub.docker.com/_/docker/

Отлично работает в CI для простых сценариев. Для экономии времени (хотя и в угоду небольшим рискам) объявляем /var/lib/docker как volume, чтобы кеш образов, скачанных при работе dind (docker-in-docker) сохранялся между запусками контейнера. Так работает Gitlab CI (один из режимов).

Пробрасывать сокет внешнего докера в контейнер нужно, например, для работы какого-то сервиса с вашим внешним же докером — например, https://github.com/chadoe/docker-cleanup-volumes или https://github.com/jwilder/docker-gen
А как вы при этом собираетесь запускать образы докера внутри уже поднятого докера? Т.е. вам по любому надо пробрасывать сокет с хоста и как минимум нужен докер клиент. Или я что то упускаю?
Docker — это два компонента, сам демон (dockerd) и клиент (docker). Клиент по дефолту работает через локальный сокет. В контейнере dind есть и демон и клиент — демон стартует как единственный процесс образа, в общем, как и должно быть.

Если зайти в запущенный dind контейнер и выполнить там какую-то команду через клиент, к примеру, docker ps — то клиент через локальный сокет внутри контейнера подключится к демону и будет с ним взаимодействовать — т.е. ps покажет контейнеры, запущенные внутри контейнера.

Если нужно, чтобы клиент внутри контейнера взаимодействовал с докер демоном хост машины, то внутрь контейнера нужно подключить сокет демона с хост машины как volume, например, запустить контейнер с параметром -v /var/run/docker.sock:/var/run/docker-on-host.sock. Затем внутри контейнера уже можно будет работать с этим сокетом как обычно. В случае использования клиента docker нужно указывать путь к кастомному сокету в параметре -H, например, команда docker -H unix:///var/run/docker-on-host.sock ps выполненная внутри такого контейнера будет взаимодействовать с демоном с хост машины — т.е. ps покажет контейнеры, запущенные не внутри контейнера, а в демоне докера на хосте.

То же самое с docker run — контейнер будет создан в том демоне, сокет которого будет использовать docker клиент. (или не сокет, а IP и порт, смотрите описание параметра -H клиента docker).
Зарегистрируйтесь на Хабре, чтобы оставить комментарий