Detailed introduction, Docker image structure and principle

Docker image structure and principle

Detailed introduction, Docker image structure and principle

docker image:

  • Mirror, that is, the template for creating containers, contains the file system and content needed to start the container, so the mirror is mainly used to create and start the container conveniently and quickly
  • The mirror can be created by yourself or on the basis of others' mirrors. The "ubuntu" image we often say is not actually an image name, but represents a Repository named ubuntu. At the same time, there are a series of tagged images under this Repository.

The image contains a layered file system called Union FS (Union FS), which can mount several layers of directories together (just like a layered cake, an onion, and a matryoshka) to form A virtual file system. The directory structure of the virtual file system is just like the directory structure of ordinary Linux. The image provides a Linux virtual environment through these files and the kernel of the host machine. Each layer of the file system is called a layer. The joint file system can set three permissions for each layer of file system, read only (readonly), read and write (readwrite) and write out (whiteout-able), but each layer of file system in the mirror is read-only. When mirroring, starting from a most basic operating system, each construction submission operation is equivalent to making a layer of modification, adding a layer of file system, layer by layer on top, and the upper layer will cover the bottom layer. It’s also very easy to understand, just like the upper layer covers the bottom layer. When using mirroring, we will only see a complete whole. We don’t know how many layers are inside, and we don’t actually need to know what is inside. There are several layers, the structure is as follows:

Note that you must distinguish between images and containers

The term Docker's, a read-only image layer is referred to, a permanent image is not changed, so the image is stateless. The container adds a writable layer above the mirror layer. This writable layer has processes running on the CPU, and has two different states: running state and exiting state. When the container is started, the Docker container enters the running state, and when the container is stopped, it enters the exit state. When there is a running Docker container, from the running state to the stopped state, the state change at this time will be permanently written to the container's file system. Remember that the changes to the container are written to the container's file system, not to the Docker image. The Docker image is read-only and will never change.
​ The same image can start multiple Docker containers, and these containers are all active after they are started, and they are still isolated from each other. Changes made to one of the containers will only be limited to the container itself.

Detailed introduction, Docker image structure and principle

A typical Linux file system is composed of two parts: bootfs and rootfs.
Bootfs (boot file system) mainly includes bootloader and kernel. Bootloader is mainly used to boot and load the kernel. When Linux starts, it will load the bootfs file system. When the boot is loaded, the kernel After being loaded into the memory to take over the control of the system, bootfs will be umount

rootfs (root file system) contains standard directories and files such as /dev, /proc, /bin, /etc in a typical Linux system. Different Linux distributions (such as ubuntu and CentOS) mainly have the rootfs layer The difference.
General mirrors are usually relatively small. The official Ubuntu mirrors are only more than 60MB, while the CentOS base mirrors are only about 200MB. Some other versions of mirrors are even only a few MB. For example, the busybox is only 1.22MB, and the alpine mirror is only about 5M. . The image directly calls the kernel of the host machine, and only the rootfs is provided in the image, that is, it only needs to include the most basic commands, configuration files, and program libraries and other related files.

The figure below shows that there are two different mirrors that implement different rootfs on a host kernel.

Detailed introduction, Docker image structure and principle

In the above figure, Debian and BusyBox provide their own rootfs on the upper layer, and share the Docker Host kernel on the lower layer.

Note: The base image is only consistent with the release version in the user space, the kernel version and the hairstyle version are different, ** the kernel version depends on the host*

[root@docker ~]# uname -r
3.10.0-514.el7.x86_64                 ##Host kernel 为 3.10.0-514
[root@docker ~]# docker run -ti centos    ##启动并进入 CentOS 容器
[root@docker ~]# cat /etc/redhat-release   ##验证容器是 CentOS 7
CentOS Linux release 7.4.1708 (Core)
[root@docker ~]# uname -r      ##容器的 kernel 版本与 Host 一致
3.10.0-514.el7.x86_64

The relationship between container, image and parent image:

Detailed introduction, Docker image structure and principle

Detailed introduction, Docker image structure and principle
As you can see, the new image is generated layer by layer from the base image. Every time a piece of software is installed, a layer is added to the existing image.

The biggest benefit of this is resource sharing

