Вопрос: Как Docker отличается от виртуальной машины?


Я продолжаю перечитывать документация Докера попытаться понять разницу между докером и полной виртуальной машиной. Как он может обеспечить полную файловую систему, изолированную сетевую среду и т. Д., Не будучи столь же тяжелым?

Почему развертывание программного обеспечения на образ докеров (если это правильный термин) проще, чем просто развертывание в последовательную производственную среду?


2841


источник


Ответы:


Первоначально использовался докер Контейнеры LinuX (LXC), но позже переключился на RunC (ранее известный как libcontainer ), который работает в той же операционной системе, что и ее хост. Это позволяет ему совместно использовать множество ресурсов операционной системы хоста. Кроме того, он использует многоуровневую файловую систему ( Aufs ) и управляет сетью.

AuFS - это многоуровневая файловая система, поэтому вы можете иметь только часть для чтения и часть записи, которые объединены вместе. Можно было бы, чтобы общие части операционной системы были доступны только для чтения (и делились между всеми вашими контейнерами), а затем давали каждому контейнеру собственное монтирование для записи.

Итак, скажем, у вас есть изображение контейнера объемом 1 ГБ; если вы хотите использовать полную виртуальную машину, вам нужно иметь 1 ГБ раз x количество виртуальных машин, которые вы хотите. С Docker и AuFS вы можете разделить основную часть 1 ГБ между всеми контейнерами, и если у вас 1000 контейнеров, у вас все еще может быть только 1 ГБ пространства для ОС контейнеров (при условии, что все они работают с одним и тем же изображением ОС) ,

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

Для полной виртуализованной системы обычно требуется несколько минут, тогда как контейнеры Docker / LXC / runC занимают секунды и часто даже меньше секунды.

Для каждого типа виртуализованной системы существуют плюсы и минусы. Если вам нужна полная изоляция с гарантированными ресурсами, полная виртуальная машина - это путь. Если вы просто хотите изолировать процессы друг от друга и хотите запустить тонну из них на узле с разумным размером, то Docker / LXC / runC, похоже, подходит.

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

Почему развертывание программного обеспечения на образ докеров (если это правильный термин) проще, чем просто развертывание в последовательную производственную среду?

Развертывание согласованной производственной среды легче сказать, чем сделать. Даже если вы используете такие инструменты, как шеф-повар а также Кукольный , всегда есть обновления ОС и другие вещи, которые меняются между хостами и средами.

Docker дает вам возможность мгновенно снимать ОС с общего образа и упрощает развертывание на других хостах Docker. Локально, dev, qa, prod и т. Д .: все тот же образ. Конечно, вы можете сделать это с помощью других инструментов, но не так легко и быстро.

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

Из комментариев ...

Интересно! Полагаю, меня все еще смущает понятие «моментальный снимок ОС». Как делать это без, ну, создавая образ ОС?

Хорошо, посмотрим, смогу ли я объяснить. Вы начинаете с базового изображения, а затем вносите свои изменения и фиксируете эти изменения с помощью docker и создаете изображение. Это изображение содержит только отличия от базы. Когда вы хотите запустить свое изображение, вам также понадобится база, и она сложит ваше изображение поверх базы с использованием многоуровневой файловой системы: как упоминалось выше, Docker использует AUFS. AUFS объединяет разные слои вместе, и вы получаете то, что хотите; вам просто нужно запустить его. Вы можете продолжать добавлять все больше и больше изображений (слоев), и оно будет продолжать сохранять только различия. Поскольку Docker обычно строит поверх готовых изображений из реестр , вам редко приходится «снимок» всего себя.


2756



Хорошие ответы. Чтобы получить представление изображения контейнера против VM, взгляните на приведенный ниже.

enter image description here

Источник: https://www.docker.com/what-container#/package_software


329



Возможно, было бы полезно понять, как виртуализация и контейнеры работают на низком уровне. Это прояснит многое.

Примечание. Я немного упрощаю описание ниже. См. Ссылки для получения дополнительной информации.

Как виртуализация работает на низком уровне?

