Как понять, что вам нужен Docker, а не VM? Нужно определить, что именно вы хотите изолировать. Если требуется изолировать систему с гарантированно выделенными ресурсами и виртуальным аппаратным обеспечение, тогда выбор должен пасть на VM. При необходимости изолировать работающие приложения как отдельные процессы системы, вам потребуется Docker.
Так в чём же отличие Docker-контейнеров от VM?
Виртуальная машина (VM) — это виртуальный компьютер со всеми виртуальными устройствами и виртуальным жёстким диском, на который и устанавливается новая независимая ОС вместе с виртуальными драйверами устройств, управлением памятью и другими компонентами. Т. е. мы получаем абстракцию физического оборудования, позволяющую запускать на одном компьютере множество виртуальных компьютеров.
Установленная VM может по-разному занимать место на диске компьютера:
- фиксированное место на жёстком диске, что позволяет осуществлять более быстрый доступ к виртуальному жёсткому диску и позволяет избежать фрагментации файла;
- динамическое выделение памяти. При установке дополнительных приложений память будет динамически выделяться под них, пока не достигнет максимального объема, отведенного ей.
Чем больше виртуальных машин на сервер, тем больше места они занимают, а также требуют постоянной поддержки окружения, требующегося для работы вашего приложения.
Docker — это ПО для создания приложений на основе контейнеров. Контейнеры и виртуальные машины имеют схожие преимущества, но работают по-разному. Контейнеры занимают меньше места, т.к. переиспользуют большее количество общих ресурсов хост-системы чем VM, т.к. в отличие от VM, обеспечивает виртуализацию на уровне ОС, а не аппаратного обеспечение. Такой подход обеспечивает меньший объем занимаемой памяти, быстрое развертывание и более простое масштабирование.
Контейнер даёт более эффективный механизм инкапсуляции приложений, обеспечивая необходимые интерфейсы хост-системы. Данная возможность позволяет контейнерам разделить ядро системы, где каждый из контейнеров работает как отдельный процесс основной ОС, у которого есть свой собственный набор областей памяти (собственное виртуальное адресное пространство). Так как виртуальное адресное пространство каждого контейнера является собственным, то данные, принадлежащие разным областям памяти, не могут быть изменены.
Нативной ОС для Docker является Linux (Docker можно использовать также и на Windows, и на MacOS), он использует её основные преимущества, которые и позволяют ему организовать разделение ядра. Запуск Docker-контейнеров на Windows будет происходить внутри виртуальной машины с ОС Linux, т.к. контейнеры разделяют ОС хост-системы и основной ОС для них является Linux.
Контейнер — как это работает?
Контейнер — это абстракция на уровне приложения, объединяющая код и зависимости. Контейнеры всегда создаются из образов, добавляя доступный для записи верхний слой и инициализирует различные параметры. Т. к. контейнер имеет свой собственный слой для записи и все изменения сохраняются в этом слое, несколько контейнеров могут совместно использовать доступ к одному и тому же основному образу.
Каждый контейнер можно настроить через файл в проекте docker-compose, включенного в основное решение — docker-compose.yml. Там можно задать различные параметры такие как имя контейнера, порты, идентификаторы, лимиты ресурсов, зависимости между другими контейнерами. Если в настройках не задавать имя контейнера, то Docker каждый раз будет создавать новый контейнер, присваивая ему имя случайным образом.
Когда контейнер запускается из образа, Docker монтирует файловую систему для чтения и записи поверх любых слоев ниже. Именно здесь будут выполняться все процессы, которые мы хотим, чтобы наш контейнер Docker выполнял.
Когда Docker впервые запускает контейнер, начальный слой чтения-записи пуст. Когда происходят изменения, они применяются к этому слою; например, если вы хотите изменить файл, этот файл будет скопирован из слоя только для чтения ниже в слой для чтения и записи.
Версия файла, доступная только для чтения, все еще будет существовать, но теперь она скрыта под копией. Для хранения данных, независимо от жизненного цикла контейнера, используются тома. Тома инициализируются при создании контейнера.
Как образ связан с контейнером?
Образ — основной элемент для каждого контейнера. Образ создаётся из Dockerfile, добавленного в проект и представляет собой набор файловых систем (слоёв) наслоённых друг на друга и сгруппированных вместе, доступных только для чтения; максимальное число слоёв равно 127.
В основе каждого образа находится базовый образ, который указывается командой FROM — входная точка при формировании образа Dockerfile. Каждый слой является readonly-слоем и представлен одной командой, модифицирующей файловую систему, записанной в Dockerfile.
Для сочетания этих слоёв в один образ Docker использует Advanced multi layered Union file system (AuFS построена на базе UnionFS), позволяя разным файлам и директориям из разных файловых слоёв прозрачно накладываться, создавая связанную файловую систему.
Слои содержат метаданные, позволяющие сохранять сопутствующую информацию о каждом слое во время выполнения и сборки. Каждый слой содержит ссылку на следующий слой, если слой не имеет ссылки, значит это самый верхний слой в образе.
Dockerfile может содержать такие команды как:
- FROM — входная точка при формировании образа;
- MAINTAINER — имя владельца образа;
- RUN — выполнения команды в ходе сборки образа;
- ADD — копирование файла хоста в новый образ, если указать URL-файла, Docker загрузит его в заданную директорию;
- ENV — переменные среды;
- CMD — запускает создание нового контейнера на основе образа;
- ENTRYPOINT — команда выполняется при запуске контейнера.
- WORKDIR — рабочий каталог для выполнения команды CMD.
- USER — устанавливает UID для создаваемого на основе образа контейнера.
- VOLUME — монтирует директорию хоста в контейнер.
- EXPOSE — набор прослушиваемых в контейнере портов.
Как работает UnionFS?
UnionFS — служебная стэковая файловая система (ФС) для Linux и FreeBSD. Данная ФС реализует механизм копирования при записи (Copy-On-Write, COW). Рабочей единицей UnionFS является слой, каждый слой следует рассматривать как отдельную полноценную файловую систему с иерархией директорий от самого корня. UnionFS создаёт объединенное монтирование для других файловых систем и позволяет прозрачно для пользователя объединять файлы и каталоги различных файловых систем (называемых ветвями) в единую связанную файловую систему.
Содержимое каталогов с одинаковыми путями будет отображаться вместе в одном объединенном каталоге (в едином пространстве имён) полученной файловой системы.
UnionFS объединяет слои, руководствуясь следующими принципами:
- один из слоёв становится слоем верхнего уровня, второй и последующие – слоями нижнего уровня;
- пользователю объекты слоёв доступны «сверху вниз», т.е. если запрошенный объект есть в «верхнем» слое, возвращается он, независимо от наличия объекта с таким именем в «нижнем» слое; иначе возвращается объект «нижнего» слоя; если запрошенного объекта нет ни там, ни там, возвращается ошибка «Нет такого файла или каталога»;
- рабочим слоем является «верхний», то есть все действия пользователя по изменению данных отражаются только на слое верхнего уровня, не влияя на содержимое слоёв нижних уровней.
Docker наиболее распространенная технология использования контейнеров в работе приложения. Он стал стандартом в этой области, строясь на основе cgroups и пространстве имён, которые обеспечивает ядро Linux.
Docker позволяет нам быстро разворачивать приложения и максимально оптимально использовать файловую систему за счет разделения ядра ОС между всеми контейнерами, работая как отдельные процессы ОС.
Комментарии (77)
vodopad
31.10.2019 20:48Статья называется «VM или Docker?», но основное внимание уделено уже деталям Docker. По заголовку ожидал другое от статьи. Статья не даёт ответа на вопрос из заголовка.
Но за старания спасибо.GDI89 Автор
01.11.2019 21:39Спасибо большое за комментарий, учту в следующих статьях. Надеюсь, было интересно.
AlexanderS
01.11.2019 22:46Предлагаю ещё осветить следующий вопрос.
VM гарантирует программную независимость. Это значит, что я могу развернут виртуальную машину на любом железе и на любой ОС и внутри неё будет всё работать как надо. Причем больше ничего не нужно — нужно просто запустить VM и настроить интерфейс с ней (общие папки, порты настроить).
А что гарантирует докер? Вот есть у меня контейнер веб-сервера. И две ОС — дебиан и windows 10. Почему и за счёт чего гарантируется работа контейнера? Что происходить после разворачивания образа?Sly_tom_cat
31.10.2019 23:29-7VM гарантирует программную независимость.… запустить VM и настроить интерфейс с ней (общие папки, порты настроить).
То же самое гарантирует и докер (и с папками портами — все тоже), но только гораздо дешевле.
Считайте, что докер просто легкая VM с Linux на борту. Все что можно сделать с VM вы можете сделать и с докером.ProFfeSsoRr
03.11.2019 08:44+1Считайте, что докер просто легкая VM с Linux на борту
Не стоит так считать, пусть даже для упрощенных объяснений — не стоит всё равно. Особенно если речь про запуск разных операционок — просто так контейнер с линуксом в винде не запустить, сначала придется запустить виртуалку с ядром линукса, которое уже сможет внутри создать все условия для запуска контейнеров.
kasthack_phoenix
01.11.2019 00:04-1А что гарантирует докер?
Побайтовые копии окружений, где будет выполняться докеризованное приложение.
Вот есть у меня контейнер веб-сервера. И две ОС — дебиан и windows 10.
Во-первых, linux-контейнер на windows хосте будет прозрачно завёрнут в Hyper-V VM с Moby Linux.
Почему и за счёт чего гарантируется работа контейнера?
- Всё окружение побайтово то же, что на dev-машине — в этом суть образов.
- Сисколлы, доступные изнутри, стабильны что в linux, что в win-контейнерах.
VolCh
01.11.2019 07:21Ядро же не войдёт в окружение. Если требуется специфичная версия ядра приложению…
gecube
01.11.2019 15:56Насчёт виртуалки — при запуске на другой архитектуре процессора могут быть нюансы. Могут быть нюансы при смене типа гипервизора. Но, в целом, да — за исключением вопроса производительности и драйверов, виртуалка переедет и запустится.
bgnx
31.10.2019 23:53+5А я вот не понимаю зачем нужен докер. Сейчас большинство хостеров и так используют kvm для виртуализации и разделения ресурсов, так зачем внутри такой vm которая предоставляется клиенту нужна еще одна абстракция для разделения ресурсов? Почему нельзя взять код сервера и необходимые зависимости (обычно это ядро линукса + код бэка, то есть никакого ненужного и предустановленного софта в виде различных linux дистрибутивов, даже busybox и ssh-сервер с таким подходом будет не нужен) и запаковать его в виде образа vm (обычно это iso-файл) и загрузить через апи хостера как kvm-образ и запустить как обычный сервер. Таким образом получаем все те же плюсы что у докера, но главное — мы избавляемся от лишнего программного слоя и получаем меньшую воронку для уязвимостей поскольку на сервере не будет ничего лишнего (не будет даже открытого ssh-порта так как деплой будет происходить снаружи)
kasthack_phoenix
01.11.2019 00:17-1А я вот не понимаю зачем нужен докер.
Способ простого развёртывания софта с минимальным оверхедом.
Почему нельзя взять код сервера и необходимые зависимости (обычно это ядро линукса + код бэка, то есть никакого ненужного и предустановленного софта в виде различных linux дистрибутивов, даже busybox и ssh-сервер с таким подходом будет ненужен) и запаковать его в виде образа vm (обычно это iso-файл) и загрузить через апи хостера как kvm-образ и запустить как обычный сервер.
В kvm уже layers завезли? У нас миграцияи сборка всех образов на следующий релиз .net core свелась к изменению переменной в .env — дальше CI пересобрал все образы из compose, просто вызвав
docker-compose build
и запушил их все с новым тегом тоже в одну строку, который подставил нужную версию вFROM mcr.microsoft.com/dotnet/core/sdk:{TARGET_FRAMEWORK}
. Размер образов свёлся к одному базовому слою и по нескольку мегабайт на каждый сервис. Я не очень представляю объём работы, который нужно сделать, чтобы протестировать и собрать такие же образы на kvm, но есть подозрение, что это несколько сложнее, а про дедупликацию можно и не думать.bgnx
01.11.2019 00:46+3А чем же миграция через сборку нового iso-образа вместе запуском нужного кода в качестве init-а (pid 1) будет отличаться от сборки такого же docker-контейнера где будет минимум ненужного софта (FROM scratch + статически собранные бинарники, либо только самое необходимое)? Как по мне отличий практически нет — iso-образы наверняка точно также можно собирать инкрементально, деплой и миграцию также можно автоматизировать.
xkondorx
01.11.2019 08:31+2Я бы с удовольствием прочитал статью о том, как выполнять «фишки» докера, на KVM. С докером все понятно, есть довольно простой язык описания контейнеров и неплохая документация. Но ничего подобного для KVM я не встречал (ну не сильно и искал). Если с помощью KVM можно без проблем собрать образ виртуалки, поместить в нее приложение и запустить, было бы неплохо узнать об этом подробнее. Не увидел в комментариях упоминания о использовании ресурсов, виртуалка вроде как потребляет больше ресурсов чем контейнер, и для одного единственного приложения (микросервиса) это такое себе решение. Другой вопрос если иметь для KVM такой-же репозиторий образов который есть у docker. В общем с нетерпением жду статью с таким сравнением.
gecube
01.11.2019 16:00Ресурсы — как правило не проблема. Понятно, что для статического сайтика, завернутого в докер, оверхед от ещё одной копии ОСи будет больше, но это разговоры из серии "вам шашечки или ехать" — может вообще не стоило пытаться самому разворачивать хостинг тогда, а взять готовое SaaS решение? Нужно инструмент выбирать под задачу, а не наоборот.
Касательно уплотнения ресурсов. Ну, да, докер поможет. Но обратная сторона — а как же стабильность? Не боитесь огрести от того, что ядро общее и некоторые ресурсы ядра не изолируются? В случае если говорим про кубернетИс, то давайте говорить про него, а не про докер. Тем более, что рантаймы в к8с меняются. И, да, он умеет управлять виртуалками тоже (!!!!)
По сборке для квм — смотрите в сторону hashicorp packer. Можно собирать готовые образа вм под облачные платформы и все основные гипервизоры.
xkondorx
01.11.2019 16:13Ну вот сценарий. У нас есть браузерная игра, игроки по всему миру. У игры есть getaway, балансировщик, штук 15 микросервисов, шардированная база данных (не важно сколько), ну и сервер очередей, пусть RabbitMQ. Надо при всплеске активности игроков в другой части земного шара, поднять кластер локационно ближе к ним. Оркестратор поверх докера позволит это сделать довольно быстро, особенно если уже есть подготовленные машины под контейнеры. При этом поднять столько нод, сколько нужно, глушить и поднимать их в зависимости от загрузки. Сколько времени по сравнению с контейнером потребуется одной виртуальной машине на запуск, сколько данных нужно перекинуть в нужный ЦОД для развертывания? Как только в одной части земли наступает ночь, в другой начинается день, и мы кидаем ресурсы в эту часть земли тратя деньги в тех ЦОД в которых нужно. Если этот сервер заточен под docker у него есть локальный репозиторий контейнеров, нам нужно только подтянуть наше приложение.
gecube
01.11.2019 16:17Это нечестно. У вас предаллоцированные ресурсы. Если вы упретесь в количество нод и все равно придется провижионить новые, то это будет от дней (баре метал) до минут (облако) и все равно спайк вы пропустите. В этом отношении — докер поможет, но за счёт того, что у вас есть резерв в кластере прямо сейчас. Читай — недоутилизированные ресурсы, за которые вы платите. И, да, в принципе, с тем же успехом можно и без докера — больше вопрос выбора оркестратора, который сможет запускать приложение в виде дополнительных реплик.
И, повторюсь опять, если требуется поднимать сами ноды (ВМ) — то из готовых образов со всем необходимым они даже подниматься будут быстрее, чем с докером, т.к. ему ещё имиджи надо стянуть с софтом… Но это больше вопрос первого, "холодного" старта
xkondorx
01.11.2019 16:29Как вариант, это балансировать нагрузку внутри KVM глуша и поднимая контейнеры. Допустим если мы размещаем на VM не кластер приложения, а отдельный пулл нод (есть не нагруженные сервисы например регистрация, а есть обработчики событий). Мы можем более тонко распределять нагрузку по нашим ограниченным ресурсам (не представляю правда когда это может понадобиться, но если случится «датапокалипсис» и всем не хватит железа… :D). При этом мы не трогаем конфигурацию наших виртуалок и всегда и везде используем один единственный стартовый снапшот для запуска.Тогда удастся выиграть пару минут для запуска дополнительных ресурсов. Идея в том, чтобы пережить непредусмотренный пик нагрузки.
VolCh
01.11.2019 07:23+1Про дедупликацию для виртуалок что-то было в недавней статье про CoW файловые системы
bgnx
01.11.2019 00:51+2Пожалую попробую прояснить подробней — суть не в том чтобы юзать kvm вместо докера — тут суть в том чтобы избавиться от лишнего программного слоя. Сейчас когда заказываем машинку у хостера (vps или различные облачные решения) то вместо целой физической машинки получаем лишь запущенный образ виртуальной машины с другими такими же соседями.
И дальше поверх этой запущенной машины мы добавляем еще один программный слой в виде докера для еще одной изоляции. И появляется вопрос — почему нельзя точно также как с докером собрать весь код, зависимости и окружение вместе в виде некого контейнера но только без докера? То есть это будет не контейнер (который будет запускаться внутри виртуальной машины которую нам предоставил хостер) это будет уже сразу готовый iso-образ операционной системы который будет запущен хостером на той виртуальной машине которую мы арендуем.
Уже сейчас многие хостеры предоставляют возможность загрузить кастомные iso-образы — и если можно собрать весь код и деплоить сразу в виде iso-образа то тогда докер становится просто ненужной абстракцией и лишним программным слоемilyapirogov
01.11.2019 03:05-3- А если у вас 40 контейнеров, то вы будете 40 VPS заказывать? А если их автоматом нужно запускать/останавливать?
- Как уже отметили выше, как жить без слоев? Каждый релиз закачивать гигабайтные ISO?
- Так же не понятно как обеспечивать взаимодействие контейнеров: как создавать виртуальные сети, маппить порты, задавать переменные окружения?
- Следующая проблема — единный API. Предположим, что хостер предоставил вам API для загрузки образов. Что делать, если вам надо переехать к другому хостеру, у которого совершенно другое API? Переписывать все? И что делать разработчикам, чтобы развернуть образ локально? Настраивать и запускать все ручками?
Этот список проблем, которые решает докер, можно продолжать еще долго.
gecube
01.11.2019 16:04Слои — не панацея. Даже правильное их расположение не решает проблему, когда по факту нужно "ромбической наследование" слоев. А оно, между прочим оказывается нужно достаточно часто. И я даже не знаю — благо ли это, что его нет в докере или нет. Т.к. наследование ромбиком это всегда путь отстрелить себе ногу (например, в обоих родительских образах есть одинаковые каталоги-файлы по имени, но разные по содержимому). Лучше бы diff докачивался не послойно, а пофайлово. Ей-Богу.
Так же не понятно как обеспечивать взаимодействие контейнеров: как создавать виртуальные сети, маппить порты, задавать переменные окружения?
Переоцениваете важность и нужность виртсетей. Зачастую лучше вообще избегать докер-сетей. Сложно. Вносят penalty при сетевом взаимодействии. И пр
ilyapirogov
01.11.2019 18:04Разумеется, это не панацея. Но это лучше, чем монолит. Или, упомянутые выше, ISO для VPS не являются монолитом?
Переоцениваете важность и нужность виртсетей. Зачастую лучше вообще избегать докер-сетей. Сложно. Вносят penalty при сетевом взаимодействии.
Не всегда же требуется максимально возможная производительность от сетевой подсистемы, тем более в случае когда проект размещается на VPS. И потом, основной вопрос был: как конфигурировать эти ISO?
PS Не совсем понятно к чему относились минусы. Разве на эти вопросы есть ответы у данного абстрактного хостера? Или они не имеют никакой значимости?
Хорошо, давайте возьмем конкретного хостера: Amazon Web Services. У них есть все это с незапамятных времен, когда докера еще и в помине не было. И образы в виде "ISO", и обширный API, и всякие Cloud Formation для автоматизации деплоя, и много прочего. Заменяет ли он все плюсы докера и решает ли все выше обозначенные проблемы?
gecube
01.11.2019 18:12Но это лучше, чем монолит
Хороший маленький монолит лучше, чем плохая распределённая сеть из микросервисов. Не так ли ?
Или, упомянутые выше, ISO для VPS не являются монолитом?
Вы прицепились к двум вещам. Причем неверным. Не iso — это сказал коллега. И это только один из способов. Те же AMI у Амазона более подобны "золотым образам" жёсткого диска. И по AMIшкам я ответил — можно их готовить HashiCorp Packer. Не нравится? Ну, давайте попробуем подобрать другой тулинг.
Во-вторых, VPS вызывает неверные (или Вы специально в это русло утаскивает?) ассоциации с маленькими провайдерами типа ТаймВеб, Beget, hetzner отчасти и пр. — которые дают отдельные ВМ, вместо того, чтобы предоставлять инфру. Как бы есть небольшая разница между непонятной vps у непонятного провайдера и EC2/Compute Engine в облаке с нормальным API?
Заменяет ли он все плюсы докера и решает ли все выше обозначенные проблемы?
Если говорить за разработчика — он хочет Хероку. Вы ведь наверняка его видели? Как локальный вариант — есть dokku. Но это абстракция более высокого уровня, чем докер...
ilyapirogov
01.11.2019 18:58Хороший маленький монолит лучше, чем плохая распределённая сеть из микросервисов. Не так ли ?
Я рассуждал именно в разрезе микросервисов. Иначе нужно было бы ставить вопрос не VPS vs Docker, а именно Монолит vs Микросервисы.
Да, я согласен, что бывают ситуации, когда монолит лучше, микросервисов. Но бывают задачи, когда именно микросервисы лучше решают проблему. И именно в этом контексте я и рассуждал.
И по AMIшкам я ответил — можно их готовить HashiCorp Packer. Не нравится? Ну, давайте попробуем подобрать другой тулинг.
Т.е. вы имеете ввиду, что можно взять нейкий тулкит и при помощи него делать более менее схожие многослойные (ромбические?) образы для того же AWS EC2? Видимо, я не сразу понял о чем речь.
Это интересная мысль, но остается проблема с репозиторием. В случае кастомных тулкитов придется размещать этот репозиторий где-то отдельно, ведь вряд-ли они предоставляют такой же сервис как и Docker Hub?
Во-вторых, VPS вызывает неверные (или Вы специально в это русло утаскивает?) ассоциации с маленькими провайдерами типа ТаймВеб, Beget, hetzner
Да, именно такое впечатление у меня и осталось от комментария bgnx.
Как бы есть небольшая разница между непонятной vps у непонятного провайдера и EC2/Compute Engine в облаке с нормальным API?
Именно так. Хорошо, если вопрос стоит как "Почему не использовать AWS/Azure/Google Cloud вместо Docker", то это немного меняет дело. Но у меня, как разработчика, все еще остаются некоторые вопросы:
- Например как запустить AMI контейнер у себя локально? Когда я работал с EC2, то не находил подобной возможности. Можно ли это сделать сейчас?
- Все та же проблема с взаимодействием контейнеров, в случае если я все же пишу микросервисы, а не монолит.
- Еще одна проблема в том, что AMI поднимаются безумно медленно. Это будет особенно мешать, если надо обновлять контейнеры часто.
- И опять же, что делать, если амазон завтра скажет, например, что больше не работает с Россией и нужно срочно переносить все другому хостеру. Как же тут быть? В случае с докером такой проблемы нету.
Если говорить за разработчика — он хочет Хероку. Вы ведь наверняка его видели? Как локальный вариант — есть dokku. Но это абстракция более высокого уровня, чем докер...
Тут именно проблема в абстракции более высокого уровня. Например, мои текущие задачи никак не вписываются в возможности Heroku
farcaller
01.11.2019 11:06+1Уже сейчас многие хостеры предоставляют возможность загрузить кастомные iso-образы — и если можно собрать весь код и деплоить сразу в виде iso-образа то тогда докер становится просто ненужной абстракцией и лишним программным слоем
Я в GCP видел возможность деплоить контейнер как VM (ЕМНИП там просто прозрасно для пользователя ContainerOS стартует).
Почему же люди бегут с VM в докер?
Я думаю, что основная причина: дешевизна. Докер (lxc/containerd) дешевле. На одну физическую машину можно упаковать больше контейнеров, проще разделять процессорное время/память.
В целом, популярные оркестраторы (k8s) умеют управлять полезной нагрузкой независимо от того, это VM или контейнер. Для тех пользователей, которым надо запускать нагрузку "ближе к железу" это решает все проблемы управления.
ProFfeSsoRr
03.11.2019 08:57+1И появляется вопрос — почему нельзя
А почему нельзя? Можно, так и делали до появления контейнеров. Хотите — продолжайте так делать и дальше.
werevolff
01.11.2019 04:54+1- Развёртывание докер контейнеров уже стандартизировано готовыми системами оркестрации. Нет нужды писать что-то своё.
- Эти системы оркестрации умеют из коробки делать всё необходимое для обеспечения связи между контейнерами, а также, для автоматического перезапуска, распределения нагрузки, ограничения доступа и т.д.
- Контейнер докера легковесный. Существующие образы содержат только самое необходимое для работы одного приложения. Докер — не полноценная виртуалка. Скорее, это эмулятор операционной системы.
- Как уже отмечалось в комментах, сборка контейнера, зачастую, стандартизирована под изменение одного файла конфигурации. Этот файл определяет поведение контейнера на разных машинах.
- Докер — мультиплатформенный. Даже дизайнер, имея самые общие представления о работе контейнеров, может поставить себе докер и запустить проект.
gecube
01.11.2019 16:08+1Контейнер докера легковесный. Существующие образы содержат только самое необходимое для работы одного приложения. Докер — не полноценная виртуалка. Скорее, это эмулятор операционной системы.
К сожалению, это полуправда. Дело в том, что большинство образов на докерхаб содержат избыточные компоненты. Вот глядишь и понимаешь, что чтобы это заработало — надо все переписать на golang'е, компилировать в статический бинарь и именно его уже класть в FROM: scratch
Тогда заживём. А пока мусора в образах больше, чем полезной нагрузки...
Докер — мультиплатформенный. Даже дизайнер, имея самые общие представления о работе контейнеров, может поставить себе докер и запустить проект.
К сожалению, если он не сидит под линуксом, то его может очень быстро настигнуть разочаровании в докере. В маке и под виндой докер работает через выделенную вм, а это означает сразу более низкую производительность. В первую очередь — по дисковым операциям. Отчасти проблему решает docker-sync
А ещё сетевое взаимодействие становится сложнее.CrzyDocTI
01.11.2019 16:15-1А пока мусора в образах больше, чем полезной нагрузки
Довольно часто, но в разработке можно и с мусором пожить, а на прод собрать что надо.
К сожалению, если он не сидит пол линуксом, то его может очень быстро настигнуть разочаровании в докере.
Ну, если разработчик умеет только счетами пользоваться — его тоже постигнет разочарование=) Пора бы уже Linux как стандарт воспринимать и знать как таблицу умножения.gecube
01.11.2019 16:32Довольно часто, но в разработке можно и с мусором пожить, а на прод собрать что надо.
Можно, но набегут сторонники того, что в тесте и в проде должны быть идентичные образы (в разработке — по ВОЗМОЖНОСТИ — тоже)
Пора бы уже Linux как стандарт воспринимать и знать как таблицу умножения.
Бородатые админы и разработчики под Виндовс… даже не знаю… плачут или смеются....
dimonuch
01.11.2019 17:02В маке и под виндой докер работает через выделенную вм, а это означает сразу более низкую производительность.
под Вин Докер уже научился использовать Windows Containers, естественно «там где оно есть». Майкрософт за тему с Докером серьезно взялись.gecube
01.11.2019 17:16К сожалению, тут у меня пробел, но насколько мне известно — windows containers позволяют запускать только Вин-приложения, но не линукс-контейнеры… Так что универсальностью тут и не пахнет.
ilyapirogov
01.11.2019 18:20+1Да, Linux контейнеры под Windows все еще используют Hyper-V, но могут работать в двух разных режимах:
- Когда докер запущен в полноценной виртуальной Linux машине.
- Сам докер запущен на Windows хосте, а каждый Linux контейнер является оптимизированной виртуальной машиной с собственным ядром.
Вот тут есть более подробная информация об этом: https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/linux-containers
VolCh
01.11.2019 17:44Дело в том, что большинство образов на докерхаб содержат избыточные компоненты. Вот глядишь и понимаешь, что чтобы это заработало — надо все переписать на golang'е, компилировать в статический бинарь и именно его уже класть в FROM: scratch
Всё же не путайте мусор, который остаётся от, скажем так, не экономной сборки образа (билд депенденси и артефакты, например) и рантайм для приложения на конкретном стэке. Я даже не уверен, что для Go FROM: scratch должно быть по умолчанию, а не только для специфических случаев
gecube
01.11.2019 17:47Мысль свою разверните. И, да, я не путаю. Потому что у Вас в стандартном докере бежит стандартная… Дистрибьюция линукса. Со стандартным пакетным менеджером. И делая apt install Вы туда тащите кучу всего. Даже не разбираясь нужно оно или нет. Причем. Что интересно. Чем более "жирный" образ — тем меньше желания залезать ему под капот (а получить образ на 3-4 ГиБ с pytorch, cuda etc — легко, хотя это и экстремальный случай)
VolCh
04.11.2019 07:25Я знаю о наличии как FROM scratch, так и образов типа alpine, но предпочитаю FROM ubuntu:bionic-20191029 на сегодняшний день. Может всё, что там в 25 мб есть, приложению и не нужно, но подавляющая часть всего этого нужна разработчикам и эксплуатанционщикам для эффективной работы с образом. Прежде всего bash и apt :) Ну, исхожу из того, что никто не делает образы на базе полноценных установок ubuntu, а используют всё же оптимизированные для докер образы
Я больше о практике, принятой в некоторых официальных образов, типа сделать apt install build-essentials и ко, а после сборки из исходников ничего в образе не чистить.
VolCh
01.11.2019 07:42+1С чисто техникоэкономической точки зрения в докере мы шарим ядро между всеми процессами, что экономит ресурсы. И, насколько я знаю, в виртуалках то ли невозможно, то ли очень сложно динамически перераспределять такие ресурсы как память и процессор между процессами. То есть чем больше процессов, тем больше будет оверхед по ним, если пики использования можно считать несовпадающими. То есть Докер обеспечивает в типовых случаях лучшую утилизацию основных ресурсов (диск, память, процессор).
Ну и субъективно тулинг докера, его экосистема (включая k8s, хотя Докер для него не обязателен) удобнее с точки зрения пользователей (читай — разработчиков, девопосов и админов) и в гораздо большей части FOSS.
ProFfeSsoRr
03.11.2019 08:55А я вот не понимаю зачем нужен докер.
Скажу не конкретно про докер, а в целом про контейнеры. Во-первых — меньше объем (не надо собирать в образ ядро линукса, systemd и прочее, переносится между серверами только приложение и необходимые именно ему библиотеки и конфиги), во-вторых — быстрый старт (контейнер стартует практически мгновенно, виртуалка так быстро не стартует. Единственный гипервизор, который кто-то использует в проде, рассчитанный на быстрый старт — firecracker от Amazon, и он всё равно медленнее контейнера стартует). В-третих — инфраструктура по сборке и деплою. Для виртуалок за все годы существования технологии таких удобных инструментов так и не сделали.gecube
03.11.2019 10:33Насчёт systemd. Его в докер не кладут, а лучше бы клали. Потому что многие не могут декомпозировать софт по разным причинам и сделать контейнер на исполняемый файл. Результат — все равно тащат всякие tini, supervisord в контейнер. И на самом деле это достаточно частая практика.
Даже systemd пинками можно в докер засунуть — это позволяет соблюсти унификацию с дистрибьюциями вне докера, — но при этом это сценарий, который требует много допдействийProFfeSsoRr
04.11.2019 06:10Результат — все равно тащат всякие tini, supervisord в контейнер. И на самом деле это достаточно частая практика.
Имхо вот для таких ситуаций контейнеры и не нужны, а проще с виртуалкой. А вот где получается нормально разделить на контейнеры — там они и раскрываются как удобный, а не костыльный инструмент.
de1m
01.11.2019 00:05+1я бы сказал, что вм надо использовать только там, где нельзя использовать докер. Из опыта могу сказать, что что-то типа файерволла лучше крутить без докера и к примеру rook я бы тоже не стал использовать.
kiba
01.11.2019 03:41Вот эти пункты перепутаны, или я чего-то не понимаю:
FROM — входная точка при формировании образа;
CMD — запускает создание нового контейнера на основе образа;VolCh
01.11.2019 07:45Просто немного странная терминология, но точно не перепутаны, потому что в FROM не упомянут контейнер.
CrzyDocTI
01.11.2019 16:05+1FROM — обязательная инструкция для описания Dockerfile
CMD — необязательная
Фактически контейнер запускает командаdocker run
, но FROM является отправной точкой при чтении dockerfile и создании контейнера.gecube
01.11.2019 16:12Поддержу. Но скорее запуск контейнера триггерит не CMD. А именно вторая инструкция после FROM :-) но это детали реализации. Давайте в них не углубляться. Просто если коллега изначально правильно написал БЫ про ENTRYPOINT + CMD....
CrzyDocTI
01.11.2019 16:20+2А именно вторая инструкция после FROM
Даже если будет одна инструкция FROM — контейнер будет запущен.
VolCh
01.11.2019 17:50При запуске контейнера докерфайл вообще не читается, а запускается то, что было указано в CMD/ENTRYPOINT исходного или родительского Докерфайла, если они вообще использовались при сборке образа. Различные RUN команды, вообще в контейнере не запускаются, если вы их имели ввиду под второй строчкой.
gecube
01.11.2019 17:54Наша дискуссия было про другое, если я уловил мысль — про создание временных контейнеров при docker build. Потом этот временный контейнер commit'ится и получается промежуточный образ.
VolCh
04.11.2019 07:28Я думаю, автор поста о временных контейнерах при docker build в посте вообще не упоминал, кроме как "FROM — входная точка при формировании образа;"
VolCh
01.11.2019 17:47-1При run FROM не читается, более того вообще Докерфайл не читается, ещё более того, Докерфайла в принципе может не быть.
werevolff
01.11.2019 05:12VM и Docker решают разные задачи. VM позволяет держать усебя запущенный экземпляр сервера. Docker предоставляет возможность упаковать приложение вместе со средой исполнения. По сути, Docker контейнер — это экзешник: запустил его, и у тебя поднялся сайт. VM запустил, и у тебя поднялась гостевая операционная система внутри виртуальной машины.
Ничто не мешает запустить Docker внутри VM. По сути, на некоторых VPS это и происходит. Сам VPS с конфигурацией можно копировать в виде VM и развернуть похожую конфигурацию локально.
Docker выгодно отличается от сервера, запущенного в VM тем, что имеет минимальный даунтайм при запуске, поскольку приложение запускается моментально и поставляется в одном пакете со средой исаолнения. А вот деплой на сервере представляет собой многошаговый процесс: поменять конфиги, выполнить команды, перезапустить сервер. С другой стороны, приложение, запущенное в контейнере, будет потреблять больше ресурсов.
VM лучше подходит для доставки приложения участникам разработки, поскольку требует только запустить виртуалку. В случае с Vagrant, сетевое соединение настроится автоматически. Ничего настраивать руками не придётся. Docker потребует от пользователя минимальные навыки администрирования системы оркестрации.VolCh
01.11.2019 07:48+1Хорошо работает доставка VM с установленным и настроенный докером, если требуется что-то сложное. :) Сами же говорите, что они не взаимоисключающие.
werevolff
01.11.2019 08:04Как-правило, доставка образа VM обходится дороже. Дешевле загнать конфигурацию в тот же Ansible и поставлять скрипты отдельно от образа.
Xop
01.11.2019 19:28Хм, а как же packer, terraform и вроде как тенденция к переходу на "иммутабельную" инфраструктуру по возможности? Деплой виртуалок из готовых образов ведь быстрее и надёжнее, чем каждый раз раскатывать конфиг ансиблом на чистой системе, плюс повторяемость..
gecube
01.11.2019 19:56-1Иммутабельная инфраструктура — это очень правильная идея. Но и к нее есть… Темные стороны
- Этот подход нам совершенно не говорит что делать с данными. Круто, когда все стейтлесс. Взял и передеплоил. Но как только нам нужно хранить данные (т.е. чуть более часто, чем всегда) — приходится думать. То ли брать внешнее хранилище (s3? Rds? Managed database?) со всеми его плюсами и недостатками, то ли разрабатывать свое хранилище… И тут начинается.
- IaC на старте очень дорог. Он усложняет процессы, не давая взамен чего-то… Ощутимого. Он хорош, когда реально проект уже зрелый и требует большой инфры. Тогда IaC прекрасен. Тут спору нет.
Xop
02.11.2019 13:08Да, стейтфул — это боль. Еще бОльшая боль — когда у вас bare metal который тоже как-то надо менеджить. В целом именно поэтому AWS и ему подобные успешно предлагают сервисы типа RDS — "мы вам настроим и будем поддерживать stateful сервис, а вы нам просто денежку платите".
Насчет дороговизны IaC на старте — не совсем согласен. Как только у вас появляется хотя бы два окружения (прод и стейджинг), то еще вопрос, что дороже — описать это как IaC, или руками поддерживать одинаковость этих окружений, и периодически при дебаге втыкаться в то, что окружения все-таки разные.
gecube
02.11.2019 18:47+1Ну, попробуйте сделать универсальное IaC для нескольких облаков, а потом поддерживать его в актуальном состоянии. Это правда больно. Если же живёте в рамках какой-то одной среды… Тогда попроще.
И ещё. IaC предполагает, что через месяц, полгода, год ты сможешь все развернуть все в том же виде. Это достижимо, но опять очень много нюансов — за это время могут поменяться API облаков, версии тулинга, да и артефакты вот тех старый версий нужно вытащить из хранилища, т.к. пересобрав их сейчас получишь уже другие версии, которые не факт, что заработают. Для справедливости скажу, что вот такая задача далеко не всегда нужна, т.к. многие SaaS продукты бегут на единственной, текущей версии. И, очевидно, что IaC требует так же, как и код программы, ежедневных практик и подгонки под реальность. Т.е. если его рассматривать именно как способ автоматизации работы и облегчения работы админа/опса/девопса, то все ок
Почему я говорил именно про зрелость проекта — потому что пока идут метания и выбор делать так или иначе, проще руками провести пару экспериментов, чем пытаться переписывать инфраструктурный код.
Xop
02.11.2019 18:56Ну, попробуйте сделать универсальное IaC для нескольких облаков, а потом поддерживать его в актуальном состоянии. Это правда больно.
Охотно верю (сам с таким в проде не сталкивался — используем только AWS). Но подозреваю, что руками это всё поддерживать не менее больно.
werevolff
02.11.2019 03:03-1А что, много хостеров предоставляют возможность развернуться со своего образа? Сейчас для проекта от среднего масштаба и выше выбирается Docker. Образ VM для раскладывания идеально подошёл бы для небольших проектов и средних проектов, поскольку их можно свести в относительный монолит — без обилия мелких микросервисов. Но большинство хостеров, предоставляющих небольшие VDS или облака под эти цели, не предоставляют возможность разложиться со своего образа. А ещё же нужен репозиторий для образа.
Xop
02.11.2019 13:32Но большинство хостеров, предоставляющих небольшие VDS или облака под эти цели, не предоставляют возможность разложиться со своего образа. А ещё же нужен репозиторий для образа.
Это немного не так работает. Большинство облачных провайдеров предоставляют возможность создания снапшотов с виртуалок, и разворачивания новых виртуалок из этих самых снапшотов. Именно это и эксплуатируется пакером — он поднимает виртуалку прямо у вашего облачного провайдера из одного из базовых образов, предоставляемых провайдером, раскатывает туда нужный софт и сохраняет снапшот. Дальше с помощью любого инструмента управления облаком (хоть собственные скрипты, напрямую дергающие REST API, хоть терраформ) из этих снапшотов поднимается нужно количество виртуалок. Загрузка своих образов не нужна. А роль репозитория играет ваш аккаунт у облачного провайдера.
VolCh
04.11.2019 07:40Вот как-то попадались хостеры такие, что со своего образа развернуться можно всегда. До вашего комментария и не подозревал, что есть такие которые не дают этого сделать.
VolCh
04.11.2019 07:38Ну вот не уверен в этом правиле. Даже если не вспоминать о пороге вхождения в создание образов виртуалок и ансибль конфигураций. На моей памяти даже там где ансибль использовался для провижна удаленных докер-нод, попытки его использовать для машин разработчиков и тестировщиков успехом не увенчались, кроме одного случая, инструкция по развертыванию которого начиналсь со слов "установите локально virtualbox и ansible для своей операционной системы"
dimonuch
01.11.2019 09:26+2Почему упомянута UnionFS, разве в Докере не OverlayFS (а ранее AuFS)?
>Данная ФС реализует механизм копирования при записи (Copy-On-Write, COW)
Разве там есть COW? Или имеется ввиду выделение отдельного read-write слоя для «жизни контейнера»?
> т.к. в отличие от VM, виртуализируют ОС, а не аппаратное обеспечение.
мне кажется, формулировка некорректная. Виртуализации там нет. ОСь никто не «виртуализирует», разве что окружение. Ядро и его ресурсы все-равно общие.
>Dockerfile может содержать такие команды как:
описание очень поверхностное. Извините, но вот например это «CMD — запускает создание нового контейнера на основе образа» очень странная формулировка. Директива CMD к «созданию контейнера» отношения не имеет. Про EXPOSE — тоже не совсем корректно, и не указано зачем на самом деле он нужен.
P.S. и, как мне кажется, не освещено главное отличие контейнеров от ВМ — первые выполняются на одном общем ядре ОС, вторые — имеют свои отдельные ядра ОС. Да, это банальщина, я понимаю. Но тут как бы тема статьи такая — про банальные вещи.GDI89 Автор
01.11.2019 09:35-1Добрый день.
Да, в статье действительно допущена неточность. Docker действительно использует AuFS, построенной на базе UnionFs.
Docker реализует механизм COW: если файл или каталог уже существуют на нижнем слое в образе, и другому слою (включая слой для записи) требуется доступ для чтения к нему, он просто использует существующий файл. Если другой слой должен изменить файл при создании образа или запуске контейнера, файл копируется в этот слой и изменяется. Это минимизирует ввод-вывод и размер каждого из последующих слоев.
EXPOSE эта инструкция указывает какой набор портов прослушивает контейнер во время выполнения, вы можете указать будут ли прослушиваться порты по UDP или TCP, по умолчанию установлен TCP.gecube
01.11.2019 16:14Aufs уже в новых дистрибутивах не используют. Там overlay2. По сути для пользователя то же самое
GDI89 Автор
01.11.2019 16:34Да, но там есть некоторые ограничения:
aufs рекомендуется использовать, если у вас Docker 18.06 или старше, когда используется Ubuntu 14.04 (kernel 3.13), которые не поддерживают overlay2.gecube
01.11.2019 16:41Вы сами-то такие старые сервера видели? Если да, то пора бы их уже обновлять.
Касательно centos — там вообще по умолчанию до последнего времени был devicemapper и ничего… как-то жили..
если у вас Docker 18.06 или старше
старше — в смысле новее версия или более ранняя? Я бы рекомендовал выражать свои мысли точнее ) Ну, и в 18.06, по-моему, overlay уже нормально работал.
dimonuch
01.11.2019 16:53+1EXPOSE эта инструкция указывает какой набор портов прослушивает контейнер во время выполнения
Не совсем так. Это лишь декларация типа «возможно, что что-то внутри контейнера будет слушать указанный порт». Не более того. EXPOSE может вообще отсутствовать в Dockerfile, что никак не помешает сетевому взаимодействию с контейнером из этого образа.
Единственное на что эта директива влияет, это на запуск контейнера через docker run с ключом -P. Тогда Докер автоматом прокинет указанные в EXPOSE порты на 0.0.0.0
Я почему акцентирую на этом внимание — изначально, изучая Докер, назначение и суть EXPOSE я понял «только с третьей попытки». Ибо в документации и разных статьях оно было описано невнятно.
ZaitsXL
01.11.2019 17:03Почему то большинство комментов тут с точки зрения использования у хостинг-провайдеров. Все же в курсе что виртуалки можно использовать не только так? :) Для VPS докер действительно не вариант.
Щас напишу одной строчкой зачем нужен докер: завернуть приложение вместе с его окружением в одну сущность (образ) с минимумом лишнего хлама. Тут писали что дескать на докерхабе большинство образов неоправданно велики потому что внутри много ненужного. Так это разве проблема докера как технологии? Или может это кривыми руками образы собирали? Качайте только официальные образы, там обычно все нормgecube
01.11.2019 17:19Качайте только официальные образы, там обычно все норм
У официальных образов другие проблемы есть. Например, достаточно ограниченный набор "ручек" для настройки, спорные дефолты. Поэтому набирают силу и клиентскую массу альтернативные образы — например, от bitnami, которые позволяют согласно 12-factor передавать все или хотя бы бОльшую часть ключей через переменные окружения.
завернуть приложение вместе с его окружением в одну сущность (образ) с минимумом лишнего хлама.
К сожалению, разрабы думают про это обратное — для них докер удобный способ замести весь мусор (в случае языков вроде python, js@node.js, ruby и пр.) в контейнер и больше об этом не думать. Не мешает? Ну, и ладно.
Т.е. если речь про тестирование/разработку — к докеру по сути-то вопросов особо и не возникает. ) Удобно. Быстро. Как правило — не вызывает особой головной боли. Но не нужно из него делать… универсальное решение всех проблем.
AlePil
С докером я бы сравнивал не VM, а LXC/LXD, оно как то ближе чем VM.
VolCh
Ближе по каким метриками? По популярности ближе? :)
13werwolf13
Контейнер ближе к контейнеру чем к виртуалке, всё правильно.
А популярность не показатель. Лохер очень популярен но это же не повод его в прод тащить.
VolCh
Я про то, что сравнивать можно не по технической близости, а по тому как, что и для чего используется.
AlePil
И? LXC используется и как докер, для отдельных приложений, так и для развертывания оперативных систем и приложений уже в них…
VolCh
Как популярны эти виды использования? Сколько процентов админов или разработчиков вспомнят об этой опции, когда им поставят задачу как-то упорядочить и стандартизировать развёртывание, например, сложных многокомпонентных систем как локально у разработчиков и тестировщиков, так и на удаленных окружениях?
akdes
Я считаю, что сравнение правильное, т.к. люди не знакомые с докером, сравнивают его именно с вм