Writable layer of container

When the container starts, a new writable layer is loaded on top of the image. This layer is usually called the "container layer", and the ones below the "container layer" are called the "mirror layer".

Detailed introduction, Docker image structure and principle

All changes to the container-no matter adding, deleting, or modifying files will only happen in the container layer.
Only the container layer is writable, and all mirror layers under the container layer are read-only .
Below we discuss the details of the container layer in depth.

  1. Adding files
    When a file is created in the container, the new file is added to the container layer.
  2. Reading
    a file When reading a file in the container, Docker will look for the file in each image layer from top to bottom. Once found, open and read into memory.
  3. Modifying a file
    When modifying an existing file in the container, Docker will look for the file in each image layer in turn from top to bottom. Once found, immediately copy it to the container layer, and then modify it.
  4. When deleting a file
    in the container, Docker also searches for the file in the image layer from top to bottom. Once found, the delete operation will be recorded in the container layer.

The benefits of docker existence can bring us

1.Detailed introduction, Docker image structure and principle

Now there are two operating systems, Application A and Application B. These two are our most traditional environments. These two operating systems run some dependency packages, and then install the corresponding operating environment or applications on them, and then run some of our applications. So how do we need to optimize this time?

2.Detailed introduction, Docker image structure and principle

We removed the operating system of application B. At this time, application B uses the operating system of application A. The advantage of this is that the operating resources of application B, the operating system itself, are not needed. But it also brings a problem. If we need to make some changes to the operating system, for example: For example, now we want to modify the ip address in the /etc/sysconfig/ file, but application B cannot support the modified IP address , At this time something went wrong, because application B is sharing application A, so the IP has to be changed, and a blank layer needs to be added at this time

3.Detailed introduction, Docker image structure and principle

Add a blank layer, the blank layer has a saying: The application priority is greater than the bottom layer, that is, the priority of the blank layer is greater than all the layers below. In this case, we write a new IP in the blank layer in the application A program, and then Write the old IP that can be supported in the blank layer of the application B program, so that the application A is the new IP and the application B is the old IP without interfering with each other. And each application has its own independent blank layer. These few things are even more perfect. But there is a problem. If application A is down now, the following applications B, C, D, etc. will be forcibly closed, because all applications depend on application A for survival. So this time you have to look at the picture below

4.Detailed introduction, Docker image structure and principle

In order to avoid the downtime of the dependent application and the subsequent shutdown of all dependent applications, we do not use application sharing, but share through mirroring. The application is alive and the mirroring is dead. As long as we do not delete the mirror, it will not be damaged. So our operating system is not supplied by applications or running environments, but by our mirror. The image is a packaged operating environment, so it is already very beautiful, the image of application A will not be broken, the container of application A can also run, and it saves our corresponding operating system-level resources, and different blank layers go Write different new data to ensure that each of our applications can be inconsistent. But at this time, another problem will be discovered, that is, if application A and application B use different mirrors. Doesn’t it take up a lot of storage resources, then let’s see what to do

5.Detailed introduction, Docker image structure and principle

Just through layering, how to understand it is that I am building a LNMP now, the first layer I need a Linux kernel such as our centos 6.8, the second layer we need to install nginx, the third layer we install php, the fourth layer we After installing mysql5.0 version, what should I do if I need a mysql5.5 version one day? At this time, we directly replace the fourth layer and replace it with mysql5.5 version. In this case, an image of ours looks like a file. In fact, it is not a file, but a combination of many, many sub-files, but there are many restrictions on the corresponding number. The limit pool is 128, which means that it cannot exceed 128 layers. For example, I saved a new mirror at this time. This mirror also has many levels, but if there is a layer that is the same as our previous mirror, he will skip this mirror. , Download others directly, which greatly reduces our storage capacity. This is our last step to optimize the tiered storage solution.

#范例:查看镜像的分层结构
[root@ubuntu1804 ~]#docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
8ec398bc0356: Pull complete
a53c868fbde7: Pull complete
79daf9dd140d: Pull complete
Digest: sha256:70821e443be75ea38bdf52a974fd2271babd5875b2b1964f05025981c75a6717
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

