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

  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
    30.08.2018 13:46

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


  1. SirEdvin
    30.08.2018 13:51

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

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


    1. D1abloRUS
      30.08.2018 14:02

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


      1. SirEdvin
        30.08.2018 14:04

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


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


        1. D1abloRUS
          30.08.2018 14:06

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


          1. gecube
            30.08.2018 19:11
            +1

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


            1. D1abloRUS
              30.08.2018 19:24

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


              1. gecube
                30.08.2018 20:52

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

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


                1. D1abloRUS
                  30.08.2018 21:08

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


                  1. GerrAlt
                    30.08.2018 21:42

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


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


                    1. D1abloRUS
                      30.08.2018 22:00

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


                      1. gecube
                        30.08.2018 22:57

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


                        1. D1abloRUS
                          30.08.2018 23:16
                          +1

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


                          1. gecube
                            31.08.2018 08:24

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

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


                        1. qrKot
                          31.08.2018 11:17

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


                          1. gecube
                            31.08.2018 12:05

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

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


                  1. gecube
                    30.08.2018 22:46

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


                1. qrKot
                  31.08.2018 11:13

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


                  1. VolCh
                    31.08.2018 15:16

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

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


                    1. qrKot
                      31.08.2018 20:15

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


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

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


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

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


                      1. VolCh
                        31.08.2018 23:25

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

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

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


              1. ybalt
                31.08.2018 11:58

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

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


                1. gecube
                  31.08.2018 12:06

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


    1. ALexhha
      30.08.2018 15:00

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

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

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


      1. VolCh
        30.08.2018 18:26

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


      1. gecube
        30.08.2018 19:09

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


        1. qrKot
          31.08.2018 11:41

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


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

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

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

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

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

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


          1. gecube
            31.08.2018 12:10

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

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


            1. qrKot
              31.08.2018 13:58

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

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


          1. ybalt
            31.08.2018 12:10

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


            1. gecube
              31.08.2018 13:56

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


            1. qrKot
              31.08.2018 14:04

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

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


              1. ybalt
                31.08.2018 23:01

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


  1. dark_ruby
    30.08.2018 14:31

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


    1. lair
      30.08.2018 14:33

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


      1. bm13kk
        30.08.2018 14:41

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


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


        1. lair
          30.08.2018 14:45

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

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


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

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


        1. VolCh
          30.08.2018 18:29

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


        1. gecube
          30.08.2018 19:07
          +2

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


        1. qrKot
          31.08.2018 11:46

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


          1. ybalt
            31.08.2018 12:20

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


            1. qrKot
              31.08.2018 14:09

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

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


              1. gecube
                31.08.2018 22:25

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


              1. ybalt
                31.08.2018 22:47

                Вы можете считать что угодно, но я говорил о подходе к кластерной архитектуре, а не о мусоре.
                СУБД, созданные в те времена, когда единственным способом увеличить их производительность было взять машину помощнее, работают до сих пор, и для их скейлинга надо постараться, я не зря упомянул операторы кубера, это просто не работает из коробки, в отличие от современных СУБД.
                Так что насчет «не маcштабируются» вы не правы
                aws.amazon.com/ru/about-aws/whats-new/2017/11/amazon-aurora-now-supports-auto-scaling-for-aurora-replicas
                azure.microsoft.com/en-us/resources/videos/azure-sql-database-dynamically-scale-up-or-scale-down


    1. DSolodukhin
      30.08.2018 18:04

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

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

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


      1. VolCh
        30.08.2018 18:45
        +1

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


      1. GerrAlt
        30.08.2018 21:47
        +1

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


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


        1. qrKot
          31.08.2018 11:59

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


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

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

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


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


          1. gecube
            31.08.2018 12:11

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


            1. qrKot
              31.08.2018 14:12

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

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


              1. VolCh
                31.08.2018 15:23

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


                1. qrKot
                  31.08.2018 20:27

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

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

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


                  1. gecube
                    31.08.2018 20:46

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


                    1. qrKot
                      31.08.2018 21:09

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

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

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


                  1. VolCh
                    31.08.2018 23:34

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


          1. GerrAlt
            31.08.2018 12:18

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


            1. qrKot
              31.08.2018 14:15

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


              1. gecube
                31.08.2018 14:54

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

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


                1. qrKot
                  31.08.2018 20:45

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

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

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

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

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


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


                  1. gecube
                    31.08.2018 20:54

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

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

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

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

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

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


                    1. qrKot
                      31.08.2018 21:51

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


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

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

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


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

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


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

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

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

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

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

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

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

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

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


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

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

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

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


                      1. VolCh
                        31.08.2018 23:49

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

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


              1. GerrAlt
                31.08.2018 15:58

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


                1. qrKot
                  31.08.2018 21:13

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

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

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


                  1. GerrAlt
                    31.08.2018 21:22

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


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


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


                    1. qrKot
                      31.08.2018 22:03

                      Прямо в этом сценарии:
                      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 версиях — так себе удовольствие.


                      1. gecube
                        31.08.2018 22:16

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

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


                      1. GerrAlt
                        31.08.2018 23:04

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

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

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


                    1. qrKot
                      31.08.2018 22:10

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


                      1. gecube
                        31.08.2018 22:20

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


                  1. gecube
                    31.08.2018 22:22

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

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


                    1. VolCh
                      31.08.2018 23:54

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


  1. gecube
    30.08.2018 19:04

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


    1. gecube
      30.08.2018 19:06

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


  1. isden
    30.08.2018 19:31
    +1

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


    1. romangoward
      31.08.2018 04:34

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


      1. isden
        31.08.2018 09:38

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


        1. romangoward
          01.09.2018 00:21

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


          1. isden
            01.09.2018 00:30

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

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

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

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


      1. qrKot
        31.08.2018 12:05

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


  1. gecube
    31.08.2018 18:23

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


    1. VolCh
      01.09.2018 00:01

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


      1. gecube
        01.09.2018 11:39

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


        1. VolCh
          02.09.2018 00:05

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

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