Контеи?неры для взрослых (Часть 03): 10 вещей, которые не надо делать с контейнерами +32



Вы, наконец, сдались на милость контейнеров и обнаружили, что они решают массу проблем и имеет массу преимуществ:

  1. Контейнеры незыблемы: ОС, библиотеки, папки и приложения – поскольку все это хранится прямо в контейнере, вы на 100 % уверены, что в продакшн всегда пойдет именно тот образ, который тестировался в QA. И работать он при этом будет абсолютно аналогично.
  2. Контейнеры легковесны: Контейнер не ест память впустую. Вместо сотен мегабайт и гигабайт контейнеру нужна память лишь под основной процесс.
  3. Контейнеры быстрые: Контейнер запускается так же быстро, как и обычный 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-адрес, который может меняться после перезапуска контейнера. Если приложению или микросервису нужно коммуницировать с другим контейнером, используете переменные среды, чтобы передать нужное имя узла номер порта от одного контейнера другому.
Запомнили? Теперь можете смело пользоваться. А практические советы по использованию контейнеров можно найти в нашем блоге.

Вы можете помочь и перевести немного средств на развитие сайта



Комментарии (84):

  1. muove
    /#19051501

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

  2. SirEdvin
    /#19051527

    Не надо выполнять в контейнере более одного процесса.

    Очень странная идея, может все-таки не больше одного приложения?
    Скажем, если приложение запускает несколько процессов (gunicorn, postgres, ..) нельзя запустить его в контейнере?)

    • D1abloRUS
      /#19051567

      Имеется ввиду, что корневой процесс один, дочерних от него сколько угодно.
      Например, если приложение работает с бд, то бд это отдельный контейнер.

      • SirEdvin
        /#19051577

        Эм… а вы сможете запустить в контейнере два корневых процесса?


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

        • D1abloRUS
          /#19051587

          Так тут и говорят, что не надо запускать в контейнере через supervisord приложения, технически это возможно, ни кто не спорит

          • gecube
            /#19053127 / +1

            От задачи зависит, имхо

            • D1abloRUS
              /#19053193

              Мое имхо, что не зависит, если зависит, значит какие то проблемы в архитектуре

              • gecube
                /#19053485

                Еще раз повторюсь, что от задачи зависит. И вопрос абсолютно не в архитектуре.

                Прекрасные примеры контейнеров для отладочных целей:
                hub.docker.com/r/gitlab/gitlab-ce
                hub.docker.com/r/hortonworks/sandbox-hdp-standalone
                Могу еще надергать.

                • D1abloRUS
                  /#19053539

                  Я не очень понимаю в чем задача, запихнуть gitlab(или любой другой проект) со всеми его зависимостями в один контейнер? Такого рода «контейнеры», просто огромны, в них нельзя изменить зависимости тот же mysql на postgres, почему просто не использовать docker-compose

                  • GerrAlt
                    /#19053673

                    например если я начинающий разработчик мне лучше чтобы "вжух" и работает, менять там mysql на postgres я не собираюсь


                    насчёт gitlab — та же история, хочу попробовать запустить и посмотреть чего как, если ок то соберу свое в прод

                    • D1abloRUS
                      /#19053739

                      docker-compose up -d вжух, это не проблема разработчика, это проблема того, кто предоставляет такие решения

                      • gecube
                        /#19053937

                        docker-compose имеет серьезный недостаток: он плохо моделирует взаимосвязи между сервисами. Т.е. он хорошо моделирует ситуацию, когда один контейнер нужен для запуска другого (например, БД для бекенда), но когда граф зависимостей становится чуточку сложнее (например, появляется отдельная сущность для миграций, предварительной подготовки данных с нормальной обработкой ошибок), то докер-компоуз пасует.
                        Это все-таки средство для разработки и отладки.

                        • D1abloRUS
                          /#19053989 / +1

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

                          • gecube
                            /#19054571

                            Простой пример. Предположим, что у нас миграции отдельно (вопрос почему так не рассматриваем — вполне возможно, что лучше их как пишет ниже VolCh засовывать в основной контейнер с сервисом). Задача, чтобы стартовали три контейнера последовательно
                            (1) БД
                            (2) миграции
                            (3) сам сервис
                            На все контейнеры мы можем поставить healtcheck'и. Попробуйте реализовать с минимальным количеством костылей. Можно в самом контейнере с сервисом сделать ожидание пока база доступна и ждать пока версия схемы БД совпадет с ожидаемым сервисом. Запуск сервисов для разработчика должно быть одной командой (ну, или несколькими, но минимальным количеством) Еще желательно сразу учесть, чтобы сервисы потом поехали в куб с минимальными изменениями и имели возможность масштабироваться.

                            С архитектурной точки зрения — конечно, лучше сразу реализовывать best practice по разработке сервисов с миграциями схем и пр.

                        • qrKot
                          /#19055315

                          Ну вот определитесь уже, вам «моделировать взаимосвязи», «выращивать граф зависимостей» и т.д., или таки монолитный контейнер «все-что-нужно внутри». Как бы, один контейнер на все совершенно аналогично не решает каких-либо задач масштабирования, зависимостей и прочего. При этом компоуз хотя бы даст возможность отдать ровно ту же базу данных еще одному сервису в пределах окружения или расшарить данные между набором контейнеров, чего монолит сделать не даст.

                          • gecube
                            /#19055573

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

                            Касательно docker-compose — это вообще отдельная история и он нерелевантен к изначальному вопросу.

                  • gecube
                    /#19053913

                    Нет такой задачи менять mysql на postgres

                • qrKot
                  /#19055283

                  Каждый раз, когда вы суете базу данных (либо любой иной контент-провайдер) для сервиса в тот же образ, в котором лежит сам сервис, где-то в мире плачет еще один разработчик SOA-архитектуры.
                  Короче, вообще непонятно, зачем:
                  1. Дублировать функционал готового контейнера с движком СУБД в свой «большой контейнер».
                  2. Прибивать сервис гвоздями-сотками к БД на локалхосте.
                  3. Отказываться заранее от возможности все это масштабировать и отливать структуру всего этого в бронзе.
                  При том, что все «плюшки» подхода «вжух и завелось» отлично работают в виде тупенького docker-compose.

                  • VolCh
                    /#19056549

                    Как минимум затем, чтобы не заморачиваться межконтейнерными связями, которые в общем случае «почему-то» настроить сложнее, чем межпроцессными связями в рамках одного контейнера/хоста/неймспейса.

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

                    • qrKot
                      /#19057955

                      Как минимум затем, чтобы не заморачиваться межконтейнерными связями, которые в общем случае «почему-то» настроить сложнее, чем межпроцессными связями в рамках одного контейнера/хоста/неймспейса.


                      Вы точно уверены, что имеете понятие о том, что вы говорите?
                      Вот ЭТО — базовый докерфайл для нормального контейнеризованного постгреса. Вы вот прямо утверждаете, что принести ЭТО в свой контейнер, а потом поддерживать ЭТО в случае надобности изменений — это проще, чем написать docker-compose.yml? На фоне ЭТОГО link: -postgres — сложно?

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


                      И опять вы, вероятно, хотите видеть слезы ни в чем не повинных авторов подхода. «Схожесть» окружений в средах разработки, тестирования и эксплуатации достигается тем, что во всех этих средах запускаются ОДНИ И ТЕ ЖЕ образы контейнеров, заради этого, собственно, все и затевалось. Зачем писать отдельный образ, который будет «вести себя почти как боевой», если можно просто развернуть копию боевого. Заодно не понадобится аккуратно ручками носить изменения из одного докерфайла в другой, лежащий по соседству.

                      Не выдавайте, пожалуйста, свои личные фантазии за «полезные практики». Сколько-нибудь полезной практики ношения СУБД в одном контейнере с сервисом не существует в природе.

                      • VolCh
                        /#19058439

                        Вот именно, что для докеризированного постгреса, который должен конфигурироваться и управляться извне контейнера. Новый уровень абстракции порождает новые сложности по низкоуровневому управлению. Формировать docker-compose сложнее чем сделать RUN apt-get install postgresql.

                        Не везде разворачивается всё из одних образов, более того не везде всё вообще из образов разворачивается. И даже если из одного образа разворачивать, то будет именно схожесть в общем случае, а не идентичность гарантируется. Как минимум из-за аппаратных различий и версий ядра.

                        Существует и используется. Чаще всего именно для целей разработки и тестирования, грубо говоря, замена вагрантфайла докерфайлом.

              • ybalt
                /#19055539

                Все-таки зависит от задачи, и запускать несколько процессов в одном контейнере это нормально, хотя и нежелательно идеологически
                Примеры:
                — надо дать приложению доступ через впн к каким-то ресурсам. через supervisord запускаются и приложение и впн
                — надо иметь монитор процесса/файловой системы/еще чего нибудь. Шарить эти ресурсы между отдельными контейнерами приложения и монитора идея гораздо хуже, чем засунуть все в один

                это только то, с чем сталкивался, примеров может быть больше

                • gecube
                  /#19055587

                  Кстати, с впн я действительно наелся, т.к. запустить ВПН демон в одном контейнер, а потом прилинковать сервис к нему снаружи — это реальная боль. Как одно из ограничений разделение сетевого стека между несколькими контейнерами: впн отвалился, мы его перезапустили, а контейнер с сервисом не видит впна. Приходится перезапускать и его тоже.
                  Проще впн и сервис запускать в одном. Подтверждаю.

    • ALexhha
      /#19051891

      А с чего это вдруг приложение будет запускать postgres? Или что вы имеете виду под приложением?

      А вообще сама идеология докера: один процесс — один контейнер. Т.е. если вы хотите запустить банальный LAMP, то надо запускать 3 контейнера: apache, php (рассматриваем вариант php-fpm), mysql.

      Ну а так конечно никто не мешает запускать какой-нибудь supervisord и уже из под него, хоть 100500 процессов, но это будет идеологически не правильно.

      • VolCh
        /#19052999

        Апач, пхп, мускуль, постгри и прочие обычно работают в режиме один мастер процесс и множество воркеров (могут быть однотипными, могут быть специализированные). Запускаешь вроде один процесс, но он порождает десятки, сотни и тысячи.

      • gecube
        /#19053125

        Нужно уточнить что такое докер контейнер. Это бизнес-единица, единица масштабирования сервиса, единица развертывания или что еще. Концепция «один процесс — один контейнер» слишком ограничена. И в лучшем случае просто приведет к излишнему раздроблению микросервиса на нанокомпоненты

        • qrKot
          /#19055447

          Нужно уточнить что такое докер контейнер. Это бизнес-единица, единица масштабирования сервиса, единица развертывания или что еще.


          Чем бы вы докер-контейнер не считали, идея запихать сервис в один контейнер с БД — хреновая.

          Единица масштабирования? Ок.
          Представим кейс: есть внешнее апи, тяжелый воркер под ним и БД, откуда воркер данные берет/пишет. И все это в одном контейнере…

          … И стал контейнер, как водится, тормозить. При этом выяснилось, что воркер не вывозит. Вот тупо два штуки запустить, и ок… Ан не так это и просто! Берем и перепиливаем весь контейнер с нуля!

          База колом встала? Кластер бы поднять, да соседние контейнеры не трогать? Нельзя — у вас контейнер монолитный, перепиливаем с нуля.

          Ну вот зачем это все, если можно было в самом начале просто один компоуз-файл написать?

          Единица развертывания? Вы реально в прод-развертывании собираетесь этим рулить голым докером? У вас один фиг «в бой» оно пойдет из-под какого-нибудь k8s с вероятностью процентов 80. Т.е. все равно оркестрация будет, декомпозируйте задачу ДО того, как она стала вашей проблемой.

          • gecube
            /#19055599

            БД (именно БД) -лучше выносить наружу и потреблять как DBaaS (например, managed instance). А вот кэш (локальный) — почему и не засунуть в контейнер?
            Я считаю, что просто нужно быть достаточно гибким и не принимать все рекомендации на веру. У всего есть свой trade-off.

            У вас один фиг «в бой» оно пойдет из-под какого-нибудь k8s с вероятностью процентов 80
            Правильное решение. Кто спорит?

            • qrKot
              /#19056129

              Собственно, триггерился я больше на идею «весь LAMP в одном контейнере, а чо нет?». Вот эта идея и прочие «эталонные реализации» с «постгресом внутри контейнера» — изначально очень плохая практика в 99% случаев, и я с ходу не могу придумать кейса, в котором такой подход хоть сколько-нибудь оправдан. Даже как «поиграться с локальным гитлабом» — достаточно «пахнущее» поделие. Натягивать СУБД на практики контейнеров приложений — это как «сова и глобус», в теории можно, но идея заведомо плохая.

              А локальный кеш — почему бы и нет. С нюансом, опять же, в скорости «прогрева» кеша. В проде «прогревающийся» по 10-15 минут инстанс может вылезти боком, «на вырост» надо трейд-офф таки планировать.

          • ybalt
            /#19055605

            При всей замечательности декомпозиции, она далеко не всегда возможна. Тот же K8s управляет, внезапно, не контейнерами, а подами, а под — это набор контейнеров, шарящих между собой общие ресурсы, такие как сетевое пространство. И в нормальной практике использовать sidecar контейнеры в подах рядом с основным приложением или БД. Причем если умирает один контейнер в поде, то перезапускается весь под.
            Так что да, контейнер это единица развертывания, а не строго «один процесс на контейнер», реальная жизнь сложнее идеального кейса. Для кубера единица развертывания — под, это уже ближе к реальности.

            • gecube
              /#19056119

              Спасибо за уточнение насчет пода — оно действительно существенное.

            • qrKot
              /#19056157

              Нюанс в том, что «единица развертывания — под», как раз, отрицает подход «докер-контейнер как единица развертывания».

              Связность сервисов/уровня данных обеспечивается на уровне пода, нет смысла городить все это внутри докера, не для того он. На уровне инициализации контейнера та же БД должна быть ссылкой, откуда ее взять. Не надо внутрь него движок базы данных тащить, плохая это идея.

              • ybalt
                /#19058383

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

  3. dark_ruby
    /#19051713

    я новичок в контейнерах, поясните момент: "Не надо хранить данные внутри контейнера." — при этом советуют создать отдельный контейнер для СУБД, разве это не означает что данные в СУБД будут хранится в контейнере, который вроде как эфемерный

    • lair
      /#19051723

      У контейнера с СУБД данные должны храниться не в контейнере, а на volume, который не эфемерен.

      • bm13kk
        /#19051777

        1) Но это нарушает правило "может быть запущено сколько угодно контейнеров выбранного типа".


        2) А где хранятся миграции? Контейнер миграций, контейнер СУБД?

        • lair
          /#19051809

          Но это нарушает правило "может быть запущено сколько угодно контейнеров выбранного типа".

          Нет, не нарушает. У каждого из этих контейнеров будет свой volume. Можно сделать и общий, но см. "проверяйте, что приложения корректно пишут данные в общее хранилище".


          А где хранятся миграции? Контейнер миграций, контейнер СУБД?

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

        • VolCh
          /#19053007

          Можно назвать это контейнером миграции. Может быть отдельным, но часто достаточно добавить запуск миграций в последовательность инициализации приложения, в какой-нибудь entrypoint.sh например.

        • gecube
          /#19053113 / +2

          Контейнер миграций — ок, тем более, если потом в кубернетес поедешь. Там очень хорошо с концепцией сайдкартов и инит контейнеров

        • qrKot
          /#19055465

          Честно говоря, сами БД в концепцию «12-факторных» приложений ложатся от слова «никак». Масштабирования БД по кластеру — это такая штука, которая средствами оркестрации контейнеров никак не решается, живите теперь с этим)

          • ybalt
            /#19055659

            Это проблема старого подхода к БД, на самом деле. Раньше, в доконтейнерную эпоху, для масштабирования БД требовалось произвести несколько операций вручную — поднять инстанс, подключить его, настроить репликацию или шардинг.
            С появлением контейнеров изменился и подход. Тот же elasticsearch с его service discovery неплохо масштабируется, простое увеличение количества реплик в statefulset приведет к автоматическому масштабированию. Если БД изначально построена со встроенными средствами автомасштбирования и автодискавери, то никаких особых проблем быть не должно.
            У кубера дело пошло еще дальше, а кубер — средство оркестрации, как ни крути, и для кейсов, где требуется масштабировать БД с дополнительными шагами используются операторы, это по сути ops-практики в коде, пример — ectd

            • qrKot
              /#19056179

              Кхм, БД разные бывают. Предлагаю не считать таки Postgre, MsSql, OracleDB и прочие махровые энтерпрайзные РСУБД устаревшим мусором, ок?

              Просто вот с ними все эти штуки вроде «простое увеличение количества реплик в statefulset приведет к автоматическому масштабированию» не работают. Тем более, что выше была идея именно потгре/мускуль в контейнер засунуть. Ну так вот — это плохая идея, и вот эти вещи так не масштабируются.

              • gecube
                /#19058301

                Меня больше пугает не scale up, а scale down, что в штатном режиме, что аварийный

    • DSolodukhin
      /#19052911

      Тут есть два момента.

      1) Запуск БД в Docker вообще нерекомендуемая практика, именно потому что, она предполагает наличие персистентности данных между запусками контейнера. Это противоречит идеологии Docker. Да, можно поиграть с volume, но это костыль.
      2) Не докером единым. Кроме докера существуют и другие виды контейнеризации, например LXC. В LXC вполне допустимо хранить данные в контейнере.

      В любом случае, использовать контейнеры только потому, что это стильно, модно, молодежно и так делают все — это глупо. Вы должны понимать, какую именно задачу вы хотите решить, и исходя из этого выбирать технологии. Если вам нужны обычные виртуалки, но вам жалко оверхеда из-за виртуализации, можно посмотреть на LXC. Docker отлично подходит в ситуации, когда вам нужно поднять N одинаковых инстансов, и N меняется в зависимости от ситуации. Увеличилась нагрузка — вы запустили еще пару инстансов, нагрузка упала — остановили лишние, оставшиеся инстансы справятся.

      • VolCh
        /#19053055 / +1

        1) volume ничуть не костыль, а механизм для хранения состояния контейнеров.
        2) LXC выглядит как набор среднеуровневых инструментов для создания высокоуровневых инструментов таких как докер.

      • GerrAlt
        /#19053691 / +1

        а можно источник, откуда "запускать БД в Docker это нерекомендуемая практика"? или это вы так не рекомендуете делать?


        для какого-нибудь apache вытаскивать webroot в volume тоже не рекомендуете? или вебсерверы тоже не стоит в контейнеры помещать?

        • qrKot
          /#19055543

          а можно источник, откуда «запускать БД в Docker это нерекомендуемая практика»? или это вы так не рекомендуете делать?


          Запуск БД в Docker — это, в первую очередь, достаточно бессмысленная практика.
          Дело в том, что «контейнер приложения» — это такая штука, которая «сдохла, да и пофиг, рядом другую запущу» или «надо масштабироваться? Не проблема, запустим еще 158 инстансов». И вся эта возня с горизонтальным масштабированием, read-only слоями, отказом от бэкапов инфраструктуры и т.д. — она на базах данных не работает. Если вы поверх одного и того же persistent volume'а запустите две одинаковых СУБД, они просто превратят ваше хранилище в кашу, не больше и не меньше. БД просто масштабируются иначе, докер для них смысловой нагрузки не несет, только чуть-чуть лишнего оверхеда приносит.

          А для отладочных целей, «чтобы не морочиться с доступом из compose» и тому подобное — да пожалуйста, не проблема.

          для какого-нибудь apache вытаскивать webroot в volume тоже не рекомендуете? или вебсерверы тоже не стоит в контейнеры помещать?


          Ну, сопсна, всякие «апачи» норм масштабируются, их можно. webroot — это, по факту, набор конфигов, которые апач читает на старте. Апач не генерит миллионы конкуррентных записей в вебрут, для него этот самый webroot — ридонли. Короче, не передергивайте, в случае с апачем все норм.

          • gecube
            /#19055613

            Апач с пхп может легко писать в webroot (говорю про php, т.к. голый апач особо и не нужен). Но это больше вопрос к корректности архитектуры самого web-приложения.

            • qrKot
              /#19056209

              Ну, собственно, php, пишущий в webroot — это «с душком» называется, если мы в контексте «горизонтального масштабирования без боли».

              Собственно, если php «какает» в webroot, то «поднять N контейнеров с этим php и смонтировать в них вольюмом один webroot на всех» — заведомо хреновая идея, например.

              • VolCh
                /#19056593

                Ну для пхп это штатный режим работы: много воркеров (неважно mod_php или php-fpm) шарят между собой один «webroot». Особой разницы нет, воркеры это одного мастера или разных (при плюс-минус совпадающих версиях пхп, есть нюансы при сильно разных).

                • qrKot
                  /#19058007

                  Собственно, я несколько далек от php и принятых в нем практик, конечно, и представления о том, что такое webroot и для чего его можно использовать, конечно, у нас могут различаться. Если под webroot'ом понимать папку с конфигами сервера, конфигурациями эндпоинтов, шаблонами для рендера, скриптами и все вот это — совершенно не вижу проблемы в совместном использовании… В readonly режиме.

                  Т.е. вы наконфигуряли то, что вам надо, разложили скрипты в желаемом порядке настроили, а потом все это «окружение» скормили N контейнерам (нет, N мало, пусть лучше будет K), чтобы они оттуда заинитились и начали работать — нормальный подход.

                  Если же вы на N контейнеров (в этом случае N уже много, лучше ограничиться M) отдали volume на запись… Кхм, даже при M=2 это УЖЕ плохая идея. Предложить нескольким процессам одновременно писать в один файл — это идея хреновая, вне зависимости от контейнеризации. В рамках одного процесса писать в файл параллельно из двух потоков — уже говнокод, простите уж за откровенность. Не надо так делать, пожалуйста. Шарить persistent volume между несколькими контейнерами безопасно только в read-only режиме.

                  • gecube
                    /#19058067

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

                    • qrKot
                      /#19058139

                      Спорно, конечно, но так тоже можно. Это уже от применения зависит.

                      Если вы пилите какой-то веб-проект и конкретно под него собираете контейнер — вполне норм подход.

                      Если вы хостите сторонние приложения, вам логичнее собрать преднастроенный контейнер-окружение и маппить в него пользовательские «папки», чем ребилдить образ на каждый чих от пользователя.

                  • VolCh
                    /#19058467

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

          • GerrAlt
            /#19055643

            Мне кажется что есть еще один момент, который добавляет смысла в идею контейнеризации СУБД: обновление версии СУБД. Лично мне очень приятно иметь всегда чистый хост и не переживать что в результате обновления версии СУБД, а потом отката обратно (всякое бывает, тестирование не всемогуще) я не смогу вернуть систему к ее предыдущему состоянию быстро.

            • qrKot
              /#19056231

              Осталось понять, откуда у вас уверенность в том, что контейнеризация в контексте сохранности БД вам что-то дает…

              • gecube
                /#19056459

                Контейнеризация — это всего лишь способ изоляции и доставки приложений. С этой точки зрения — на отдельно стоящем хосте даже БД с volume лучше запускать в контейнере.
                Другой вопрос, что именно docker как реализация контейнернего движка имеет свои особенности, которые нужно учитывать.

                Просто если развивать концепцию до абсурда, то каждый настоящий мужчина должен ставить постгрес (например) не из бинарного пакета (deb/rpm), а из исходников (make && make install — да, давайте замочим систему «мусором»).

                • qrKot
                  /#19058057

                  Конкретно докер вообще никак не маппится на нужды поддержания консистентности БД. Вся концепция контейнеров приложений строится вокруг «мухи отдельно, котлеты отдельно».

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

                  Вот с вещами вроде постгреса подход не работает.
                  Нельзя вот просто так взять persistent volume, на котором работал 9-й постгре и примонтировать его к контейнеру 10-го. А если вы попрыгали с бубном и примонтировали таки, вы уже не сможете по-быстрому откатиться на 9-ю версию.
                  Собственно структура хранения данных в РСУБД, как правило, очень сильно привязана к версии движка, поэтому вот эти вещи типа «быстрых переключений между версиями безо всяких проблем» — это из разряда сказок на ночь.

                  Бэкап уровня данных — хорошо. При этом забэкапить контейнер ОС (предположим LXD) с развернутым постгресом и данными до кучи — гораздо более простая в реализации и более быстрая с точки зрения «восстановления» или «отката» идея. Тем более, что базы данных вроде постгре имеет смысл использовать на датасетах такого размера, когда «накладные расходы 50МБ на бэкап самого постгреса» — это совершенно малозначимая вещь.

                  Просто если развивать концепцию до абсурда, то каждый настоящий мужчина должен ставить постгрес (например) не из бинарного пакета (deb/rpm), а из исходников (make && make install — да, давайте замочим систему «мусором»).


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

                  • gecube
                    /#19058089

                    Нельзя вот просто так взять persistent volume, на котором работал 9-й постгре и примонтировать его к контейнеру 10-го.
                    На самом деле, это так и работает. Берешь volume от 9-го, подключаешь к 10-му. Он делает какую-то магию и обновляет БД.

                    А если вы попрыгали с бубном и примонтировали таки, вы уже не сможете по-быстрому откатиться на 9-ю версию.
                    Да, правда при вышеописанном процессе запуск volume с обновленными данными со старым 9-м постгрессом зафейлится, т.к. в БД уже будет пометка, что она переконвертирована в 10-ю версию.

                    Это проверено на моем личном опыте.

                    Бэкап уровня данных — хорошо. При этом забэкапить контейнер ОС (предположим LXD) с развернутым постгресом и данными до кучи — гораздо более простая в реализации и более быстрая с точки зрения «восстановления» или «отката» идея.
                    бекапить постгре в контейнере тоже просто. Версия ПО и все ее зависимости — в образе, который лежит в локальном реджистри. Данные — снаружи. И их можно либо бекапить с простоем БД пофайлово, либо утилитами для работы с БД, которые умеют нагорячую. На рабочей же типовой системе — нужно бекапить И конфиги, И базу, и вероятно исполняемые модули (если какая-то хитрая схема экстеншенов). Окей, можно и только базу, но все равно все остальное нужно учитывать. Т.е. докеризация позволяет переложить сложность работы информационной системы с одного уровня на другой (в общем об этом все новомодные технологии вроде k8s)

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

                    В общем, все равно мы приходим к идее, что использование контейнеров весьма многогранно и не ограничивается концепцией развертывания приложений в продуктовой среде по принципу «один контейнер — один процесс».

                    • qrKot
                      /#19058229

                      На самом деле, это так и работает. Берешь volume от 9-го, подключаешь к 10-му. Он делает какую-то магию и обновляет БД.


                      Ну вот этот подход «там произошла какая-то магия, и оно теперь работает» — это малоприемлемо на боевых окружениях со сколько-нибудь ценными данными. Отмазка уровня «какая-то магия как-то там не сработала, и теперь у нас почему-то ничего никак не работает» — это плохая отмазка.
                      Миграция на новую версию БД — это само по себе отдельная песня, и докером она решается примерно никак. В проде — мигрируем руками, в дев-окружении… Ну, в локальных девелоперских окружениях, почему бы и нет. Но там вам, если быть откровенным, ни консистентность данных, ни надежность хранения, ни миграции какие-то не нужны. В дев-окружении необходимо иметь возможность «в случае чего в разумное время заполучить что-то работающее с какими-то правдоподобными данными». Вы же не собираетесь всерьез бэкапить девелоперскую базу?

                      Да, правда при вышеописанном процессе запуск volume с обновленными данными со старым 9-м постгрессом зафейлится, т.к. в БД уже будет пометка, что она переконвертирована в 10-ю версию.

                      Это проверено на моем личном опыте.


                      Вот и я о том же, происходит миграция/конвертация данных. Поэтому уровень хранения данных для СУБД, собственно, от рантайма неотделим. Так что и снапшотить проще и лучше целиком состояние системы, причем, как показывает практика, иногда с точностью до версии ядра или номера версии «третьей сверху системной библиотеки, которая, вроде, и отношения к БД не имеет»

                      бекапить постгре в контейнере тоже просто. Версия ПО и все ее зависимости — в образе, который лежит в локальном реджистри. Данные — снаружи. И их можно либо бекапить с простоем БД пофайлово, либо утилитами для работы с БД, которые умеют нагорячую. На рабочей же типовой системе — нужно бекапить И конфиги, И базу, и вероятно исполняемые модули (если какая-то хитрая схема экстеншенов). Окей, можно и только базу, но все равно все остальное нужно учитывать. Т.е. докеризация позволяет переложить сложность работы информационной системы с одного уровня на другой (в общем об этом все новомодные технологии вроде k8s)


                      Бэкапить БД на уровне логической целостности — просто сделать sqldump. Контейнер на этом уровне не дает вам ничего. Бэкапить БД на уровне физической целостности — отдельный бэкап файлов на диске, с которыми работает СУБД вам опять же ничего не даст. Оно просто не в вакууме живет, и окружение, на котором это все работает, достаточно много значит. Есть же контейнеры ОС, забэкапьте целиком. Собственно, из сценариев быстрого отката в случае БД смысл имеет только бэкап системы. В конце концов, есть же LXD и некоторые другие «контейнеры ОС», дались вам эти «контейнеры приложений».

                      А докеризация никаких проблем в этом контексте не решает. С точки зрения БД вам один фиг под конкретные кейсы «твикать» окружение придется. А пересобирать окружение под конкретные настройки конкретной базы — тоже та еще дичь, если честно.

                      К слову, тот же k8s — он вообще не эти проблемы решает. Он про оркестрацию, ничего там про организацию бэкапов/миграций БД нету, я проверял.

                      Ну и про «рентабельность» всего этого мероприятия (я про контейнеризацию БД). Обычно «докеризованные» сборки СУБД предполагают сценарий «запустить 1 базу на сервере». А СУБД кэшировать любят, индексы строить всяческие и т.д. и т.п. Вот с рациональностью использования ресурсов будут большие вопросы в этом подходе. Запустишь 50 инстансов, в каждом по постгресу. И ограничения выставишь, чтобы «разумно использовать ресурсы». И будет у тебя 40 баз в оперативке лежать закешированные целиком, и еще 10 дейтсвительно «тяжелых» раком встанут под нагрузкой, причем «в среднем по палате» нагрузка на сервер будет околонулевой.

                      А потом появится база, которая не будет «вытягивать» в рамках отдельной машины — и вот тут встанет вопрос «кластера», репликаций и всего вот этого, что в контейнере приложения делается строго «никак».

                      И весь этот геморрой для решения проблемы… чего, собственно? Какую проблему мы решаем? Проблему обновления версии СУБД, которая нам встречается раз в год-два? Не та это задача, которую «автоматизируют» и «ставят на поток». Или проблему сохранности данных? Ну, собственно, и для нее контейнеры приложений решения не предоставляют. Проблему масштабирования? Не масштабируются РСУБД «в лоб» горизонтально…

                      Как вариант — использование докера в качестве промежуточного сборочного этапа (т.е. на входе вольюм с сурцами, на выходе — вольюм с бинарниками, посередине — докер-контейнер со всеми зависимостями для сборки).

                      Собственно, для этого специальный stage в докер добавили не так давно. Специальный билд-контейнер, по факту.

                      В общем, все равно мы приходим к идее, что использование контейнеров весьма многогранно и не ограничивается концепцией развертывания приложений в продуктовой среде по принципу «один контейнер — один процесс».


                      Практика показывает, что использование «контейнера приложений» типа докера офигенно себя показывает именно в схеме «один контейнер-один процесс». Подход 12-факторных приложений, воспроизводимые сборки и т.д. и т.п. — все это офигенно работает в контексте докера.

                      При этом она же показывает, что часть задач «контейнеры приложений» решать не способны, ну просто не маппятся эти задачи на логику контейнера. Собственно, те же РСУБД и не маппятся, собственно. В каких-то задачах докеро-подобные решения дают профит, в каких-то профита нет, а в каких-то лучше докер-со-товарищи и не трогать. И это факт.

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

                      Ну и, по поводу «контейнер все-в-себе-и-даже-БД»… говно подход. При этом задача уже тысячу лет как решена, есть вполне себе вменяемая оркестрация — docker-compose для мелочей на локалхосте, k8s — для продакшена и тысяча решений где-то между этими двумя крайними точками. При этом поверх того же k8s уже пилятся свои обертки… Короче, оно все растет.

                      • VolCh
                        /#19058497

                        Как минимум, помещение СУБД в контейнер (пока не про all-in-one) решает задачу унификации доступа к ней из других контейнеров. Где-то в продакшене контейнер с СУБД может (или даже должен) быть прибит метками и прочим к конкретному хосту, но в рамках контейнерного кластера используются обычные механизмы доступа к контейнеру со всей магией оркестратора типа сервис дискавери, внутренних днсб хелсчекинга и т. п.

                        Про all-in-one — вполне годный подход для определённых задач. Например когда использование докера на проде даже не планируется, и он служит лишь для быстрого развёртывания максимально близких дев и тест окружений. Как легковесная замена вагранту. Зачем городить «пробивание» дефолтной докеровской изоляции процессов в контейнерах друг от друга, если прод заточен на отсуствие изоляции?

              • GerrAlt
                /#19056779

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

                • qrKot
                  /#19058151

                  Хотите «чистую» инсталляцию с «только необходимыми данными» — я вас расстрою. Докер тут помогает «никак». Единственный путь: сдампить БД => поднять «голый» инстанс новой версии => развернуть данные из дампа. Автомиграции контейнера к «чистоте» вообще никак не ведут.

                  Откат на предыдущую версию, выкашивание изменений… Кхм, вы о чем? Сделайте снапшот системы ДО начала миграции. Не получилось — восстановились из снапшота. И быстро, и качественно.

                  Контейнер приложения НЕ гарантирует вам неизменность состояния, к которому вы планируете вернуться. Он гарантирует воспроизводимость сборки, более ничего.

                  • GerrAlt
                    /#19058167

                    А если так:
                    я забэкапил volume с БД
                    убил контейнер с mysql 5.6 (не volume с данными)
                    запустил контейнер с mysql 5.7 смонтировав ему этот volume


                    если надо откатить:
                    я убил контейнер mysql 5.7, volume с данными тоже убил
                    я создал volume с бэкапом
                    я запустил контейнер с mysql 5.6 подцепив ему этот volume


                    почему вы считаете что в данной схеме docker не помогает мне вернуться к стабильному состоянию системы? Или вы считаете что состояние будет не соответствовать исходному?

                    • qrKot
                      /#19058255

                      Прямо в этом сценарии:
                      1. Представим, что у вас контейнер mysql:5.6, вот прям с тэгом 5.6. При этом у вас НЕТ гарантии, что там лежит ровно тот же 5.6, что и был в предыдущем образе. В предыдущем, предположим, был 5.6.28, а в регистри уже обновился до 5.6.45 (цифры с потолка). Т.е. вы НЕ вернулись в предыдущее состояние.
                      2. В случае снапшота системы целиком вы просто запускаетесь из снапшота. В вашем сценарии вы убиваете контейнер, который у вас не завелся — это раз, затем создаете новый вольюм с бэкапом (кстати, он у вас КОПИЯ, т.е. где-то могли права доступа к файлам «поехать» или еще что-то по мелочам, что вы выясните уже гораздо позже) — это два, пересоздали и запустили новый контейнер без гарантии полной идентичности версии (в докер-образе mysql:5.6 5.6 — это ТЕГ контейнера, который, по джентльменскому соглашению с сопровождающими образ совпадает, вроде как, с версией мускуля, при этом не гарантированно совпадает).
                      Т.е. вы сделали 3 шага вместо одного, вы имеете МЕНЬШУЮ вероятность отката в предыдущее состояние.

                      Т.е. мы имеем:
                      1. Более длительный откат состояния (за помощь от докера не засчитывается).
                      2. Вы получили меньше гарантий возврата в исходное состояние (тоже помощью считать трудно).
                      3. Вы не получили внятной информации о происходящем и затруднили себе отладку всей этой ситуации (тоже, вроде, не помощь).

                      Понимаете, докер — это про rolling release. Вот там он цветет и пахнет. Крутить СУБД на rolling-release версиях — так себе удовольствие.

                      • gecube
                        /#19058281

                        1. Если мы собираем образы сами, то мы это гарантируем. Если нет, то обычно в нормальных дистрибьюциях (нормальных пацанов, которые собирают образы, или у официальных поставщиков ПО) есть какие-либо четкие регламенты. Т.е. деплоить latest или любой другой общий тег — слабоумие и отвага (с)
                        Касательно разницы минорных версий — она есть, но не всегда она существенна. Мне кажется, что с минорными версиями Вы преувеличваете проблему.
                        2. Касательно прав. Обычно к этому моменту процесс уде отлажен и тогда такая проблема не возникнет. Либо в любом случае всегда хорошая идея проверять миграции на клоне продакшена, а не пытаться сразу что-то «на живую» сделать с продом. И тогда если полыхнет в тесте, то пойдешь изучать вопрос, а не мигрировать прод сразу
                        Дополнительно — всегда контейнер можно перезапустить НЕ ПО ТЕГУ, который действительно может уже иметь под собой другой образ, а по sha-сумме, которая гарантированно отличает образы и позволяет инстанцировать из образа «тот самый» контейнер

                        Касательно обновления бинарными пакетами (deb/rpm) или не дай Бог — исходниками — тоже так себе удовольствие

                      • GerrAlt
                        /#19058391

                        Вы делаете странное предположение что я тащу контейнеры из общего репозитория, для продакшена я такого никогда не делаю и вам не советую. У меня есть мой Dockerfile, из него собранный образ, и в нем совершенно точно лежит именно та версия которая работала до начала обновления.

                        кстати, он у вас КОПИЯ, т.е. где-то могли права доступа к файлам «поехать»
                        — не понял вас, что значит «поехать»? При копировании файлов владельцем у файлов могут поменятся права?

                        Понимаете, докер — это про rolling release
                        я и не спорю что его так можно использовать, пока что не понял почему вы отказываете ему в функции фиксации состояния системы? Потому что вы используете готовые контейнеры и не можете полностью положиться на систему тегов?

                    • qrKot
                      /#19058269

                      А, забыл еще вот что.
                      Вы же КОПИЮ volume'а создадите. Это будут НОВЫЕ файлы, НОВЫЕ файловые дескрипторы и все вот это. Тот же постгре после отката на совершенно законных основаниях может начать ребилдить индексы, реструктурировать хранилище и все вот эти вещи, которые он так прикольно умеет делать, что может отсрочить возвращение базы в строй «на некоторое слабопредсказуемое время». Думаю, этот кейс мы тоже в плюсы «докеризации» записывать не будем?

                      • gecube
                        /#19058289

                        И что? Не вижу связи. Никто и не гарантирует на уровне структуры БД, что одни и те же файлы БД будут попадать в те же, скажем, физические структуры вроде айнодов, но как-то живем и так?

                  • gecube
                    /#19058293

                    Касательно снапшота — его тоже нужно уметь констстентно делать. Я уже наелся со снимками, сделанными средствами гипервизора (ага, желательно без клиентских утилит в гостевой ОС)…

                    К чему это я? А к тому, что кол-во уровней абстракции катастрофически выросло и нужно понимать связанные с этим риски (что и где может «протечь»)

                    • VolCh
                      /#19058515

                      Или наоборот: абстракции закроют доступ к важным деталям реализации.

  4. gecube
    /#19053105

    Редхат в своем репертуаре. Опять статья ни «о чем». Рассмотрены вроде бы прописные истины, но жизнь, как обычно, оказывается разнообразнее. Например, тезис про «один процесс на контейнер» очень хорошо опровергается примером гитлаб омнибус докер образом. Да, он не для продуктива в энтерпрайзе, но для продуктива маленькой команды или для дев/тест среды — идеально.
    Также статья не дает готовых решений с описанием почему так, а не иначе. Например, тот же кейс с supervisord, tini/runit и зомби-процессами, как грамотно определять вольюм. А запуск приложения не под-рутом в докере — это отдельный способ выстрелить себе в ногу, в случае если к файлам в volume нужно еще как-то обращаться (из другого контейнера или с хостовой системы)

    • gecube
      /#19053109

      От коллег из редхата с богатым опытом эксплуатации докер и разработки опеншифт реально ожидаешь мегастатью, руководство к действию, а не перечисление каких-то «азбучных истин» (да и то с определенными границами применимости)

  5. isden
    /#19053221 / +1

    Хочу напомнить, что контейнеры — это не только docker. Еще есть, например, lxd. И там немного другая идеология.

    • romangoward
      /#19054369

      "Другой идеологи" там нет, этот тот же Swarm, только от Cannonical.

      • isden
        /#19054811

        Нет, там контейнеры чуть ближе к виртмашинам (и таки да, можно в cloud-init при наличии поддержки в образе). Нет слоев и прочего. Swarm (в терминах докера) там вообще нет. И, внезапно, нет докерфайлов. Можно персистентность.

        • romangoward
          /#19058585

          Там используются одинаковые системные инстурменты для создания окружений.
          И точно так же там есть поддержка и overlayfs, и blockdevices.
          И как в Swarm, там можно управлять удалённо кластером нод и контейнерами.

          • isden
            /#19058603

            Насколько помню, нет в lxd overlayfs (ну т.е. так как оно в докере, слоисто). Там все работает через снепшоты btrfs/zfs/lvm.
            Swarm в докере — это не только «управлять удалённо кластером нод и контейнерами», но и этого нет в lxd (ну мы сейчас не про k8s же?).

            И вот про это можно ли подробнее?

            > Там используются одинаковые системные инстурменты для создания окружений.

            Я имел некоторый опыт и с докером и с lxd, подходы там к сборке образов и деплою ну совершенно разные.

      • qrKot
        /#19055575

        Есть.
        Докер — контейнер приложения.
        LXD — контейнер ОС.

  6. gecube
    /#19057581

    Касательно п.10 — начали за здравие и кончили за упокой. Таким образом очень быстро приходим к необходимости service discovery, которого в docker изначально нет. Либо изворачиваться с внешними решениями, которые инкапсулируешь к себе в контейнер (consul, например), либо резко перекатываться в кубик и использовать его возможности (но тоже не абсолют).

    • VolCh
      /#19058527

      в docker есть встроенный кластерный оркестратор в том числе с service discovery — swarm. Возможностей (судя по описаниям k8s) поменьше, ограничений побольше, но гораздо-гораздо проще, если вам не нужна оркестрация тысячами контейнеров только в прод окружении, автоскейлинг и прочие мастхэв плюшки хайлоада, ентерпрайза и т. п., а просто нужно CI/CD приложения на пару десятков сервисов. Да даже чего-то вроде бложика на вордпресс.

      • gecube
        /#19059233

        Это такое… Все равно эти доменные имена надо где-то регистрировать, чтобы сервис-потребитель мог найти сервис-поставщика. В частности, проблема с сервисами типа nginx, который если DNS апстрима не резолвится, вообще стартовать не будет. Это все можно обойти перестроив свое мышление и архитектуру приложения(й), но это требует времени, внимания и усилий.

        • VolCh
          /#19060559

          Как-то особо не сталкивался с глобальной перестройкой мышления пока просто контейнеризируешь относительно простые приложения с условно стандартной архитектурой, которые до того раскатывались по серверам ручками по пускай объёмной, но простой инструкции. Единственная более-менее серьёзная проблема — отзыв контейнеров на запросы внешних клиентов, вернее донесение до них IP публичного адреса контейнера (обычно контейнера с прокси).

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