В этом случае диспетчер VM берет на себя процессорное кольцо 0 (или «корневой режим» в новых процессорах) и перехватывает все привилегированные вызовы, сделанные гостевой ОС, чтобы создать иллюзию, что гостевая ОС имеет свое собственное оборудование. Забавный факт: до 1998 года считалось невозможным достичь этого в архитектуре x86, потому что не было никакого способа сделать такой перехват. Люди в VMWare были первыми у которого была идея переписать исполняемые байты в памяти для привилегированных вызовов гостевой ОС для достижения этого.

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

Как контейнеры работают на низком уровне?

Вокруг 2006 , люди, включая некоторых сотрудников Google, внедрили новую функцию уровня ядра, называемую Пространства имен (однако идея длинный до существует во FreeBSD ). Одна из функций ОС - разрешить совместное использование глобальных ресурсов, таких как сеть и диск, для процессов. Что делать, если эти глобальные ресурсы были обернуты в пространствах имен, чтобы они были видны только тем процессам, которые выполняются в одном пространстве имен? Скажем, вы можете получить кусок диска и поместить его в пространство имен X, а затем процессы, запущенные в пространстве имен Y, не могут увидеть или получить к нему доступ. Аналогично, процессы в пространстве имен X не могут получить доступ к чему-либо в памяти, которая распределена для пространства имен Y. Конечно, процессы в X не могут видеть или говорить с процессами в пространстве имен Y. Это обеспечивает вид виртуализации и изоляции для глобальных ресурсов. Так работает докер: каждый контейнер работает в своем собственном пространстве имен, но использует точно одна и та же как все остальные контейнеры. Изоляция происходит, потому что ядро ​​знает пространство имен, которое было назначено процессу, и во время вызовов API он гарантирует, что процесс сможет обращаться к ресурсам только в своем собственном пространстве имен.

Ограничения контейнеров против VM должны быть очевидны сейчас: вы не можете запускать совершенно другую ОС в контейнерах, например, в виртуальных машинах. Однако вы Можно запускают разные дистрибутивы Linux, потому что они используют одно и то же ядро. Уровень изоляции не такой сильный, как у VM. Фактически, для «гостевого» контейнера был способ захвата узла в ранних реализациях. Также вы можете видеть, что при загрузке нового контейнера вся новая копия ОС запускается не так, как в VM. Все контейнеры делиться тем же ядром , Вот почему контейнеры легкие. Кроме того, в отличие от виртуальной машины, вам не нужно заранее выделять значительную часть памяти в контейнеры, потому что у нас нет новой копии ОС. Это позволяет запускать тысячи контейнеров на одной ОС, в то время как изолировать их, что может быть невозможно, если мы запускаем отдельную копию ОС в своей собственной виртуальной машине.


284



I like Ken Cochrane's answer.

But I want to add additional point of view, not covered in detail here. In my opinion Docker differs also in whole process. In contrast to VMs, Docker is not (only) about optimal resource sharing of hardware, moreover it provides a "system" for packaging application (Preferable but not a must, as a set of Microservices).

To me it fits in the gap between Developer Oriented tools like rpm, debian packages, maven, npm + git on one side and Ops tools like Puppet, VMWare, Xen you name it...

Why is deploying software to a docker image (if that's the right term) easier than simply deploying to a consistent production environment?

Your question assumes some consistent production environment. But how to keep it consistent? Consider some amount (>10) of servers and applications, stages in the pipeline. To keep this in sync you'll start to use something like Puppet, Chef or your own provisioning scripts, unpublished rules and/or lot of documentation... In theory servers can run indefinitely, and be kept completely consistent and up to date. Practice fails to manage a server's configuration completely, so there is considerable scope for configuration drift, and unexpected changes to running servers.

So there is a known pattern to avoid this, the so called Immutable Server. But the immutable server pattern was not loved. Mostly because of the limitations of VM's it was used before Docker. Dealing with several Gigabytes big images, moving those big images around, just to change some fields in the app, was very very laborious. Understandable...

With a Docker ecosystem, you will never need to move around Gigabytes on "small changes" (Thanks aufs and Registry) and you don't need to worry about losing performance by packaging applications into a Docker container on runtime. You don't need to worry about versions of that image. And finally you will even often be able to reproduce complex production environments even on your linux laptop (don't call me if doesn't work in your case ;))