#查看镜像分层历史
[root@ubuntu1804 ~]#docker image history nginx
IMAGE        CREATED       CREATED BY               
   SIZE        COMMENT
0901fa9da894     9 days ago     /bin/sh -c #(nop) CMD ["nginx" "-g"
"daemon…  0B         
<missing>      9 days ago     /bin/sh -c #(nop) STOPSIGNAL SIGTERM 
    0B         
<missing>      9 days ago     /bin/sh -c #(nop) EXPOSE 80      
   0B         
<missing>      9 days ago     /bin/sh -c #(nop) ENTRYPOINT ["/docker-
entr…  0B         
<missing>      9 days ago     /bin/sh -c #(nop) COPY
file:0fd5fca330dcd6a7…  1.04kB       
<missing>      9 days ago     /bin/sh -c #(nop) COPY
file:1d0a4127e78a26c1…  1.96kB       
<missing>      9 days ago     /bin/sh -c #(nop) COPY
file:e7e183879c35719c…  1.2kB       
<missing>      9 days ago     /bin/sh -c set -x   && addgroup --
system -…  63.3MB       
<missing>      9 days ago     /bin/sh -c #(nop) ENV
PKG_RELEASE=1~buster   0B         
<missing>      9 days ago     /bin/sh -c #(nop) ENV NJS_VERSION=0.4.2
   0B         
<missing>      9 days ago     /bin/sh -c #(nop) ENV
NGINX_VERSION=1.19.1   0B         
<missing>      5 weeks ago     /bin/sh -c #(nop) LABEL
maintainer=NGINX Do…  0B         
<missing>      5 weeks ago     /bin/sh -c #(nop) CMD ["bash"]    
    0B         
<missing>      5 weeks ago     /bin/sh -c #(nop) ADD
file:4d35f6c8bbbe6801c…  69.2MB

