- A nebule-friendly Introduction to Containers, VMs and Docker
- By Preethi Kasireddy
- The Nuggets translation Project
- Permanent link to this article: github.com/xitu/gold-m…
- Translator: steinliber
- Proofreader: 7Ethan, Jianboy
From: flipboard.com/topic/conta…
If you’re a developer or technician, you’ve probably heard of Docker: it’s a tool for packaging, transporting, and running apps in “containers.” It is so important that both development and operations people are now looking at this tool. Even big companies like Google, VMware and Amazon are building services to support it.
Whether Docker is immediately available to you or not, I think it’s important to understand some of the basic concepts of “containers” and how they differ from virtual machines (VMS). While there are plenty of good Docker tutorials on the Internet, I don’t see many concept guides for beginners, especially when it comes to container composition. So hopefully this article will help solve the problem 🙂
Let’s start by understanding what virtual machines and containers are.
What are “containers” and “virtual machines”
Containers and virtual machines their purpose is similar: to put an application and its dependencies into a self-contained unit that can run in any environment.
In addition, containers and virtual machines eliminate the need for physical hardware, allowing us to use computing resources more efficiently in terms of energy consumption and cost effectiveness,
The main difference between containers and virtual machines is the way they are architected. Let’s take a closer look.
The virtual machine
A virtual machine is essentially a simulation of a real computer that executes programs just like a real computer. Hypervisor allows a VM to run on a physical machine. Hypervisors can run on a host or “bare metal” machine.
Let’s demystify these terms:
A hypervisor (later called a hypervisor) is the software, firmware, or hardware that allows a virtual machine to run on it. The hypervisor itself runs on the physical machine, called the ** “host” **. Hosts provide resources for VMS, including the RAM and CPU. These resources are divided among virtual machines and can be allocated as needed. So if a virtual machine is running a more resource-intensive application, you can allocate more resources to it than other virtual machines running on the same host.
A virtual machine running on a host (again, through the use of a hypervisor) is often called a “visiting plane.” The client contains the application and all the dependencies (such as system binaries and libraries) needed to run the application. It also comes with a full virtualization hardware stack of its own, including virtualized network adapters, storage, and CPUS – meaning it also has its own full-fledged guest operating system. From the virtual machine internal point of view, the operation of the passenger plane is that its use is their own dedicated resources. Externally, we know that it is a virtual machine – sharing resources provided by the host with other virtual machines.
As mentioned earlier, visitors can run on either a hosted hypervisor or bare-metal hypervisor. There are some important differences.
First, the managed virtualization hypervisor runs on the host operating system. For example, you can install virtual machines (for example, VirtualBox or VMware Workstation 8) on a computer running the OSX operating system. The virtual machine cannot access the hardware directly, so it must be accessed through the operating system running on the host (in our case, the Mac’s OSX operating system).
The advantage of hosting the hypervisor is that the underlying hardware is not that important. The host operating system takes care of the hardware drivers without the need for hypervisors. This approach is therefore considered to have better “hardware compatibility”. On the other hand, this additional layer between the hardware and the hypervisor incurs more resource overhead, which can degrade virtual machine performance.
Bare-metal hypervisor solves this performance problem by installing and running directly on the host hardware. Because it is directly exposed to the underlying hardware, it does not need to run on top of the host’s operating system. In this case, the bare-metal hypervisor is the first installed on the host to run as an operating system. Unlike the managed hypervisor, it has its own device driver that interacts directly with each component to perform any I/O, processing, or operating system-specific tasks. This results in better performance, scalability, and stability. The tradeoff here is that hardware compatibility is limited, since bare-metal hypervisors only have so many device drivers built into them.
After discussing the hypervisor, you may be wondering why we need this extra “hypervisor” layer between the virtual machine and the host.
Well, hypervisors do play an important role in this, and since virtual machines have their own virtual operating systems, hypervisors provide a platform for virtual machines to manage and execute guest operating systems. It allows hosts to share their resources with virtual machines running as clients.
Vm icon
As you can see in the illustration, VMS packages virtual hardware, a kernel (or operating system), and user space for each new VIRTUAL machine.
The container
Unlike virtual machines that provide hardware virtualization, containers provide operating system-level virtualization by abstracting “user space.” You’ll see what I mean when we explain the term container in detail.
For all intents and purposes, the container looks like a virtual machine. For example, they have private space for execution processes, root permission to execute commands, private network interfaces and IP addresses, custom routing and IPtable rules, and file systems to mount.
One important difference between containers and virtual machines is that containers share the kernel of the host system with other containers.
The container is
This diagram shows that the container packages only user space, not the kernel or virtual hardware as a virtual machine does. Each container has its own separate user space to allow multiple containers to run on a single host. We can see that all operating system-level architectures are shared by all containers. The only parts to create from scratch are bins and libs directories. That’s what makes the container so light.
Where did Docker come from?
Docker is an open source project based on Linux container technology. It uses Luinux kernel features such as namespaces and control groups to create containers on the operating system.
Containers are far from a new technology: Google has been using their own container technology for years. Other container technologies including Solaris Zones, BSD Jails, and LXC have been around for years.
So why Docker’s sudden success?
-
Easy to use: Docker makes it easier for anyone (developers, operations, architects, and others) to take advantage of containers to quickly build and test portable applications. It allows anyone to package an application on their laptop and have it run in the public cloud, private cloud or even bare metal without any modifications. Docker’s mantra is “Build once, run everywhere”.
-
Speed: Docker containers are very lightweight and fast. Because containers are just sandbox environments running on the kernel, they take up fewer resources. You can create a Docker container in seconds compared to a virtual machine that might take more time to create because the virtual machine has to boot a full operating system each time.
-
Docker Hub: Docker users can also benefit from the increasingly rich Docker Hub ecosystem, which you can think of as “the app store for Docker images.” Docker Hub has tens of thousands of community-built public images that are always available. It’s easy to search for images that match your needs, you just need to be ready to pull images and almost no modifications are required.
-
Modularity and extensibility: Docker allows you to easily split applications into separate containers by function. For example, your Postgre database can run in one container, your Redis service in another, and your Node.js application in another. With Docker, it’s much easier to link the containers together to create your application, while easily extending and updating individual components in the future.
Last but not least, who doesn’t love Docker’s whale (Docker’s logo)? 🙂
From: www.docker.com/docker-birt…
Basic Docker concepts
Now that we have an overview of Docker, let’s take a look at the basics of Docker in turn:
Docker Engine
Docker Engine is the underlying Docker Engine. It is a lightweight runtime and tool that can be used to manage containers, images, builds, and more. It runs on Linux local machines and consists of the following parts:
- Docker daemon running on the host.
- Docker client, used to communicate with the Docker daemon to execute commands.
- REST API for remote interaction with Docker daemons.
The Docker client
Docker clients are designed to interact with you, the Docker end user. You can think of it as Docker’s UI. Such as:
You’re interacting with a Docker client, and the Docker client passes your instructions to the Docker daemon.
docker build iampeekay/someImage .
Copy the code
Docker daemon
Commands sent to Docker clients are actually executed by Docker daemons (such as build, run, and distribute containers). The Docker daemon runs on the host, but as a user, you can’t directly interact with the daemon. Docker clients can also run on hosts, but this is not required. It can run on different machines and communicate with the Docker daemon running on the host.
Dockerfile
You can write instructions to build Docker images in Dockerfile. These instructions can be:
- RUN apt-get y install some-package: install the software package
- EXPOSE 8000: Exposes a port
- ENV ANT_HOME /usr/local/apache-ant: Pass environment variables
One step further. Once your Dockfile is configured, you can use the Docker build command to build an image from it. Here is an example of a Dockerfile:
Simple Dockerfile:
FROM Ubuntu :14.04 MAINTAINER preethi kasireddy [email protected] # For SSH login and port redirection ENV ENV DEBIAN_FRONTEND noninteractive RUN echo "debconf shared/accepted-oracle-license-v1-1 select true" | debconf-set-selections RUN echo "debconf Shared/accepted - oracle - license - v1-1 seen true "| debconf - set - selections # update RUN apt - get - y # update installation tools/RUN apt-get -y install python3-software-properties \ software-properties-common \ bzip2 \ ssh \ net-tools \ vim \ curl \ expect \ git \ nano \ wget \ build-essential \ dialog \ make \ build-essential \ checkinstall \ bridge-utils \ Virt -viewer \ python-pip \ python-setuptools \ python-dev # NPM RUN curl - sL https://deb.nodesource.com/setup_4.x | sudo bash - E - RUN apt - get the install - y # nodejs add oracle - jdk7 to Ubuntu package warehouse RUN the add apt - repository ppa: webupd8team/Java # ensure that warehouse is the latest RUN echo "deb http://archive.ubuntu.com/ubuntu "> /etc/apt/sources.list # updateapt-get -y update # updateoracle -jdk7 RUN apt-get -y install /usr/lib/ JVM/Java -7-oracle/SSHD RUN apt-get install -y openssh-server RUN mkdir /var/run/sshd RUN echo "root:$ROOTPASSWORD" | chpasswd RUN sed -i 's/PermitRootLogin Without -password/PermitRootLogin yes/' /etc/ssh/sshd_config # RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/ SSHD # exposed RUN mkdir -p /usr/ SRC /my-app WORKDIR /usr/src/my-app /usr/src/my-app RUN NPM install # ADD entryPoint ADD entryPoint. Sh/entryPoint ENTRYPOINT ["/entrypoint.sh"] CMD ["npm", "start"]
Copy the code
Docker mirror
The image built from the instructions in your Dockerfile is a read-only template. The image defines not only the application you want to package and its dependencies, but also the process to run at startup.
Docker images are built using Dockerfile. Each instruction in a Dockerfile adds a new “mirror layer” to the image. The mirror layer represents the part of the mirrored file system that can be added or replaced beneath it. The mirror layer is the key to Docker’s lightweight and powerful structure. Docker uses the Union file system to do this:
Union file system
Docker uses the Union file system to build an image. You can think of a Union file system as a stackable file system, which means that files and directories in different file systems (also known as branches) can transparently form a single file system.
Content with the same path directories within overlapping branches is treated as a single merged directory, avoiding the need to create separate copies for each level. Instead, they are both given Pointers to the same resource; When some mirror layer needs to be changed, it creates a copy and modifies the local copy, leaving the original mirror layer unchanged. This approach makes it look like the file system is writable from the outside but not from the inside. (In other words, a copy-on-write system.)
The hierarchical system provides two main advantages:
- No copy: The image layer helps avoid copying the entire file every time you create or run a container with an image, which makes Docker container instantiation very fast and cheap.
- Mirror layer isolation: Faster when you change an image, Docker updates only propagate to the changed mirror layer.
volume
The volume is the “data part” of the container and is initialized when the container is created. Volumes allow you to persist and share data in containers. The data volumes are separated from the default Union file system in the mirror and exist as normal directories and files on the host file system. So, even if you destroy, update, or rebuild your container, the data volume will remain the same. If you want to update a data volume, you can also make changes to it directly. (An added benefit of this feature is that data volumes can be shared and reused across multiple containers, so it’s neat and elegant.)
Docker container
As mentioned above, the Docker container packs the application’s software and everything it needs to run into an invisible sandbox. This includes the operating system, application code, runtime, system libraries, and so on. Docker containers are built based on Docker images. Because the image is read-only, Docker adds a read-write file system to the image’s read-only file system to create the container.
From: Docker
In addition, Docker takes many steps to create the container. It creates a network interface so that the container and localhost can communicate, appends the available IP address to the container, and runs the process that you specify to run the application when defining the image.
Once the container has been successfully created, you can run it in any environment without making any changes.
Double-click Container
Yo! I’ve covered a lot of parts. One thing that has always intrigued me is how containers are actually implemented, especially since there aren’t any abstract infrastructure boundaries around containers. It’s all worth it after a lot of reading, so here’s my attempt to explain it to you! 🙂
The “container” is really just an abstract concept describing how different functions work together to create a visual “container”. Let’s take a quick look at these features:
1) Namespaces
Namespaces provide containers with their own underlying Linux view, limiting what containers can view and access. When you run a container, Docker creates the namespace that that particular container will use.
Docker uses several different types of namespaces provided in the kernel, such as:
NET: provides the container with a system network stack visible only to itself (for example, its own network devices, IP addresses, IP routing tables, /proc/net directories, port numbers, and so on). B. PID: PID indicates the PROCESS ID. If you’ve ever run ps AUX from the command line to detect the processes running on your system, you’ll see a column called “PID.” The PID namespace provides containers with a view of processes that are visible and interactive only within their own scope. This includes a separate init process (PID 1), which is the “ancestor” of all processes in the container. C. MNT: Give the container its own system “mount” view. Therefore, processes in different mounted namespaces have different views of the file hierarchy. D. UTS: UTS stands for UNIX time-sharing system. It allows processes to recognize system identifiers (that is, host names, domain names, etc.). UTS allows containers to have their own hostname and NIS domain name, independent of other containers and host systems. E. IPC: IPC indicates inter-process communication. The IPC namespace is responsible for isolating IPC resources between running processes in each container. F. USER: This namespace is used to isolate users in each container. Compared to the host system, its function is to have different views of the container in the UID (user ID) and GID (group ID) ranges. Therefore, the Uids and Gids of processes inside the user namespace can be different from those of external hosts, allowing uids outside the container to be non-privileged without sacrificing root privileges to process Uids inside the container.
Docker uses these namespaces together to isolate and start creating containers. The following functions are called control groups.
2) The control group
Control groups (also known as Cgroups) are a Linux kernel feature used to isolate, prioritize, and count the resource usage (CPU, memory, disk I/O, network, and so on) of a group of processes. In this sense, control groups ensure that Docker containers only use the resources they need – and can set limits on the resources that containers can use if needed. The control group also ensures that a single container does not run out of resources and cause the system to crash.
Finally, the Union file system is another feature Docker uses:
3) Isolated Union file systems:
This is described above in the Docker image section 🙂
That’s what the Docker container is all about (of course, the devil is in the implementation details – like how to manage interactions between different components).
The future of Docker: Docker will coexist with virtual machines
While Docker does have a lot of support, I don’t see it as a real threat to virtual machines. Containers will continue to be useful, but there are many situations where virtual machines are better suited.
For example, if you need to run multiple applications on multiple servers, it might make sense to use virtual machines. On the other hand, if you need to run multiple copies of a single app, Docker offers some compelling advantages.
In addition, while containers allow you to split your application into more functional, independent parts to create separation of concerns, it also means that you have more and more parts to manage, which can become unmanageable.
Security is also an area of concern for Docker containers – the separation between containers is thinner due to the shared kernel. A full virtual machine can only make super calls to the host hypervisor, but a Docker container can make system calls to the host kernel, which makes it much more vulnerable. When security is particularly important, developers may opt for virtual machines isolated by abstract hardware – which can make it more difficult for processes to interfere with each other between different virtual machines.
Of course, safety and management issues will certainly evolve as containers are used more in production environments and users review them further. For now, the container versus virtual machine debate is really the best one for people who work with them every day.
conclusion
I hope you now have everything you need to know about Docker and maybe even use it in your projects one day.
As always, please leave a comment in the comments if I have any mistakes or if you have any helpful suggestions! 🙂
If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.
The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.