Вы, наконец, сдались на милость контейнеров и обнаружили, что они решают массу проблем и имеет массу преимуществ:
- Контейнеры незыблемы: ОС, библиотеки, папки и приложения – поскольку все это хранится прямо в контейнере, вы на 100 % уверены, что в продакшн всегда пойдет именно тот образ, который тестировался в QA. И работать он при этом будет абсолютно аналогично.
- Контейнеры легковесны: Контейнер не ест память впустую. Вместо сотен мегабайт и гигабайт контейнеру нужна память лишь под основной процесс.
- Контейнеры быстрые: Контейнер запускается так же быстро, как и обычный Linux-процесс. Не минуты, а буквально считанные секунд.
Однако, многие до сих пор считают, что контейнеры – это виртуальные машины, и забывают про важнейшее их свойство…
Контейнеры эфемерны
Одноразовость – вот почему вы должны изменить свой подход к тому, как обращаться с контейнерами.
И вот что ни в коем случае не надо делать, чтобы не растерять преимущества контейнеров:
1. Не надо хранить данные внутри контейнера. В ходе жизненного цикла контейнеры могут приостанавливаться, уничтожаться, заменяться. Если приложение работает в контейнере, то версия 1.0 этого приложения должна легко меняться на версию 1.1 без потери данных и прочих неприятностей. Поэтому, если требуется сохранять данные, их надо писать на том. Однако тогда надо позаботиться, чтобы два контейнера не писали в одно и то же место, чтобы не повредить данные. Так что, проверяйте, что приложения корректно пишут данные в общее хранилище.
2. Не надо дробить доставку приложений. Некоторые думают, что контейнер – это та же виртуальная машина. И большинство из них считают, что приложения надо развертывать в уже имеющиеся работающие контейнеры. На самом деле так тоже можно, особенно в фазе разработки, когда идет постоянная отладка и развертывание. Но вот поступать на CD-конвейер непрерывной доставки для передачи отделу QA или в продакшн приложения должны только в составе собственного образа. Помните: контейнеры незыблемы.
3. Не надо создавать большие образы. Большой образ сложнее распространять. Поэтому в образ следует включать только те файлы и библиотеки, которые действительно нужны для запуска процесса приложения. Не надо устанавливать ненужные пакеты или запускать обновления (yum update), которые создают в образе новый слой и пишут на него массу файлов.
4. Не надо использовать однослойные контейнеры. Чтобы эффективно использовать многослойные (многоуровневые) файловые системы, всегда создавайте отдельные слои для ОС, для username definition, для конфигурации и, наконец, для, собственно, приложения. Так будет проще пересоздавать, сопровождать и распространять образы.
5. Не надо создавать образы из запущенных контейнеров. Иначе говоря, не применяйте команду docker commit для создания образа, поскольку такие образы не будут воспроизводимыми. Вместо нее всегда используйте Dockerfile или другие инструменты S2I (source-to-image), которые обеспечивают воспроизводимость. Кроме того, в Dockerfile можно легко отследить изменения, если хранить его в репозитории исходных текстов (git).
6. Не надо использовать только тег latest. Этот тег – что-то вроде SNAPSHOT для пользователей Maven. В силу многослойности файловой системы контейнеров теги очень полезны. Однако вас может поджидать неприятный сюрприз, когда, например, после многомесячного перерыва вы решите собрать образ и внезапно обнаружите, что приложения больше не запускается, поскольку родительный слой (FROM на языке Dockerfile) был заменен новой версией, которая не поддерживает обратную совместимость. Или потому, что из кэша сборки извлеклась не та последняя (latest) версия, что вы ждали. Кроме того, тега latest также стоит избегать при развертывании контейнеров в продакшн, поскольку вы не сможете отследить, какая версия образа запускается.
7. Не надо выполнять в контейнере более одного процесса. Контейнеры идеально приспособлены для выполнения одного процесса (демона http daemon, сервера приложений, СУБД). В противном случае вы можете столкнуться с разного рода неприятностями, типа копания в логах или обновления процессов по отдельности.
8. Не надо хранить учетные данные в образе – используйте для этого переменные среды. Не прописывайте в образе никаких логинов и паролей. Вместо этого используйте переменные среды, чтобы вытащить соответствующие данные из внешних по отношению к контейнеру источников. Образ Postgres – отличный пример того, как это надо делать правильно.
9. Не надо запускать процессы от имени root. «По умолчанию docker-контейнеры запускаются с правами root. (...) Однако по мере развития технологии могут появиться и другие, более безопасные варианты запуска по умолчанию. В современных условиях требование прав root может расцениваться как угроза и предоставляться не во всех средах. Для указания пользователя, отличного от root, от имени которого будет запускаться контейнер, используется директива USER» (Выдержка из Guidance for Docker Image Authors)
10. Не надо полагаться на IP-адреса. У каждого контейнера есть собственный внутренний IP-адрес, который может меняться после перезапуска контейнера. Если приложению или микросервису нужно коммуницировать с другим контейнером, используете переменные среды, чтобы передать нужное имя узла номер порта от одного контейнера другому.
Запомнили? Теперь можете смело пользоваться. А практические советы по использованию контейнеров можно найти в нашем блоге.
Автор: redhatrussia