[root@ubuntu1804 ~]#docker inspect nginx
[
 {
    "Id":
"sha256:0901fa9da894a8e9de5cb26d6749eaffb67b373dc1ff8a26c46b23b1175c913a",
    "RepoTags": [
      "nginx:latest"
   ],
    "RepoDigests": [
    
 "nginx@sha256:a93c8a0b0974c967aebe868a186e5c205f4d3bcb5423a56559f2f9599074bbcd"
   ],
    "Parent": "",
    "Comment": "",
    "Created": "2020-07-10T20:26:44.624785651Z",
    "Container":
"348c3ade7f4bdc0366f3f390ea4cfaebfb355ad7d621547eaf73728136d3bd2d",
    "ContainerConfig": {
      "Hostname": "348c3ade7f4b",
      "Domainname": "",
      "User": "",
      "AttachStdin": false,
      "AttachStdout": false,
      "AttachStderr": false,
      "ExposedPorts": {
        "80/tcp": {}
     },
      "Tty": false,
      "OpenStdin": false,
      "StdinOnce": false,
      "Env": [
      
 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "NGINX_VERSION=1.19.1",
        "NJS_VERSION=0.4.2",
        "PKG_RELEASE=1~buster"
     ],
      "Cmd": [
        "/bin/sh",
        "-c",
        "#(nop) ",
        "CMD [\"nginx\" \"-g\" \"daemon off;\"]"
     ],
      "ArgsEscaped": true,
      "Image":
"sha256:8a6dfc8c21a1b3f3679b7755fc7869a22b5f8583778cf7835b5ee5387a73ae5e",
      "Volumes": null,
      "WorkingDir": "",
      "Entrypoint": [
        "/docker-entrypoint.sh"
     ],
      "OnBuild": null,
      "Labels": {
        "maintainer": "NGINX Docker Maintainers <docker-
[email protected]>"
     },
      "StopSignal": "SIGTERM"
   },
    "DockerVersion": "18.09.7",
    "Author": "",
    "Config": {
      "Hostname": "",
      "Domainname": "",
      "User": "",
      "AttachStdin": false,
      "AttachStdout": false,
      "AttachStderr": false,
      "ExposedPorts": {
        "80/tcp": {}
     },
      "Tty": false,
      "OpenStdin": false,
      "StdinOnce": false,
      "Env": [
      
 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "NGINX_VERSION=1.19.1",
        "NJS_VERSION=0.4.2",
        "PKG_RELEASE=1~buster"
     ],
      "Cmd": [
        "nginx",
        "-g",
        "daemon off;"
     ],
      "ArgsEscaped": true,
      "Image":
"sha256:8a6dfc8c21a1b3f3679b7755fc7869a22b5f8583778cf7835b5ee5387a73ae5e",
      "Volumes": null,
      "WorkingDir": "",
      "Entrypoint": [
        "/docker-entrypoint.sh"
     ],
      "OnBuild": null,
      "Labels": {
        "maintainer": "NGINX Docker Maintainers <docker-
[email protected]>"
     },
      "StopSignal": "SIGTERM"
   },
    "Architecture": "amd64",
    "Os": "linux",
    "Size": 132484492,
    "VirtualSize": 132484492,
    "GraphDriver": {
      "Data": {
        "LowerDir":
"/var/lib/docker/overlay2/87dfa2bbff4f392e64e8a2fce11e2d9b8c3fffcfd51c6721ef0103
f7d6b525aa/diff:/var/lib/docker/overlay2/925c1a9c01939d111b3f0576608ad02a09bceea
fb6cad8dd616c24a59151bb25/diff:/var/lib/docker/overlay2/b9fd33e18d7bb7bb29b51ee3
99dfe3f21654fa4a9a086e02dcbc23f34f140c09/diff:/var/lib/docker/overlay2/35c6b8c39
68cdc21b78d4bcd6c192683b47db788db612dee04c5110037eed7af/diff",
        "MergedDir":
"/var/lib/docker/overlay2/23d3c6ecee136afe7137528b0e6997a488b1f277e86c794fa9a70b
5638a5d3f9/merged",
        "UpperDir":
"/var/lib/docker/overlay2/23d3c6ecee136afe7137528b0e6997a488b1f277e86c794fa9a70b
5638a5d3f9/diff",
        "WorkDir":
"/var/lib/docker/overlay2/23d3c6ecee136afe7137528b0e6997a488b1f277e86c794fa9a70b
5638a5d3f9/work"
     },
      "Name": "overlay2"
   },
    "RootFS": {
      "Type": "layers",
      "Layers": [
      
 "sha256:13cb14c2acd34e45446a50af25cb05095a17624678dbafbcc9e26086547c1d74",
      
 "sha256:0e32546a8af0cd04ad451d6a9d22e650e500e5da3636a32648c9f5aca96a0ff7",
      
 "sha256:7ef35766ef7d5d3d958022405b308d5c105b41190e1b63b2037c4055c6950c9e",
      
 "sha256:4856db5e4f59384c413c20c46cd5403a860e1b07c8fdbad24df1ffd9209d44e7",
 "sha256:2808ec4a8ea71c2660284d06cf7e25354b70b58504edb46ac3e705fb7e6ea519"
     ]
   },
    "Metadata": {
      "LastTagTime": "0001-01-01T00:00:00Z"
   }
 }
]

[root@ubuntu1804 ~]#docker save nginx -o nginx.tar

[root@ubuntu1804 ~]#docker images
REPOSITORY     TAG         IMAGE ID      CREATED      
SIZE
nginx        latest       0901fa9da894     3 days ago    
127MB
alpine        3.11.3       e7d92cdc71fe     7 days ago    
 5.59MB
centos       centos8.1.1911   470671670cac     7 days ago    
237MB
busybox       latest       6d5fcfe5ff17     4 weeks ago    
1.22MB
hello-world     latest       fce289e99eb9     12 months ago   
1.84kB

[root@ubuntu1804 ~]#ll -h nginx.tar
-rw------- 1 root root 131M Jul 20 22:33 nginx.tar

[root@ubuntu1804 ~]#tar xf nginx.tar -C /data

