Чем Docker отличается от виртуальной машины?
Я продолжаю перечитывать документацию Docker, чтобы попытаться понять разницу между Docker и полной виртуальной машиной. Как ему удается обеспечить полную файловую систему, изолированную сетевую среду и т. Д., Не будучи таким тяжелым?
Почему развертывание программного обеспечения в образ Docker (если это правильный термин) проще, чем простое развертывание в согласованной рабочей среде?
24 ответа
Изначально Docker использовал контейнеры LinuX (LXC), но позже переключился на runC (ранее известный как libcontainer), который работает в той же операционной системе, что и его хост. Это позволяет ему совместно использовать много ресурсов операционной системы хоста. Кроме того, он использует многоуровневую файловую систему ( AuFS) и управляет сетью.
AuFS - это многоуровневая файловая система, поэтому вы можете иметь часть только для чтения и часть записи, которые объединяются вместе. Можно иметь общие части операционной системы только для чтения (и совместно использовать их для всех ваших контейнеров), а затем дать каждому контейнеру собственное монтирование для записи.
Итак, предположим, у вас есть изображение контейнера 1 ГБ; если вы хотите использовать полную виртуальную машину, вам потребуется 1 ГБ, умноженное на количество требуемых виртуальных машин. С Docker и AuFS вы можете разделить большую часть 1 ГБ между всеми контейнерами, и если у вас есть 1000 контейнеров, у вас все еще может быть только чуть более 1 ГБ пространства для ОС контейнеров (при условии, что все они работают под одним и тем же образом ОС),
Полностью виртуализированная система получает свой собственный набор ресурсов, выделенных для нее, и осуществляет минимальное совместное использование. Вы получаете больше изоляции, но она намного тяжелее (требует больше ресурсов). С Docker вы получаете меньшую изоляцию, но контейнеры легки (требуют меньше ресурсов). Таким образом, вы можете легко запустить тысячи контейнеров на хосте, и он даже не будет мигать. Попробуйте сделать это с Xen, и если у вас нет действительно большого хоста, я не думаю, что это возможно.
Полностью виртуализированная система обычно запускается за несколько минут, тогда как контейнеры Docker/LXC/runC занимают секунды, а часто даже меньше секунды.
Есть плюсы и минусы для каждого типа виртуализированной системы. Если вам нужна полная изоляция с гарантированными ресурсами, лучше использовать полную виртуальную машину. Если вы просто хотите изолировать процессы друг от друга и хотите запустить тонну из них на хосте разумного размера, то, похоже, вам подойдет Docker/LXC/runC.
Для получения дополнительной информации, посмотрите этот набор постов в блоге, которые хорошо объясняют, как работает LXC.
Почему развертывание программного обеспечения в образ докера (если это правильный термин) проще, чем простое развертывание в согласованной рабочей среде?
Развертывание согласованной производственной среды легче сказать, чем сделать. Даже если вы используете такие инструменты, как Chef и Puppet, всегда есть обновления ОС и другие вещи, которые меняются между хостами и средами.
Docker дает вам возможность делать снимок ОС в общем образе и упрощает развертывание на других хостах Docker. Локально, dev, qa, prod и т.д.: все одно и то же изображение. Конечно, вы можете сделать это с помощью других инструментов, но не так легко и быстро.
Это отлично подходит для тестирования; Допустим, у вас есть тысячи тестов, которым необходимо подключиться к базе данных, и каждый тест требует первоначальной копии базы данных и внесет изменения в данные. Классический подход к этому состоит в том, чтобы сбрасывать базу данных после каждого теста либо с помощью пользовательского кода, либо с помощью таких инструментов, как Flyway - это может занять очень много времени и означает, что тесты должны выполняться последовательно. Однако с помощью Docker вы можете создать образ вашей базы данных и запустить один экземпляр на тест, а затем запустить все тесты параллельно, поскольку вы знаете, что все они будут работать с одним и тем же снимком базы данных. Поскольку тесты выполняются параллельно и в контейнерах Docker, они могут выполняться одновременно на одном и том же блоке и должны заканчиваться намного быстрее. Попробуйте сделать это с полной виртуальной машиной.
Из комментариев...
Интересно! Полагаю, меня все еще смущает понятие "снимок ОС". Как это сделать, не создавая образ ОС?
Что ж, посмотрим, смогу ли я объяснить. Вы начинаете с базового образа, затем вносите свои изменения и фиксируете эти изменения с помощью Docker, и он создает изображение. Это изображение содержит только отличия от базы. Когда вы хотите запустить ваше изображение, вам также нужна база, и она накладывает ваше изображение поверх базы, используя многоуровневую файловую систему: как упоминалось выше, Docker использует AUFS. AUFS объединяет разные слои, и вы получаете то, что хотите; вам просто нужно запустить его. Вы можете продолжать добавлять все больше и больше изображений (слоев), и он будет продолжать сохранять только различия. Поскольку Docker обычно строится поверх готовых образов из реестра, вам редко приходится "снимать" всю ОС самостоятельно.
Может быть полезно понять, как виртуализация и контейнеры работают на низком уровне. Это многое прояснит.
Примечание: я немного упрощаю описание ниже. Смотрите ссылки для получения дополнительной информации.
Как работает виртуализация на низком уровне?
В этом случае диспетчер виртуальных машин захватывает кольцо ЦП 0 (или "корневой режим" в более новых процессорах) и перехватывает все привилегированные вызовы, сделанные гостевой ОС, чтобы создать иллюзию того, что гостевая ОС имеет собственное оборудование. Интересный факт: до 1998 года считалось невозможным достичь этого в архитектуре x86, потому что не было никакого способа сделать такой перехват. Люди в VMWare были первыми, кто задумал переписать исполняемые байты в памяти для привилегированных вызовов гостевой ОС, чтобы добиться этого.
В результате виртуализация позволяет запускать две совершенно разные ОС на одном и том же оборудовании. Каждая гостевая ОС проходит весь процесс начальной загрузки, загрузки ядра и т. Д. У вас может быть очень строгая защита, например, гостевая ОС не может получить полный доступ к хост-ОС или другим гостям и испортить ситуацию.
Как контейнеры работают на низком уровне?
Приблизительно в 2006 году люди, в том числе некоторые сотрудники Google, внедрили новую функцию уровня ядра, называемую пространствами имен (однако эта идея существовала задолго до того, как существовала во FreeBSD). Одной из функций ОС является обеспечение совместного использования глобальных ресурсов, таких как сеть и диск, процессам. Что если эти глобальные ресурсы были обернуты в пространства имен, чтобы они были видны только тем процессам, которые выполняются в одном и том же пространстве имен? Скажем, вы можете получить кусок диска и поместить его в пространство имен X, а затем процессы, выполняющиеся в пространстве имен Y, не смогут увидеть или получить к нему доступ. Точно так же процессы в пространстве имен X не могут получить доступ к чему-либо в памяти, выделенному для пространства имен Y. Конечно, процессы в X не могут видеть или взаимодействовать с процессами в пространстве имен Y. Это обеспечивает своего рода виртуализацию и изоляцию для глобальных ресурсов. Вот как работает Docker: каждый контейнер работает в своем собственном пространстве имен, но использует то же ядро, что и все другие контейнеры. Изоляция происходит потому, что ядру известно пространство имен, которое было назначено процессу, и во время вызовов API оно обеспечивает доступ к ресурсам только в своем собственном пространстве имен.
Теперь ограничения контейнеров и виртуальных машин должны быть очевидны: вы не можете запускать совершенно разные ОС в контейнерах, как в виртуальных машинах. Однако вы можете использовать разные дистрибутивы Linux, потому что они используют одно и то же ядро. Уровень изоляции не такой сильный, как в ВМ. Фактически, в ранних реализациях для гостевого контейнера был путь к хосту. Также вы можете видеть, что при загрузке нового контейнера вся новая копия ОС запускается не так, как в VM. Все контейнеры имеют одно и то же ядро. Вот почему контейнеры имеют легкий вес. Кроме того, в отличие от ВМ, вам не нужно предварительно выделять значительный кусок памяти для контейнеров, потому что мы не запускаем новую копию ОС. Это позволяет запускать тысячи контейнеров в одной ОС, в то же время помещая их в "песочницу", что было бы невозможно сделать, если бы мы работали с отдельной копией ОС в ее собственной виртуальной машине.
Хорошие ответы. Просто чтобы получить образное представление контейнера против VM, взгляните на изображение ниже.
Мне нравится ответ Кена Кокрейна.
Но я хочу добавить дополнительную точку зрения, подробно не освещенную здесь. На мой взгляд, Docker отличается и целым процессом. В отличие от виртуальных машин, Docker (не только) обеспечивает оптимальное совместное использование ресурсов аппаратного обеспечения, более того, он обеспечивает "систему" для пакетного приложения (предпочтительно, но не обязательно, как набор микросервисов).
Для меня это вписывается в разрыв между инструментами, ориентированными на разработчика, такими как rpm, пакеты Debian, Maven, npm + Git с одной стороны, и такими инструментами, как Puppet, VMware, Xen, вы называете это...
Почему развертывание программного обеспечения в образ докера (если это правильный термин) проще, чем простое развертывание в согласованной рабочей среде?
Ваш вопрос предполагает некоторую последовательную производственную среду. Но как сохранить это последовательным? Рассмотрим некоторое количество (>10) серверов и приложений, этапов в конвейере.
Чтобы синхронизировать это, вы начнете использовать что-то вроде Puppet, Chef или ваших собственных сценариев инициализации, неопубликованных правил и / или большого количества документации... Теоретически серверы могут работать неограниченное время и быть полностью согласованными и актуальными. Практика не позволяет полностью управлять конфигурацией сервера, поэтому существуют значительные возможности для отклонения конфигурации и неожиданных изменений в работающих серверах.
Таким образом, существует известный способ избежать этого, так называемый неизменный сервер. Но неизменный шаблон сервера не был любим. Главным образом из-за ограничений виртуальных машин, которые использовались до Docker. Работа с большими изображениями в несколько гигабайт, перемещение этих больших изображений, просто чтобы изменить некоторые области в приложении, было очень и очень трудоемким. Понятный...
В экосистеме Docker вам никогда не придется перемещаться в гигабайтах при "небольших изменениях" (спасибо aufs и Registry), и вам не нужно беспокоиться о потере производительности, упаковывая приложения в контейнер Docker во время выполнения. Вам не нужно беспокоиться о версиях этого изображения.
И, наконец, вы даже часто сможете воспроизводить сложные производственные среды даже на своем ноутбуке с Linux (не звоните мне, если в вашем случае это не сработает;))
И, конечно, вы можете запускать Docker-контейнеры в виртуальных машинах (это хорошая идея). Сократите подготовку сервера на уровне виртуальной машины. Все вышеперечисленное может управляться Docker.
PS Между тем Docker использует собственную реализацию "libcontainer" вместо LXC. Но LXC все еще можно использовать.
Докер не методология виртуализации. Он опирается на другие инструменты, которые фактически реализуют виртуализацию на основе контейнеров или виртуализацию на уровне операционной системы. Для этого Docker изначально использовал драйвер LXC, затем перешел на libcontainer, который теперь переименован в runc. Docker в основном занимается автоматизацией развертывания приложений внутри контейнеров приложений. Контейнеры приложений предназначены для упаковки и запуска одного сервиса, тогда как системные контейнеры предназначены для запуска нескольких процессов, например виртуальных машин. Итак, Docker рассматривается как инструмент управления контейнерами или развертывания приложений в контейнерных системах.
Чтобы узнать, чем она отличается от других виртуализаций, давайте пройдемся по виртуализации и ее типам. Тогда было бы легче понять, в чем разница.
Виртуализация
В своей задуманной форме он рассматривался как метод логического разделения мэйнфреймов, позволяющий запускать несколько приложений одновременно. Однако сценарий радикально изменился, когда компании и сообщества с открытым исходным кодом смогли предоставить метод обработки привилегированных инструкций тем или иным образом и обеспечить возможность одновременной работы нескольких операционных систем в одной системе на базе x86.
гипервизор
Гипервизор управляет созданием виртуальной среды, в которой работают гостевые виртуальные машины. Он контролирует гостевые системы и обеспечивает выделение ресурсов для гостей по мере необходимости. Гипервизор находится между физической машиной и виртуальными машинами и предоставляет услуги виртуализации виртуальным машинам. Чтобы реализовать это, он перехватывает операции гостевой операционной системы на виртуальных машинах и эмулирует работу в операционной системе хост-машины.
Быстрое развитие технологий виртуализации, в первую очередь в облаке, привело к дальнейшему использованию виртуализации, позволяя создавать несколько виртуальных серверов на одном физическом сервере с помощью гипервизоров, таких как Xen, VMware Player, KVM и т. Д., И включение аппаратной поддержки в такие стандартные процессоры, как Intel VT и AMD-V.
Типы виртуализации
Метод виртуализации можно разделить на категории в зависимости от того, как он имитирует оборудование для гостевой операционной системы и эмулирует гостевую операционную среду. Прежде всего, существует три типа виртуализации:
- эмуляция
- Паравиртуализация
- Контейнерная виртуализация
эмуляция
Эмуляция, также известная как полная виртуализация, полностью запускает ядро ОС виртуальной машины в программном обеспечении. Гипервизор, используемый в этом типе, известен как гипервизор типа 2. Он устанавливается поверх операционной системы хоста, которая отвечает за перевод кода ядра гостевой ОС в программные инструкции. Перевод выполнен полностью программно и не требует участия оборудования. Эмуляция позволяет запускать любую немодифицированную операционную систему, которая поддерживает эмулируемую среду. Недостатком этого типа виртуализации является дополнительная нагрузка на системные ресурсы, которая приводит к снижению производительности по сравнению с другими типами виртуализаций.
Примеры в этой категории включают VMware Player, VirtualBox, QEMU, Bochs, Parallels и т. Д.
Паравиртуализация
Паравиртуализация, также известная как гипервизор 1-го типа, выполняется непосредственно на аппаратном уровне или "голым железом" и предоставляет услуги виртуализации непосредственно для виртуальных машин, работающих на нем. Это помогает операционной системе, виртуализированному оборудованию и реальному оборудованию сотрудничать для достижения оптимальной производительности. Эти гипервизоры, как правило, занимают довольно мало места и сами по себе не требуют обширных ресурсов.
Примеры в этой категории включают Xen, KVM и т. Д.
Контейнерная виртуализация
Виртуализация на основе контейнеров, также известная как виртуализация на уровне операционной системы, позволяет выполнять несколько изолированных исполнений в одном ядре операционной системы. Он имеет наилучшую производительность и плотность, а также обладает динамическим управлением ресурсами. Изолированная виртуальная среда выполнения, обеспечиваемая этим типом виртуализации, называется контейнером и может рассматриваться как отслеживаемая группа процессов.
Концепция контейнера стала возможной благодаря функции пространств имен, добавленной в ядро Linux версии 2.6.24. Контейнер добавляет свой идентификатор для каждого процесса и добавляет новые проверки контроля доступа к каждому системному вызову. Доступ к нему осуществляется с помощью системного вызова clone(), который позволяет создавать отдельные экземпляры ранее глобальных пространств имен.
Пространства имен можно использовать по-разному, но наиболее распространенный подход заключается в создании изолированного контейнера, который не имеет видимости или доступа к объектам вне контейнера. Процессы, выполняющиеся внутри контейнера, по-видимому, выполняются в обычной системе Linux, хотя они совместно используют базовое ядро с процессами, расположенными в других пространствах имен, то же самое для других типов объектов. Например, при использовании пространств имен пользователь root внутри контейнера не рассматривается как root вне контейнера, что добавляет дополнительную безопасность.
Подсистема Linux Control Groups (cgroups), следующий основной компонент, обеспечивающий виртуализацию на основе контейнеров, используется для группировки процессов и управления их совокупным потреблением ресурсов. Обычно используется для ограничения потребления памяти и ЦП контейнерами. Поскольку контейнерная система Linux имеет только одно ядро, а ядро полностью контролирует контейнеры, существует только один уровень распределения ресурсов и планирования.
Для контейнеров Linux доступно несколько инструментов управления, включая LXC, LXD, systemd-nspawn, lmctfy, Warden, Linux-VServer, OpenVZ, Docker и т. Д.
Контейнеры против виртуальных машин
В отличие от виртуальной машины, контейнеру не нужно загружать ядро операционной системы, поэтому контейнеры могут быть созданы менее чем за секунду. Эта функция делает виртуализацию на основе контейнеров уникальной и желательной по сравнению с другими подходами к виртуализации.
Поскольку виртуализация на основе контейнеров практически не увеличивает нагрузку на хост-машину, виртуализация на основе контейнеров имеет почти естественную производительность
Для виртуализации на основе контейнеров не требуется никакого дополнительного программного обеспечения, в отличие от других виртуализаций.
Все контейнеры на хост-машине совместно используют планировщик хост-машины, что экономит потребность в дополнительных ресурсах.
Состояния контейнера (образы Docker или LXC) имеют небольшой размер по сравнению с образами виртуальных машин, поэтому их легко распространять.
Управление ресурсами в контейнерах осуществляется через cgroups. Cgroups не позволяет контейнерам потреблять больше ресурсов, чем выделено им. Однако на данный момент все ресурсы хост-машины видны на виртуальных машинах, но не могут быть использованы. Это можно реализовать, запустив top
или же htop
на контейнерах и хост-машине одновременно. Вывод во всех средах будет выглядеть одинаково.
Обновить:
Как Docker запускает контейнеры в системах, отличных от Linux?
Если контейнеры возможны из-за функций, доступных в ядре Linux, то очевидный вопрос заключается в том, как системы не-Linux запускают контейнеры. Как Docker для Mac, так и Windows используют виртуальные машины Linux для запуска контейнеров. Docker Toolbox используется для запуска контейнеров в виртуальных машинах Virtual Box. Но последняя версия Docker использует Hyper-V в Windows и Hypervisor.framework в Mac.
Теперь позвольте мне подробно описать, как Docker для Mac запускает контейнеры.
Docker для Mac использует https://github.com/moby/hyperkit для эмуляции возможностей гипервизора, а Hyperkit использует hypervisor.framework в своей основе. Hypervisor.framework - это родное гипервизорное решение для Mac. Hyperkit также использует VPNKit и DataKit для пространства имен сети и файловой системы соответственно.
Виртуальная машина Linux, которую Docker запускает в Mac, доступна только для чтения. Тем не менее, вы можете войти в него, запустив:
screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
,
Теперь мы можем даже проверить версию ядра этой виртуальной машины:
# uname -a
Linux linuxkit-025000000001 4.9.93-linuxkit-aufs #1 SMP Wed Jun 6 16:86_64 Linux
,
Все контейнеры работают внутри этой виртуальной машины.
Есть некоторые ограничения для hypervisor.framework. Из-за этого Докер не выставляет docker0
сетевой интерфейс в Mac. Таким образом, вы не можете получить доступ к контейнерам с хоста. На данный момент, docker0
доступно только внутри виртуальной машины.
Hyper-v является родным гипервизором в Windows. Они также пытаются использовать возможности Windows 10 для естественного запуска систем Linux.
Большинство ответов здесь говорят о виртуальных машинах. Я собираюсь дать вам однострочный ответ на этот вопрос, который помог мне больше всего за последние пару лет использования Docker. Это так:
Docker - это просто модный способ запуска процесса, а не виртуальная машина.
Теперь позвольте мне объяснить немного больше о том, что это значит. Виртуальные машины - это их собственные звери. Мне кажется, что объяснение того, что такое Docker, поможет вам понять это больше, чем объяснение, что такое виртуальная машина. Тем более, что здесь есть много прекрасных ответов, в которых точно сказано, что кто-то имеет в виду, когда говорит "виртуальная машина". Так...
Контейнер Docker - это просто процесс (и его дочерние элементы), который отделен с помощью cgroups внутри ядра хост-системы от остальных процессов. Вы можете увидеть процессы контейнера Docker, запустив ps aux
на хосте. Например, начиная apache2
"в контейнере" только начинается apache2
как особый процесс на хосте. Он просто отделен от других процессов на машине. Важно отметить, что ваши контейнеры не существуют вне времени жизни вашего контейнерного процесса. Когда ваш процесс умирает, ваш контейнер умирает. Это потому, что Docker заменяет pid 1
внутри вашего контейнера с вашим приложением (pid 1
обычно это система инициализации). Этот последний пункт о pid 1
очень важно.
Что касается файловой системы, используемой каждым из этих процессов-контейнеров, Docker использует образы с поддержкой UnionFS, которые вы загружаете, когда делаете docker pull ubuntu
, Каждое "изображение" - это просто серия слоев и связанных метаданных. Концепция наслоения здесь очень важна. Каждый слой - это просто изменение слоя под ним. Например, когда вы удаляете файл в своем Dockerfile при создании контейнера Docker, вы фактически просто создаете слой поверх последнего слоя, который говорит: "Этот файл был удален". Кстати, именно поэтому вы можете удалить большой файл из вашей файловой системы, но образ все равно занимает тот же объем дискового пространства. Файл все еще там, в слоях под текущим. Сами слои - это просто архивы файлов. Вы можете проверить это с docker save --output /tmp/ubuntu.tar ubuntu
а потом cd /tmp && tar xvf ubuntu.tar
, Тогда вы можете осмотреться. Все эти каталоги, которые выглядят как длинные хеши, на самом деле являются отдельными слоями. Каждый содержит файлы (layer.tar
) и метаданные (json
) с информацией об этом конкретном слое. Эти слои просто описывают изменения в файловой системе, которые сохраняются как слой "поверх" его первоначального состояния. При чтении "текущих" данных файловая система считывает данные так, как будто она просматривает только самые верхние слои изменений. Вот почему файл кажется удаленным, даже если он все еще существует в "предыдущих" слоях, потому что файловая система просматривает только самые верхние слои. Это позволяет совершенно разным контейнерам совместно использовать свои слои файловой системы, даже если некоторые существенные изменения могли произойти с файловой системой на верхних слоях в каждом контейнере. Это может сэкономить вам массу дискового пространства, когда ваши контейнеры совместно используют свои базовые слои изображений. Однако, когда вы монтируете каталоги и файлы из хост-системы в свой контейнер с помощью томов, эти тома "обходят" UnionFS, поэтому изменения не сохраняются в слоях.
Сеть в Docker достигается с помощью моста Ethernet (называемого docker0
на хосте) и виртуальные интерфейсы для каждого контейнера на хосте. Создает виртуальную подсеть в docker0
чтобы ваши контейнеры общались "между собой". Здесь есть много вариантов сетевого взаимодействия, включая создание пользовательских подсетей для ваших контейнеров и возможность "поделиться" сетевым стеком вашего хоста, чтобы ваш контейнер имел прямой доступ.
Докер движется очень быстро. Его документация - одна из лучших, которые я когда-либо видел. Это, как правило, хорошо написано, сжато и точно. Я рекомендую вам проверить доступную документацию для получения дополнительной информации и доверять документации всему, что вы читаете онлайн, включая переполнение стека. Если у вас есть конкретные вопросы, я настоятельно рекомендую присоединиться #docker
на Freenode IRC и спрашивая там (вы даже можете использовать веб-чат Freenode для этого!).
В этом посте мы проведем некоторые различия между виртуальными машинами и LXC. Давайте сначала определим их.
ВМ:
Виртуальная машина эмулирует физическую вычислительную среду, но запросы к ЦП, памяти, жесткому диску, сети и другим аппаратным ресурсам управляются уровнем виртуализации, который переводит эти запросы в базовое физическое оборудование.
В этом контексте виртуальная машина называется гостем, а среда, в которой она работает, называется хостом.
LXC s:
Контейнеры Linux (LXC) - это возможности уровня операционной системы, которые позволяют запускать несколько изолированных контейнеров Linux на одном управляющем хосте (хосте LXC). Контейнеры Linux служат легкой альтернативой виртуальным машинам, поскольку они не требуют наличия гипервизоров. Virtualbox, KVM, Xen и др.
Теперь, если вы не были одурманены Аланом (Заком Галифианакисом - из серии "Похмелье") и не были в Вегасе в течение прошлого года, вы будете в курсе огромного всплеска интереса к технологии контейнеров Linux, и если я буду конкретен, один контейнер Проект, который за последние несколько месяцев вызвал оживление во всем мире, - это докер, который привел к некоторому повторяющемуся мнению, что средам облачных вычислений следует отказаться от виртуальных машин (ВМ) и заменить их контейнерами из-за их меньших издержек и потенциально лучшей производительности.
Но главный вопрос в том, возможно ли это? Будет ли это разумным?
а. LXC относятся к экземпляру Linux. Это могут быть разные варианты Linux (например, контейнер Ubuntu на хосте CentOS, но это все-таки Linux.) Точно так же контейнеры на основе Windows теперь относятся к экземпляру Windows, если мы посмотрим на виртуальные машины, они имеют более широкую область применения и используют Гипервизоры не ограничиваются операционными системами Linux или Windows.
б. LXC имеют низкие накладные расходы и имеют лучшую производительность по сравнению с виртуальными машинами. Инструменты, а именно Докер, созданный на основе технологии LXC, предоставил разработчикам платформу для запуска своих приложений и в то же время предоставил операционным сотрудникам инструмент, который позволит им развертывать один и тот же контейнер на производственных серверах или в центрах обработки данных. Он пытается сделать взаимодействие между разработчиком, запускающим приложение, загружающим и тестирующим приложение, и оперативным сотрудником, развертывающим это приложение, беспроблемным, потому что именно в этом заключается вся проблема, и цель DevOps - сломать эти бункеры.
Таким образом, лучший подход заключается в том, что поставщики облачной инфраструктуры должны защищать надлежащее использование виртуальных машин и LXC, поскольку каждый из них подходит для обработки определенных рабочих нагрузок и сценариев.
Отказаться от виртуальных машин на данный момент нецелесообразно. Таким образом, как виртуальные машины, так и LXC имеют свое индивидуальное существование и важность.
Docker инкапсулирует приложение со всеми его зависимостями.
Виртуализатор инкапсулирует ОС, которая может запускать любые приложения, которые он обычно может запускать на голой железной машине.
Они оба очень разные. Docker облегчен и использует LXC/libcontainer (который опирается на пространства имен ядра и cgroups) и не имеет эмуляции машины / оборудования, такой как гипервизор, KVM. Ксен, которые тяжелы.
Docker и LXC больше предназначены для песочницы, контейнеризации и изоляции ресурсов. Он использует API-интерфейс клонирования операционной системы хоста (в настоящее время только ядро Linux), который обеспечивает пространство имен для IPC, NS (mount), сети, PID, UTS и т. Д.
А как насчет памяти, ввода-вывода, процессора и т. Д.? Это контролируется с помощью cgroups, где вы можете создавать группы с определенной спецификацией / ограничением ресурсов (ЦП, памяти и т. Д.) И размещать там свои процессы. Помимо LXC, Docker предоставляет серверную часть хранилища ( http://www.projectatomic.io/docs/filesystems/), например, объединяющую файловую систему, где вы можете добавлять слои и обмениваться слоями между различными пространствами имен монтирования.
Это мощная функция, при которой базовые изображения обычно доступны только для чтения, и только когда контейнер изменяет что-либо в слое, он может что-то записать в раздел для чтения-записи (также как копирование при записи). Он также предоставляет множество других оболочек, таких как реестр и управление версиями изображений.
С обычным LXC вам нужно прийти с некоторыми rootfs или поделиться rootfs и, когда они будут общими, изменения отражаются в других контейнерах. Благодаря большому количеству этих дополнительных функций, Docker более популярен, чем LXC. LXC популярен во встраиваемых средах для обеспечения безопасности вокруг процессов, открытых для внешних объектов, таких как сеть и пользовательский интерфейс. Docker популярен в облачной многопользовательской среде, где ожидается согласованная производственная среда.
Обычная виртуальная машина (например, VirtualBox и VMware) использует гипервизор, а соответствующие технологии либо имеют специальное встроенное ПО, которое становится первым уровнем для первой ОС (хост-ОС или гостевая ОС 0), либо программное обеспечение, которое запускается на хост-ОС для обеспечить аппаратную эмуляцию, такую как процессор, USB/ аксессуары, память, сеть и т. д., для гостевых ОС. Виртуальные машины по-прежнему (по состоянию на 2015 г.) популярны в мультитенантной среде с высоким уровнем безопасности.
Docker/ LXC практически можно запустить на любом дешевом оборудовании (если у вас более новое ядро, можно использовать и менее 1 ГБ памяти), тогда как нормальным виртуальным машинам требуется как минимум 2 ГБ памяти и т. Д., Чтобы сделать что-то значимое с ней, Но поддержка Docker на хост-ОС недоступна в таких ОС, как Windows (по состоянию на ноябрь 2014 г.), где могут работать типы виртуальных машин в Windows, Linux и Mac.
1. легкий
Это, вероятно, первое впечатление для многих изучающих докер.
Во-первых, образы докеров, как правило, меньше, чем образы виртуальных машин, что позволяет легко создавать, копировать и делиться ими.
Во-вторых, контейнеры Docker могут запускаться за несколько миллисекунд, а виртуальная машина запускается за секунды.
2. Многоуровневая файловая система
Это еще одна ключевая особенность Docker. Изображения имеют слои, и разные изображения могут совместно использовать слои, что делает его еще более компактным и ускоряет создание.
Если все контейнеры используют Ubuntu в качестве базовых образов, не каждое изображение имеет собственную файловую систему, но совместно использует одни и те же файлы подчеркивания Ubuntu и отличается только данными своих приложений.
3. Ядро общей ОС
Думайте о контейнерах как о процессах!
Все контейнеры, запущенные на хосте, действительно представляют собой набор процессов с разными файловыми системами. Они используют одно и то же ядро ОС, только инкапсулируют системную библиотеку и зависимости.
Это хорошо для большинства случаев (без поддержки дополнительного ядра ОС), но может стать проблемой, если между контейнерами необходима строгая изоляция.
Почему это важно?
Все это похоже на улучшение, а не революцию. Что ж, количественное накопление ведет к качественному преобразованию.
Подумайте о развертывании приложения. Если мы хотим развернуть новое программное обеспечение (сервис) или обновить его, лучше изменить файлы конфигурации и процессы, а не создавать новую виртуальную машину. Поскольку создание виртуальной машины с обновленным сервисом, ее тестирование (совместное использование между Dev & QA), развертывание в производство занимает часы, даже дни. Если что-то пойдет не так, вы должны начать все заново, тратя еще больше времени. Поэтому для установки нового программного обеспечения используйте инструмент управления конфигурацией (puppet, salttack, chef и т. Д.), Загрузка новых файлов является предпочтительной.
Когда дело доходит до докера, невозможно использовать недавно созданный контейнер докера для замены старого. Сопровождение намного проще! Создание нового образа, предоставление его в QA, тестирование, развертывание занимает всего несколько минут (если все автоматизировано), в худшем случае - часы. Это называется неизменной инфраструктурой: не поддерживайте (не обновляйте) программное обеспечение, вместо этого создайте новое.
Это меняет способ предоставления услуг. Мы хотим приложения, но должны поддерживать виртуальные машины (что является болью и имеет мало общего с нашими приложениями). Docker заставляет вас сосредоточиться на приложениях и сглаживает все.
Docker, в основном контейнеры, поддерживает виртуализацию ОС, т.е. ваше приложение чувствует, что оно имеет полный экземпляр ОС, тогда как виртуальная машина поддерживает аппаратную виртуализацию. Вы чувствуете, что это физическая машина, на которой вы можете загрузить любую ОС.
В Docker работающие контейнеры совместно используют ядро операционной системы, тогда как в виртуальных машинах они имеют свои собственные файлы операционной системы. Среда (ОС), в которой вы разрабатываете приложение, будет одинаковой при развертывании его в различных обслуживающих средах, таких как "тестирование" или "производство".
Например, если вы разрабатываете веб-сервер, работающий на порте 4000, при развертывании его в своей "тестовой" среде этот порт уже используется какой-либо другой программой, поэтому он перестает работать. В контейнерах есть слои; все изменения, которые вы внесли в ОС, будут сохранены в одном или нескольких слоях, и эти слои будут частью изображения, поэтому, где бы ни находилось изображение, также будут присутствовать зависимости.
В приведенном ниже примере хост-машина имеет три виртуальные машины. Чтобы обеспечить полную изоляцию приложений в виртуальных машинах, у каждого из них есть собственные копии файлов ОС, библиотек и кода приложения, а также полный экземпляр ОС в памяти. Принимая во внимание, что на рисунке ниже показан тот же сценарий с контейнерами. Здесь контейнеры просто совместно используют операционную систему хоста, включая ядро и библиотеки, поэтому им не нужно загружать ОС, загружать библиотеки или оплачивать стоимость отдельной памяти для этих файлов. Единственное добавочное пространство, которое они занимают, - это любая память и дисковое пространство, необходимые для запуска приложения в контейнере. Хотя среда приложения выглядит как выделенная ОС, приложение развертывается точно так же, как и на выделенном хосте. Контейнерное приложение запускается за считанные секунды, и на машине может поместиться гораздо больше экземпляров приложения, чем в случае с виртуальной машиной.
Источник: https://azure.microsoft.com/en-us/blog/containers-docker-windows-and-trends/
Существуют три различные установки, которые предоставляют стек для запуска приложения (это поможет нам понять, что такое контейнер и что делает его настолько мощным, чем другие решения):
1) Traditional Servers(bare metal)
2) Virtual machines (VMs)
3) Containers
1) Традиционный стек серверов состоит из физического сервера, на котором работает операционная система и ваше приложение.
Преимущества:
Утилизация сырьевых ресурсов
изоляция
Недостатки:
- Очень медленное время развертывания
- Дорого
- Потраченные впустую ресурсы
- Сложно масштабировать
- Трудно мигрировать
- Сложная конфигурация
2) Стек виртуальных машин состоит из физического сервера, на котором работает операционная система, и гипервизора, который управляет вашей виртуальной машиной, общими ресурсами и сетевым интерфейсом. Каждый Vm запускает гостевую операционную систему, приложение или набор приложений.
Преимущества:
- Хорошее использование ресурсов
- Легко масштабируется
- Простое резервное копирование и миграция
- Эффективность затрат
- гибкость
Недостатки:
- Распределение ресурсов проблематично
- Поставщик блокировки
- Сложная конфигурация
3) Контейнерная установка, ключевое отличие от другого стека заключается в том, что виртуализация на основе контейнеров использует ядро операционной системы хоста для поиска нескольких изолированных гостевых экземпляров. Эти гостевые экземпляры называются контейнерами. Хост может быть физическим сервером или виртуальной машиной.
Преимущества:
- изоляция
- облегченный
- Ресурс эффективен
- Легко мигрировать
- Безопасность
- Низкие накладные расходы
- Зеркальное производство и среда разработки
Недостатки:
- Та же архитектура
- Ресурс тяжелых приложений
- Проблемы с сетью и безопасностью.
Сравнивая настройку контейнера с его предшественниками, мы можем сделать вывод, что контейнеризация - самая быстрая, наиболее эффективная и наиболее безопасная установка, которую мы знаем на сегодняшний день. Контейнеры - это изолированные экземпляры, которые запускают ваше приложение. Docker каким-то образом раскручивает контейнер, слои получают оперативную память с драйверами хранилища по умолчанию (драйверы оверлеев), которые запускаются в течение нескольких секунд, и слоем копирования при записи, созданным поверх него после фиксации в контейнере, который обеспечивает выполнение контейнеры. В случае виртуальных машин это займет около минуты, чтобы загрузить все в среду виртуализации. Эти легкие экземпляры можно легко заменять, перестраивать и перемещать. Это позволяет нам отражать среду производства и разработки и является огромной помощью в процессах CI/CD. Преимущества, которые могут предоставить контейнеры, настолько убедительны, что они определенно здесь, чтобы остаться.
В связи с:-
"Почему развертывание программного обеспечения в образ докера проще, чем простое развертывание в согласованной рабочей среде?"
Большая часть программного обеспечения развернута во многих средах, обычно как минимум три из следующих:
- Индивидуальные ПК разработчика
- Общая среда разработки
- Индивидуальный тестер ПК
- Общая тестовая среда
- QA среда
- Среда UAT
- Тестирование нагрузки / производительности
- Живая постановка
- производство
- Архив
Также необходимо учитывать следующие факторы:
- Разработчики и, в действительности, тестировщики, будут иметь как слегка, так и совершенно разные конфигурации ПК, в зависимости от характера работы.
- Разработчики часто могут разрабатывать на ПК вне контроля корпоративных или бизнес-стандартов (например, фрилансеры, которые разрабатывают на своих машинах (часто удаленно), или участники проектов с открытым исходным кодом, которые не "заняты" или "не заключили контракт" для настройки своих ПК определенным образом). путь)
- Некоторые среды состоят из фиксированного количества нескольких машин в конфигурации с балансировкой нагрузки
- Во многих производственных средах облачные серверы динамически (или "упруго") создаются и уничтожаются в зависимости от уровня трафика.
Как вы можете видеть, экстраполированное общее количество серверов для организации редко бывает в единичных цифрах, очень часто в тройных цифрах и может быть еще значительно выше.
Все это означает, что создание согласованных сред, во-первых, достаточно сложно только из-за большого объема (даже в сценарии "зеленого поля"), но поддерживать их согласованность практически невозможно, учитывая большое количество серверов, добавление новых серверов (динамически или вручную), автоматические обновления от поставщиков операционной системы, антивирусных программ, поставщиков браузеров и т. п., ручная установка программного обеспечения или изменения конфигурации, выполняемые разработчиками или специалистами по серверам и т. д. Позвольте мне повторить, что это практически (без каламбура) невозможно поддерживать согласованность окружения (хорошо, для пуриста это можно сделать, но это требует огромного количества времени, усилий и дисциплины, именно поэтому в первую очередь были разработаны виртуальные машины и контейнеры (например, Docker)).
Поэтому задумайтесь над своим вопросом следующим образом: "Учитывая чрезвычайную сложность поддержания согласованности всех сред, проще ли развертывать программное обеспечение в образ докера, даже если принять во внимание кривую обучения?", Я думаю, вы найдете, что ответ неизменно будет "да" - но есть только один способ узнать это, разместите этот новый вопрос в переполнении стека.
Есть много ответов, которые более подробно объясняют различия, но вот мое очень краткое объяснение.
Одним из важных отличий является то, что виртуальные машины используют отдельное ядро для запуска ОС. По этой причине он тяжелый и требует времени для загрузки, потребляя больше системных ресурсов.
В Docker контейнеры делят ядро с хостом; следовательно, он легкий и может быстро запускаться и останавливаться.
В виртуализации ресурсы выделяются в начале установки, и, следовательно, ресурсы используются не полностью, когда виртуальная машина простаивает во многих случаях. В Docker контейнеры не выделяются с фиксированным количеством аппаратных ресурсов и могут свободно использовать ресурсы в зависимости от требований, и, следовательно, они легко масштабируются.
Docker использует файловую систему UNION. Docker использует технологию копирования при записи, чтобы уменьшить объем памяти, занимаемой контейнерами. Узнайте больше здесь
С виртуальной машиной у нас есть сервер, у нас есть хост-операционная система на этом сервере, а затем у нас есть гипервизор. И затем, работая поверх этого гипервизора, мы имеем любое количество гостевых операционных систем с приложением и его зависимыми двоичными файлами, а также библиотеками на этом сервере. Это приносит целую гостевую операционную систему с этим. Это довольно тяжеловес. Также есть ограничение на то, сколько вы на самом деле можете поставить на каждую физическую машину.
Контейнеры Docker, с другой стороны, немного отличаются. У нас есть сервер. У нас есть операционная система хоста. Но вместо гипервизора у нас есть механизм Docker, в данном случае. В этом случае мы не будем брать с собой целую гостевую операционную систему. Мы представляем очень тонкий слой операционной системы, и контейнер может связываться с хост-ОС, чтобы получить доступ к функциональности ядра. И это позволяет нам иметь очень легкий контейнер.
Все, что у него есть, - это код приложения и все необходимые ему двоичные файлы и библиотеки. И эти двоичные файлы и библиотеки могут фактически использоваться в разных контейнерах, если вы хотите, чтобы они тоже были. И что это позволяет нам делать, это ряд вещей. У них намного быстрее время запуска. Вы не можете встать ни одной виртуальной машины в течение нескольких секунд, как это. И в равной степени, убирая их так же быстро... чтобы мы могли очень быстро увеличивать и уменьшать их, и мы рассмотрим это позже.
Каждый контейнер думает, что он работает в своей собственной копии операционной системы. У него есть собственная файловая система, собственный реестр и т. Д., Что является своего рода ложью. Это на самом деле виртуализировано.
Я использовал Docker в производственных средах и в постановке очень много. Когда вы привыкнете к нему, вы найдете его очень мощным для построения мультиконтейнера и изолированных сред.
Docker был разработан на основе LXC (Linux Container) и отлично работает во многих дистрибутивах Linux, особенно в Ubuntu.
Контейнеры Docker являются изолированной средой. Вы можете увидеть это, когда вы выпускаете top
команда в контейнере Docker, который был создан из образа Docker.
Кроме того, они очень легкие и гибкие благодаря конфигурации dockerFile.
Например, вы можете создать образ Docker, настроить DockerFile и сказать, что, например, когда он работает, wget 'this', apt-get 'that', запустить 'некоторый сценарий оболочки', установить переменные среды и так далее.
В проектах микро-сервисов и архитектуре Docker является очень жизнеспособным активом. С помощью Docker, Docker Swarm, Kubernetes и Docker Compose вы можете добиться масштабируемости, отказоустойчивости и эластичности.
Еще одна важная проблема, касающаяся Docker, - это Docker Hub и его сообщество. Например, я реализовал экосистему для мониторинга кафки, используя Prometheus, Grafana, Prometheus-JMX-Exporter и Dokcer.
Для этого я скачал настроенные контейнеры Docker для zookeeper, kafka, Prometheus, Grafana и jmx-collector, затем смонтировал свою собственную конфигурацию для некоторых из них, используя файлы yml, или для других, я изменил некоторые файлы и конфигурацию в контейнере Docker и собрал целое Система мониторинга кафки с использованием многоконтейнерных докеров на одной машине с изоляцией, масштабируемостью и отказоустойчивостью, благодаря которой эту архитектуру можно легко перенести на несколько серверов.
Помимо сайта Docker Hub есть еще один сайт под названием quay.io, который вы можете использовать, чтобы иметь там свою собственную панель изображений Docker и перетаскивать / выдвигать на нее / с нее. Вы даже можете импортировать образы Docker из Docker Hub в Quay, а затем запускать их из Quay на своем компьютере.
Примечание. Изучение Docker в первую очередь кажется сложным и трудным делом, но когда вы к нему привыкнете, вы не сможете работать без него.
Я помню первые дни работы с Docker, когда я вводил неправильные команды или по ошибке удалял свои контейнеры и все данные и конфигурации.
Вот как Docker представляет себя:
Docker - компания, управляющая движением контейнеров, и единственный поставщик контейнерных платформ, работающий с любым приложением в гибридном облаке. Современные предприятия испытывают трудности с цифровым преобразованием, но ограничены существующими приложениями и инфраструктурой, рационализируя все более разнообразный портфель облаков, центров обработки данных и архитектур приложений. Docker обеспечивает подлинную независимость между приложениями и инфраструктурой, а также разработчиками и ИТ-специалистами, чтобы раскрыть их потенциал и создает модель для улучшения сотрудничества и инноваций.
Итак, Docker основан на контейнерах, что означает, что у вас есть образы и контейнеры, которые можно запустить на вашем текущем компьютере. Он не включает в себя операционную систему, такую как виртуальные машины, но как пакет различных рабочих пакетов, таких как Java, Tomcat и т. Д.
Если вы понимаете контейнеры, вы получаете, что такое Docker и чем он отличается от виртуальных машин...
Итак, что такое контейнер?
Образ контейнера - это легкий, автономный исполняемый пакет программного обеспечения, который включает в себя все необходимое для его запуска: код, время выполнения, системные инструменты, системные библиотеки, настройки. Контейнерное программное обеспечение, доступное как для Linux, так и для Windows, всегда будет работать одинаково, независимо от среды. Контейнеры изолируют программное обеспечение от его окружения, например, различия между средой разработки и промежуточными средами, и помогают уменьшить конфликты между командами, использующими различное программное обеспечение в одной и той же инфраструктуре.
Итак, как вы видите на изображении ниже, каждый контейнер имеет отдельный пакет и работает на одной машине с общей операционной системой этой машины... Они безопасны и просты в отправке...
Здесь есть много хороших технических ответов, в которых четко обсуждаются различия между виртуальными машинами и контейнерами, а также происхождение Docker.
Для меня принципиальное различие между виртуальными машинами и Docker заключается в том, как вы управляете продвижением своего приложения.
С помощью виртуальных машин вы продвигаете свое приложение и его зависимости от одной виртуальной машины до следующей DEV, от UAT до PRD.
- Часто эти виртуальные машины будут иметь различные патчи и библиотеки.
- Многие приложения часто используют виртуальную машину. Это требует управления конфигурацией и зависимостями для всех приложений.
- Отмена требует отмены изменений в ВМ. Или восстановить его, если это возможно.
Идея Docker заключается в том, что вы упаковываете свое приложение в собственный контейнер вместе с необходимыми библиотеками, а затем рекламируете весь контейнер как единое целое.
- За исключением ядра патчи и библиотеки идентичны.
- Как правило, в каждом контейнере есть только одно приложение, которое упрощает настройку.
- Отказ состоит из остановки и удаления контейнера.
Таким образом, на самом фундаментальном уровне с виртуальными машинами вы продвигаете приложение и его зависимости как дискретные компоненты, тогда как с помощью Docker вы продвигаете все в один удар.
И да, есть проблемы с контейнерами, включая управление ими, хотя такие инструменты, как Kubernetes или Docker Swarm, значительно упрощают задачу.
Контейнеры изолируют библиотеки и программные пакеты от системы, так что вы можете устанавливать разные версии одного и того же программного обеспечения и библиотек без конфликтов. Он использует минимальное хранилище и оперативную память, почти без накладных расходов, используя то же ядро базовой ОС и доступные библиотеки с небольшой разницей, если это возможно. Вы можете прямо или косвенно предоставлять контейнерам доступ к своему оборудованию, чтобы использовать ускорение, такое как GPU, для вычислений.
На практике вы используете docker для готовых контейнеров. Вы устанавливаете их и запускаете в одну строку. Установить tensorflow-gpu так же просто, какdocker run -it tensorflow-gpu
. Хотя мне не удалось найти много готовых контейнеров lxd (контейнеров lxc) , я нахожу их более простыми в настройке , более стабильными и производительными.
Для распределения нагрузки можно использовать как контейнеры, так и виртуальные машины. Но поскольку у контейнеров почти нет накладных расходов, программное обеспечение для управления контейнерами ориентировано на создание кластеров контейнеров, чтобы вы могли легко распределять их, а значит, и нагрузку, на металлические машины.
Пример из реальной жизни:
Предположим, вам нужно более 50 типов вычислительной среды и 50 типов служб, таких как mysql, веб-хостинг и облачные службы (например, jenkins и объектное хранилище), и у вас есть более 50 различных серверов без ПО. Как правило, это академическая среда со многими факультетами. И вам нужно эффективно использовать ресурсы, и вам нужна высокая доступность. Когда один сервер выходит из строя, пользователи не должны испытывать никаких проблем. Чтобы решить эту проблему, вы в основном устанавливаете все типы контейнеров на все серверы. И распределите нагрузку на все металлические машины. Поскольку на один тип контейнера требуется больше, можно автоматически создавать больше из них на одной или нескольких машинах с голым металлом. Таким образом, множество разных пользователей могут постоянно и гибко использовать различные сервисы и среды.
В этой настройке предположим, что 100 студентов используют систему одновременно. 95 из них используют серверы для элементарных услуг, таких как проверка среднего балла, учебных программ, библиотечной базы данных и т. д. Но 5 из них выполняют 5 различных типов инженерных симуляций. Вы увидите, что 49 «голых» серверов полностью посвящены инженерному моделированию, каждый из которых имеет 5 различных типов вычислительных контейнеров, каждый из которых привязан к гонке, но сбалансирован как использование ресурсов %20. Когда вы добавите еще 2500 студентов для элементарных задач, они будут использовать 5% всех машин с «голым железом». Остальное будет использоваться для вычислений.
Таким образом, наиболее важными отличительными чертами контейнера, обеспечивающими такие преимущества гибкости, являются:
готовые к развертыванию готовые контейнеры, почти никаких накладных расходов, быстрое создание с квотами, регулируемыми в реальном времени
используя .cpu_allowences , .ram_allowances или непосредственно cgroup.Kubernetes сделает все это за вас. После того, как вы поиграли с docker и lxd, вы можете проверить это.
Я предполагаю, что вы уже знакомы с тем, как виртуальная машина использует эмуляцию аппаратного уровня.
Контейнер Docker, однако, работает как обычный процесс в операционной системе хоста и опирается на функции ядра Linux, обеспечивающие изоляцию: пространства имен. На самом деле вы можете играть с пространствами имен отдельно от «контейнеров», если хотите, и это может помочь вам понять, как все это сочетается друг с другом. Вот список:
- Пространство имен процессов: процесс в пространстве имен PID имеет видимость только процессов в том же пространстве имен. Так что на практике, если вы запускаете оболочку bash в пространстве имен процессов и делаете «ps -a», ядро покажет вам процессы только в том же пространстве имен. Что особенно интересно, так это то, что на хост-компьютере докера вы можете увидеть все процессы-контейнеры, выполнив «ps -a», поскольку ядро не ограничивает вас за пределами пространства имен — это просто обычные процессы, видимость которых ограничена.
- Сетевое пространство имен: сетевое пространство имен имеет собственный изолированный экземпляр полного сетевого стека Linux. Итак, подумайте об интерфейсах, правилах iptables, таблице маршрутизации и т. д. Фактически, сетевое пространство имен начинает полностью отключенным от внешнего мира, и докер добавляет сверху некоторые сетевые фу, чтобы дать контейнеру интерфейс по умолчанию с доступом к хосту через NAT. подключение к сети.
- Пространство имен IPC: здесь нечего сказать — оно идет рука об руку с пространством имен PID, как и следовало ожидать.
- Пространство имен монтирования: это способ, которым докер предоставляет контейнеру собственную файловую систему. В пространстве имен mount Docker монтирует всю файловую систему из файла в корень. Только процессы, которые являются членами пространства имен, увидят это. В других ответах описана хитрость того, как докер использует UnionFS, поэтому я не буду здесь подробно останавливаться (редактировать: я решил уточнить в нижнем разделе, как это помогает докеру быть легким)
- Пространство имен пользователей: пространство имен пользователей — это то, что позволяет док-контейнерам иметь своих собственных выделенных пользователей, * не затрагивая остальную часть системы. (У этих пользователей по-прежнему будет UID/GID, поэтому файлы, которые они создают, будут принадлежать этим UID/GID, когда вы извлечете их из контейнера, и root внутри контейнера сможет изменять любые файлы, которые вы монтируете в контейнер, так что уход все равно нужен)
- Пространство имен UTS: по-видимому, это позволяет контейнерам иметь свои собственные имена хостов и доменные имена — я не часто думаю об этом.
- Time Namespace: это позволяет контейнерам иметь свои собственные независимые системные часы. Я подозреваю, что докер не беспокоится об этом, поскольку фоновые службы, такие как NTP, не будут работать в контейнере.
Когда вы определяете контейнер, вы обычно определяете один корневой процесс, который Docker загружает в выделенный набор пространств имен, которые вместе мы называем контейнером. Docker будет отслеживать этот родительский процесс КАК контейнер, и когда он умирает, Docker считает, что контейнер остановлен. Вот почему, как правило, вам не следует пытаться запускать фоновые службы внутри контейнера — думайте о докере как о диспетчере служб, а ваше приложение — это отдельная служба. Дочерние процессы остаются в тех же пространствах имен, что и их родительские процессы, поэтому сохраняется изоляция. «Docker exec» на самом деле просто причудливая оркестровка реальной команды «nsenter», предоставляемая ядром, чтобы позволить вам выполнять программу внутри пространств имен.
В дополнение к совместному использованию одного и того же ядра, Docker использует еще пару приемов для упрощения.
Слои изображений
Во-первых, как указывали другие, докер использует UnionFS, которая представляет собой многоуровневую файловую систему. Предыдущие слои доступны только для чтения, а текущий слой доступен для редактирования, но с возможностью копирования при записи. Таким образом, если в предыдущем слое есть файл A, и вы изменяете этот файл, весь файл вместе с вашими изменениями сохраняется в текущем слое r/w. UnionFS отвечает за отображение только последней копии файла. Это может показаться расточительным — вы храните копию старого документа, даже если больше его не используете? Однако это позволяет структурировать слои изображения в виде дерева, где в любой момент вы можете разветвить массу различных конфигураций из общих базовых изображений без дублирования файлов в этих базовых слоях.
Предположим, вы создаете образ докера для веб-сервера. Первым уровнем, с которого вы начинаете, часто является ОС. Разработчики ОС обычно выпускают образ, который состоит только из одного или двух слоев, поскольку они предварительно собирают ОС и просто распаковывают ее в один слой образа. В вашем Dockerfile каждая команда обычно создает новый слой, поэтому вы часто будете видеть команды RUN с большим количеством продолжений строк и удалением временных файлов: все, что вы оставляете в слое изображения, остается там навечно, даже если вы удалите его в новом слое. После создания образа веб-сервера все слои становятся доступными только для чтения.
Теперь предположим, что вы запускаете 100 контейнеров своего веб-сервера. Каждый контейнер получает свой собственный редактируемый слой среды выполнения, но, что особенно важно, все контейнеры совместно используют слои изображений веб-сервера — нет необходимости тратить затраты, в 100 раз превышающие требования к хранилищу 1 веб-сервера. Во время работы контейнеры потребляют только новое пространство для хранения артефактов времени выполнения, таких как, возможно, журналы или временные файлы. Как правило, контейнерные приложения разрабатываются таким образом, что эти уровни контейнеров эфемерны и могут быть удалены без последствий.
Говорить об этом выходит за рамки этого ответа, но если ваш контейнер будет создавать важные файлы, которые должны храниться дольше, чем срок службы одного контейнера (например, базы данных), вы должны монтировать «тома» в контейнер во время выполнения. , и эти тома обеспечат безопасное хранение данных отдельно от жизненного цикла образа/контейнера.
СГРУППЫ
Другая функция ядра, которую могут использовать контейнеры, называется «cgroups» или «control groups»: они позволяют вам ограничивать аппаратные ресурсы, доступные группе процессов (например, контейнеру).
По умолчанию док-контейнерам доступны все ресурсы ОЗУ и ЦП, что может быть очень эффективным. В отличие от виртуальных машин, где ресурсы относительно выделены, контейнеры могут масштабироваться вверх и вниз (по вертикали) параллельно друг другу, совместно распределяя ресурсы в соответствии с нагрузкой.
Однако иногда это может быть небезопасно — у приложения может быть скачок нагрузки, потребление слишком большого количества ресурсов и зависание других контейнеров. Предполагая, что это не вредоносное или плохо написанное приложение, хороший способ справиться с этим законным всплеском нагрузки — использовать несколько хостов в кластере с какой-либо системой оркестровки для динамического запуска новых экземпляров ваших контейнеров.
Я думаю, что это должно быть основой для понимания всех других ответов и дополнительной информации, связанной.
Честно говоря, мы не можем сравнить докер с ВМ. Из всех ответов до меня многие из них уже показали такую точку зрения. Но они все еще не смогли сказать это конкретно.
Чтобы сравнить одну вещь с другой, они должны иметь схожую позицию или функциональность, по крайней мере, в своей области.
Ниже я придумываю примерный список пар, который включает все известные мне концепции / программы. Я буду признателен, если кто-то сможет сделать это для всех нас. Спасибо!
Докер - VMWare
libcontainer / runc - гипервизор
Образ Docker - образ ОС VM
Контейнер Docker - VM/ виртуальная машина
Надеюсь, это поможет всем вам. По моему мнению, Docker - это инструмент (основанный на libcontainer/runc), который может каким-то образом переносить инструкции ядра в несколько контейнеров. VMWare - это инструмент (основанный на гипервизоре), который может каким-то образом передавать аппаратные инструкции нескольким экземплярам виртуальной машины.
Вот и все.
На мой взгляд, это зависит, это видно из потребностей вашего приложения, почему вы решили развернуть приложение в Docker, потому что Docker разбивает приложение на мелкие части в соответствии с его функцией, это становится эффективным, потому что, когда одно приложение / функция является ошибкой, оно имеет не влияет на другие приложения, в отличие от использования полной виртуальной машины, он будет медленнее и сложнее по настройке, но в некотором смысле безопаснее, чем докер
Документация докеров (и самообъяснения) проводит различие между "виртуальными машинами" и "контейнерами". Они имеют тенденцию интерпретировать и использовать вещи несколько необычными способами. Они могут это сделать, потому что это их дело, что они пишут в своей документации, и потому что терминология виртуализации еще не совсем точна.
Факт - это то, что документация Docker понимает под "контейнерами", это паравиртуализация (иногда "виртуализация на уровне ОС") в действительности, в отличие от аппаратной виртуализации, которой не является докер.
Docker - это низкокачественное решение для паравиртуализации. Различие между контейнером и виртуальной машиной придумано разработчиками докеров, чтобы объяснить серьезные недостатки их продукта.
Причина, по которой он стал настолько популярным, заключается в том, что они " зажгли огонь простых людей", то есть сделали возможным простое использование типично серверных ( = Linux) сред / программных продуктов на рабочих станциях Win10. Это тоже повод для нас терпеть их маленькие "нюансы". Но это не значит, что мы тоже должны этому верить.
Ситуация становится еще более туманной из-за того, что докеры на хостах Windows использовали встроенный Linux в HyperV, и его контейнеры работали в нем. Таким образом, докер в Windows использует комбинированное решение для оборудования и паравиртуализации.
Короче говоря, контейнеры Docker - это некачественные (пара) виртуальные машины с огромным преимуществом и множеством недостатков.