Docker best practices

В данной записи я бы хотел подытожить тот опыт, что я получил при работе с Docker. Надеюсь, данная статья поможет тем, кто обдумывает его внедрение в своих проектах. Являясь низкоуровневым компонентом, который трудно заменить на боевой системе, знание определенных моментов поможет обойти некоторые грабли заранее.

1. Не все серверное ПО имеет смысл изолировать в контейнерах.

Перед вашим сайтом стоит HA-Proxy? За рассылку писем отвечает Postfix? Не спешите перетягивать их на Docker. Почему? Во-первых, оба этих инструмента исполняются в chroot-окружении. Соответственно, отпадает надобность в их изоляции на уровне ФС. Во-вторых, HA-Proxy при перезагрузке запускает новый процесс, передает ему сокет, ждет, когда старый процесс обработает все имеющиеся у него запросы и останавливает его. Такая процедура несовместима с docker по той причине, что как только главный процесс останавливается, вместе с ним также останавливается контейнер. Единственный способ обновить конфигурацию haproxy — перезапустить контейнер (или использовать supervizord, что противоречит самой концепции Docker).

2. Храните весь волатильный контент на хост-машине.

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

3. Избегайте линковки контейнеров и использования —add-host.

В первую очередь, это касается линковки (опция —link). Эти директивы весьма схожи по своему поведению. Слинкованные контейнеры могут взаимодействовать по сети, используя имя в качестве доменного имени. То есть, если мы запустили контейнер foo и слинковали его с контейнером bar, то в контейнере foo команда ping bar будет пинговать контейнер bar.

Опция —add-host ведет себя аналогичным образом, только вместо контейнера используется произвольный IP адрес или хостнейм. Аналогичного результата, можно было бы добиться, внеся в контейнере в /etc/hosts имя и адрес.

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

4. Иногда имеет смысл предоставить контейнеру интерфейс хост машины.

Или дать ему свой личный. В основном, это касается приложений, активно использующих сеть (прокси серверы, СУБД). По умолчанию, Docker использует NAT, что означает, что для всех пакетов, прежде чем они попадут в целевой контейнер, будет изменен IP адрес получателя и пересчитаны чексуммы. То же самое касается и исходящих пакетов. Все эти действия накладывают дополнительную нагрузку на систему, что приводит к падению производительности. В заметке блога компании Percona, видно, что это приводит к более чем двукратному падению пропускной способности.

Добавить комментарий