[root@ubuntu1804 ~]#ll /data
total 60
drwxr-xr-x  8 root root  4096 Jul 20 22:34 ./
drwxr-xr-x 24 root root  4096 Jul 20 16:23 ../
-rw-r--r--  1 root root  7510 Jul 11 04:26
0901fa9da894a8e9de5cb26d6749eaffb67b373dc1ff8a26c46b23b1175c913a.json
drwxr-xr-x  2 root root  4096 Jul 11 04:26
0bb74fcd4b686412f7993916e58c26abd155fa10b10a4dc09a778e7c324c39a2/
drwxr-xr-x  2 root root  4096 Jul 11 04:26
517e3239147277447b60191907bc66168963e0ce8707a6a33532f7c63a0d2f12/
drwxr-xr-x  2 root root  4096 Jul 11 04:26
68c9e9da52d5a57ee196829ce4a461cc9425b0b920689da9ad547f1da13dbc9d/
drwxr-xr-x  2 root root  4096 Jul 11 04:26
d2cf0fc540bb3be33ee7340498c41fd4fc82c6bb02b9955fca2109e599301dbd/
drwxr-xr-x  2 root root  4096 Jul 11 04:26
f4bf863ecdbb8bddb4b3bb271bdd97b067dcb6c95c56f720018abec6af190c6e/
drwx------  2 root root 16384 Mar 18 09:49 lost+found/
-rw-r--r--  1 root root  509 Jan  1  1970 manifest.json
-rw-r--r--  1 root root   88 Jan  1  1970 repositories

[root@ubuntu1804 ~]#cat /data/manifest.json
[{"Config":"0901fa9da894a8e9de5cb26d6749eaffb67b373dc1ff8a26c46b23b1175c913a.jso
n","RepoTags":["nginx:latest"],"Layers":
["d2cf0fc540bb3be33ee7340498c41fd4fc82c6bb02b9955fca2109e599301dbd/layer.tar","f
4bf863ecdbb8bddb4b3bb271bdd97b067dcb6c95c56f720018abec6af190c6e/layer.tar","517e
3239147277447b60191907bc66168963e0ce8707a6a33532f7c63a0d2f12/layer.tar","0bb74fc
d4b686412f7993916e58c26abd155fa10b10a4dc09a778e7c324c39a2/layer.tar","68c9e9da52
d5a57ee196829ce4a461cc9425b0b920689da9ad547f1da13dbc9d/layer.tar"]}]
[root@ubuntu1804 ~]#du -sh /data/*
8.0K
/data/0901fa9da894a8e9de5cb26d6749eaffb67b373dc1ff8a26c46b23b1175c913a.json
16K /data/0bb74fcd4b686412f7993916e58c26abd155fa10b10a4dc09a778e7c324c39a2
16K /data/517e3239147277447b60191907bc66168963e0ce8707a6a33532f7c63a0d2f12
16K /data/68c9e9da52d5a57ee196829ce4a461cc9425b0b920689da9ad547f1da13dbc9d
70M /data/d2cf0fc540bb3be33ee7340498c41fd4fc82c6bb02b9955fca2109e599301dbd
62M /data/f4bf863ecdbb8bddb4b3bb271bdd97b067dcb6c95c56f720018abec6af190c6e
16K /data/lost+found
4.0K /data/manifest.json
4.0K /data/repositories
[root@ubuntu1804 ~]#cd
/data/d2cf0fc540bb3be33ee7340498c41fd4fc82c6bb02b9955fca2109e599301dbd/
[root@ubuntu1804
d2cf0fc540bb3be33ee7340498c41fd4fc82c6bb02b9955fca2109e599301dbd]#ls
json layer.tar VERSION
[root@ubuntu1804
d2cf0fc540bb3be33ee7340498c41fd4fc82c6bb02b9955fca2109e599301dbd]#tar xf
layer.tar
[root@ubuntu1804
d2cf0fc540bb3be33ee7340498c41fd4fc82c6bb02b9955fca2109e599301dbd]#ls
bin  dev home layer.tar lib64 mnt proc run  srv tmp var
boot etc json lib    media opt root sbin sys usr VERSION
[root@ubuntu1804
d2cf0fc540bb3be33ee7340498c41fd4fc82c6bb02b9955fca2109e599301dbd]#cat etc/i
init.d/  issue   issue.net 
[root@ubuntu1804
d2cf0fc540bb3be33ee7340498c41fd4fc82c6bb02b9955fca2109e599301dbd]#cat etc/issue
Debian GNU/Linux 10 \n \l

Guess you like

Origin blog.51cto.com/13887323/2551061