And of course you can start docker containers in VMs (it's a good idea). Reduce your server provisioning on VM level. All the above could be managed by Docker.

P.S. Meanwhile Docker uses its own implementation "libcontainer" instead of LXC. But LXC is still usable.


277



Docker isn't a virtualization methodology. It relies on other tools that actually implement container-based virtualization or operating system level virtualization. For that, Docker was initially using LXC driver, then moved to libcontainer which is now renamed as runc. Docker primarily focuses on automating the deployment of applications inside application containers. Application containers are designed to package and run a single service, whereas system containers are designed to run multiple processes, like virtual machines. So, Docker is considered as a container management or application deployment tool on containerized systems.

In order to know how it is different from other virtualizations, let's go through virtualization and its types. Then, it would be easier to understand what's the difference there.

Virtualization

In its conceived form, it was considered a method of logically dividing mainframes to allow multiple applications to run simultaneously. However, the scenario drastically changed when companies and open source communities were able to provide a method of handling the privileged instructions in one way or another and allow for multiple operating systems to be run simultaneously on a single x86 based system.

Hypervisor

The hypervisor handles creating the virtual environment on which the guest virtual machines operate. It supervises the guest systems and makes sure that resources are allocated to the guests as necessary. The hypervisor sits in between the physical machine and virtual machines and provides virtualization services to the virtual machines. To realize it, it intercepts the guest operating system operations on the virtual machines and emulates the operation on the host machine's operating system.

The rapid development of virtualization technologies, primarily in cloud, has driven the use of virtualization further by allowing multiple virtual servers to be created on a single physical server with the help of hypervisors, such as Xen, VMware Player, KVM, etc., and incorporation of hardware support in commodity processors, such as Intel VT and AMD-V.

Types of Virtualization

The virtualization method can be categorized based on how it mimics hardware to a guest operating system and emulates guest operating environment. Primarily, there are three types of virtualization:

  • Emulation
  • Paravirtualization
  • Container-based virtualization

Emulation

Emulation, also known as full virtualization runs the virtual machine OS kernel entirely in software. The hypervisor used in this type is known as Type 2 hypervisor. It is installed on the top of host operating system which is responsible for translating guest OS kernel code to software instructions. The translation is done entirely in software and requires no hardware involvement. Emulation makes it possible to run any non-modified operating system that supports the environment being emulated. The downside of this type of virtualization is additional system resource overhead that leads to decrease in performance compared to other types of virtualizations.

Emulation

Examples in this category include VMware Player, VirtualBox, QEMU, Bochs, Parallels, etc.

Paravirtualization

Paravirtualization, also known as Type 1 hypervisor, runs directly on the hardware, or “bare-metal”, and provides virtualization services directly to the virtual machines running on it. It helps the operating system, the virtualized hardware, and the real hardware to collaborate to achieve optimal performance. These hypervisors typically have a rather small footprint and do not, themselves, require extensive resources.

Examples in this category include Xen, KVM, etc.

Paravirtualization

Container-based Virtualization

Container-based virtualization, also know as operating system-level virtualization, enables multiple isolated executions within a single operating system kernel. It has the best possible performance and density and features dynamic resource management. The isolated virtual execution environment provided by this type of virtualization is called container and can be viewed as a traced group of processes.

Container-based virtualization

The concept of a container is made possible by the namespaces feature added to Linux kernel version 2.6.24. The container adds its ID to every process and adding new access control checks to every system call. It is accessed by the clone() system call that allows creating separate instances of previously-global namespaces.

Namespaces can be used in many different ways, but the most common approach is to create an isolated container that has no visibility or access to objects outside the container. Processes running inside the container appear to be running on a normal Linux system although they are sharing the underlying kernel with processes located in other namespaces, same for other kinds of objects. For instance, when using namespaces, the root user inside the container is not treated as root outside the container, adding additional security.

The Linux Control Groups (cgroups) subsystem, next major component to enable container-based virtualization, is used to group processes and manage their aggregate resource consumption. It is commonly used to limit memory and CPU consumption of containers. Since a containerized Linux system has only one kernel and the kernel has full visibility into the containers, there is only one level of resource allocation and scheduling.

Several management tools are available for Linux containers, including LXC, LXD, systemd-nspawn, lmctfy, Warden, Linux-VServer, OpenVZ, Docker, etc.

Containers vs Virtual Machines

Unlike a virtual machine, a container does not need to boot the operating system kernel, so containers can be created in less than a second. This feature makes container-based virtualization unique and desirable than other virtualization approaches.

Since container-based virtualization adds little or no overhead to the host machine, container-based virtualization has near-native performance

For container-based virtualization, no additional software is required, unlike other virtualizations.

All containers on a host machine share the scheduler of the host machine saving need of extra resources.

Container states (Docker or LXC images) are small in size compared to virtual machine images, so container images are easy to distribute.

Resource management in containers is achieved through cgroups. Cgroups does not allow containers to consume more resources than allocated to them. However, as of now, all resources of host machine are visible in virtual machines, but can't be used. This can be realized by running top or htop on containers and host machine at the same time. The output across all environments will look similar.


118



Through this post we are going to draw some lines of differences between VMs and LXCs. Let's first define them.

VM:

A virtual machine emulates a physical computing environment, but requests for CPU, memory, hard disk, network and other hardware resources are managed by a virtualization layer which translates these requests to the underlying physical hardware.

In this context the VM is called as the Guest while the environment it runs on is called the host.

LXCs:

Linux Containers (LXC) are operating system-level capabilities that make it possible to run multiple isolated Linux containers, on one control host (the LXC host). Linux Containers serve as a lightweight alternative to VMs as they don’t require the hypervisors viz. Virtualbox, KVM, Xen, etc.

Now unless you were drugged by Alan (Zach Galifianakis- from the Hangover series) and have been in Vegas for the last year, you will be pretty aware about the tremendous spurt of interest for Linux containers technology, and if I will be specific one container project which has created a buzz around the world in last few months is – Docker leading to some echoing opinions that cloud computing environments should abandon virtual machines (VMs) and replace them with containers due to their lower overhead and potentially better performance.

But the big question is, is it feasible?, will it be sensible?

a. LXCs are scoped to an instance of Linux. It might be different flavors of Linux (e.g. a Ubuntu container on a CentOS host but it’s still Linux.) Similarly, Windows-based containers are scoped to an instance of Windows now if we look at VMs they have a pretty broader scope and using the hypervisors you are not limited to operating systems Linux or Windows.

b. LXCs have low overheads and have better performance as compared to VMs. Tools viz. Docker which are built on the shoulders of LXC technology have provided developers with a platform to run their applications and at the same time have empowered operations people with a tool that will allow them to deploy the same container on production servers or data centers. It tries to make the experience between a developer running an application, booting and testing an application and an operations person deploying that application seamless, because this is where all the friction lies in and purpose of DevOps is to break down those silos.

So the best approach is the cloud infrastructure providers should advocate an appropriate use of the VMs and LXC, as they are each suited to handle specific workloads and scenarios.

Abandoning VMs is not practical as of now. So both VMs and LXCs have their own individual existence and importance.


116



Most of the answers here talk about virtual machines. I'm going to give you a one-liner response to this question that has helped me the most over the last couple years of using Docker. It's this:

Docker is just a fancy way to run a process, not a virtual machine.

Now, let me explain a bit more about what that means. Virtual machines are their own beast. I feel like explaining what Docker is will help you understand this more than explaining what a virtual machine is. Especially because there are many fine answers here telling you exactly what someone means when they say "virtual machine". So...

A Docker container is just a process (and its children) that is compartmentalized using cgroups inside the host system's kernel from the rest of the processes. You can actually see your Docker container processes by running ps aux on the host. For example, starting apache2 "in a container" is just starting apache2 as a special process on the host. It's just been compartmentalized from other processes on the machine. It is important to note that your containers do not exist outside of your containerized process' lifetime. When your process dies, your container dies. That's because Docker replaces pid 1 inside your container with your application (pid 1 is normally the init system). This last point about pid 1 is very important.

As far as the filesystem used by each of those container processes, Docker uses UnionFS-backed images, which is what you're downloading when you do a docker pull ubuntu. Each "image" is just a series of layers and related metadata. The concept of layering is very important here. Each layer is just a change from the layer underneath it. For example, when you delete a file in your Dockerfile while building a Docker container, you're actually just creating a layer on top of the last layer which says "this file has been deleted". Incidentally, this is why you can delete a big file from your filesystem, but the image still takes up the same amount of disk space. The file is still there, in the layers underneath the current one. Layers themselves are just tarballs of files. You can test this out with docker save --output /tmp/ubuntu.tar ubuntu and then cd /tmp && tar xvf ubuntu.tar. Then you can take a look around. All those directories that look like long hashes are actually the individual layers. Each one contains files (layer.tar) and metadata (json) with information about that particular layer. Those layers just describe changes to the filesystem which are saved as a layer "on top of" its original state. When reading the "current" data, the filesystem reads data as though it were looking only at the top-most layers of changes. That's why the file appears to be deleted, even though it still exists in "previous" layers, because the filesystem is only looking at the top-most layers. This allows completely different containers to share their filesystem layers, even though some significant changes may have happened to the filesystem on the top-most layers in each container. This can save you a ton of disk space, when your containers share their base image layers. However, when you mount directories and files from the host system into your container by way of volumes, those volumes "bypass" the UnionFS, so changes are not stored in layers.

Networking in Docker is achieved by using an ethernet bridge (called docker0 on the host), and virtual interfaces for every container on the host. It creates a virtual subnet in docker0 for your containers to communicate "between" one another. There are many options for networking here, including creating custom subnets for your containers, and the ability to "share" your host's networking stack for your container to access directly.

Docker is moving very fast. Its documentation is some of the best documentation I've ever seen. It is generally well-written, concise, and accurate. I recommend you check the documentation available for more information, and trust the documentation over anything else you read online, including Stack Overflow. If you have specific questions, I highly recommend joining #docker on Freenode IRC and asking there (you can even use Freenode's webchat for that!).


89



Docker encapsulates an application with all its dependencies, a virtualizer encapsulates an O.S. that can run any applications it can normally run on a bare metal machine.


57



They both are very different. Docker is lightweight and uses LXC/libcontainer (which relies on kernel namespacing and cgroups) and does not have machine/hardware emulation such as hypervisor, KVM. Xen which are heavy.

Docker and LXC is meant more for sandboxing, containerization, and resource isolation. It uses the host OS's (currently only Linux kernel) clone API which provides namespacing for IPC, NS (mount), network, PID, UTS, etc.

What about memory, I/O, CPU, etc.? That is controlled using cgroups where you can create groups with certain resource (CPU, memory, etc.) specification/restriction and put your processes in there. On top of LXC, Docker provides a storage backend (http://www.projectatomic.io/docs/filesystems/) e.g., union mount filesystem where you can add layers and share layers between different mount namespaces.

This is a powerful feature where the base images are typically readonly and only when the container modifies something in the layer will it write something to read-write partition (a.k.a. copy on write). It also provides many other wrappers such as registry and versioning of images.

With normal LXC you need to come with some rootfs or share the rootfs and when shared, and the changes are reflected on other containers. Due to lot of these added features, Docker is more popular than LXC. LXC is popular in embedded environments for implementing security around processes exposed to external entities such as network and UI. Docker is popular in cloud multi-tenancy environment where consistent production environment is expected.

A normal VM (for example, VirtualBox and VMware) uses a hypervisor, and related technologies either have dedicated firmware that becomes the first layer for the first OS (host OS, or guest OS 0) or a software that runs on the host OS to provide hardware emulation such as CPU, USB/accessories, memory, network, etc., to the guest OSes. VMs are still (as of 2015) popular in high security multi-tenant environment.

Docker/LXC can almost be run on any cheap hardware (less than 1 GB of memory is also OK as long as you have newer kernel) vs. normal VMs need at least 2 GB of memory, etc., to do anything meaningful with it. But Docker support on the host OS is not available in OS such as Windows (as of Nov 2014) where as may types of VMs can be run on windows, Linux, and Macs.

Here is a pic from docker/rightscale : Here is a pic from rightscale


45



1. Lightweight

This is probably the first impression for many docker learners.

First, docker images are usually smaller than VM images, makes it easy to build, copy, share.

Second, Docker containers can start in several milliseconds, while VM starts in seconds.

2. Layered File System

This is another key feature of Docker. Images have layers, and different images can share layers, make it even more space-saving and faster to build.

If all containers use Ubuntu as their base images, not every image has its own file system, but share the same underline ubuntu files, and only differs in their own application data.

3. Shared OS Kernel

Think of containers as processes!

All containers running on a host is indeed a bunch of processes with different file systems. They share the same OS kernel, only encapsulates system library and dependencies.

This is good for most cases(no extra OS kernel maintains) but can be a problem if strict isolations are necessary between containers.

Why it matters?

All these seem like improvements, not revolution. Well, quantitative accumulation leads to qualitative transformation.

Think about application deployment. If we want to deploy a new software(service) or upgrade one, it is better to change the config files and processes instead of creating a new VM. Because Creating a VM with updated service, testing it(share between Dev & QA), deploying to production takes hours, even days. If anything goes wrong, you got to start again, wasting even more time. So, use configuration management tool(puppet, saltstack, chef etc.) to install new software, download new files is preferred.

When it comes to docker, it's impossible to use a newly created docker container to replace the old one. Maintainance is much easier!Building a new image, share it with QA, testing it, deploying it only takes minutes(if everything is automated), hours in the worst case. This is called immutable infrastructure: do not maintain(upgrade) software, create a new one instead.

It transforms how services are delivered. We want applications, but have to maintain VMs(which is a pain and has little to do with our applications). Docker makes you focus on applications and smooths everything.


21



In relation to:-

"Why is deploying software to a docker image easier than simply deploying to a consistent production environment ?"

Most software is deployed to many environments, typically a minimum of three of the following:

  1. Individual developer PC(s)
  2. Shared developer environment
  3. Individual tester PC(s)
  4. Shared test environment
  5. QA environment
  6. UAT environment
  7. Load / performance testing
  8. Live staging
  9. Production
  10. Archive

There are also the following factors to consider:

  • Developers, and indeed testers, will all have either subtlely or vastly different PC configurations, by the very nature of the job
  • Developers can often develop on PCs beyond the control of corporate or business standardisation rules (e.g. freelancers who develop on their own machines (often remotely) or contributors to open source projects who are not 'employed' or 'contracted' to configure their PCs a certain way)
  • Some environments will consist of a fixed number of multiple machines in a load balanced configuration
  • Many production environments will have cloud-based servers dynamically (or 'elastically') created and destroyed depending on traffic levels

As you can see the extrapolated total number of servers for an organisation is rarely in single figures, is very often in triple figures and can easily be significantly higher still.

This all means that creating consistent environments in the first place is hard enough just because of sheer volume (even in a green field scenario), but keeping them consistent is all but impossible given the high number of servers, addition of new servers (dynamically or manually), automatic updates from o/s vendors, anti-virus vendors, browser vendors and the like, manual software installs or configuration changes performed by developers or server technicians, etc. Let me repeat that - it's virtually (no pun intended) impossible to keep environments consistent (okay, for the purist, it can be done, but it involves a huge amount of time, effort and discipline, which is precisely why VMs and containers (e.g. Docker) were devised in the first place).

So think of your question more like this "Given the extreme difficulty of keeping all environments consistent, is it easier to deploying software to a docker image, even when taking the learning curve into account ?". I think you'll find the answer will invariably be "yes" - but there's only one way to find out, post this new question on Stack Overflow.


16



Docker, basically containers, supports OS virtualization i.e. your application feels that it has a complete instance of an OS whereas VM supports hardware virtualization. You feel like it is a physical machine in which you can boot any OS.

In Docker, the containers running share the host OS kernel, whereas in VMs they have their own OS files. The environment (the OS) in which you develop an application would be same when you deploy it to various serving environments, such as "testing" or "production".

For example, if you develop a web server that runs on port 4000, when you deploy it to your "testing" environment, that port is already used by some other program, so it stops working. In containers there are layers; all the changes you have made to the OS would be saved in one or more layers and those layers would be part of image, so wherever the image goes the dependencies would be present as well.

In the example shown below, the host machine has three VMs. In order to provide the applications in the VMs complete isolation, they each have their own copies of OS files, libraries and application code, along with a full in-memory instance of an OS. Without Containers Whereas the figure below shows the same scenario with containers. Here, containers simply share the host operating system, including the kernel and libraries, so they don’t need to boot an OS, load libraries or pay a private memory cost for those files. The only incremental space they take is any memory and disk space necessary for the application to run in the container. While the application’s environment feels like a dedicated OS, the application deploys just like it would onto a dedicated host. The containerized application starts in seconds and many more instances of the application can fit onto the machine than in the VM case. enter image description here

Source: https://azure.microsoft.com/en-us/blog/containers-docker-windows-and-trends/


16