- Docker
- 什么是Docker
- Docker基本架构
- Docker元素
- 镜像
- 容器
- Dockerfile
- Dockerfile命令
- 从Dockfile命令看镜像分层
- 修改时复制策略 copy-on-write (CoW)
- Copying makes containers efficient
- 参考链接
Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production
Docker 是一个用于开发、传送和运行应用程序的开放平台。 Docker 使您能够将应用程序与基础设施分开,以便您可以快速交付软件。 使用 Docker,您可以像管理应用程序一样管理基础设施。 通过利用 Docker 的快速交付、测试和部署代码的方法,您可以显着减少编写代码和在生产中运行代码之间的延迟。
Docker基本架构Docker uses a client-server architecture. The Docker client talks to the Docker daemon, which does the heavy lifting of building, running, and distributing your Docker containers. The Docker client and daemon can run on the same system, or you can connect a Docker client to a remote Docker daemon. The Docker client and daemon communicate using a REST API, over UNIX sockets or a network interface. Another Docker client is Docker Compose, that lets you work with applications consisting of a set of containers.
Docker 使用客户端-服务器架构。 Docker 客户端与 Docker 守护进程对话,后者负责构建、运行和分发 Docker 容器的繁重工作。 Docker 客户端和守护程序可以在同一系统上运行,或者您可以将 Docker 客户端连接到远程 Docker 守护程序。 Docker 客户端和守护进程使用 REST API、UNIX 套接字或网络接口进行通信。 另一个 Docker 客户端是 Docker Compose,它允许您使用由一组容器组成的应用程序。
Docker元素 镜像An image is a read-only template with instructions for creating a Docker container. Often, an image is based on another image, with some additional customization. For example, you may build an image which is based on the ubuntu image, but installs the Apache web server and your application, as well as the configuration details needed to make your application run.
You might create your own images or you might only use those created by others and published in a registry. To build your own image, you create a Dockerfile with a simple syntax for defining the steps needed to create the image and run it. Each instruction in a Dockerfile creates a layer in the image. When you change the Dockerfile and rebuild the image, only those layers which have changed are rebuilt. This is part of what makes images so lightweight, small, and fast, when compared to other virtualization technologies.
镜像是一个只读模板,包含创建 Docker 容器的说明。 通常,一个镜像基于另一个镜像,并带有一些额外的自定义。 例如,您可以构建一个基于 ubuntu 镜像的镜像,并安装 Apache Web 服务器和您的应用程序,以及使您的应用程序运行所需的配置详细信息。
您可以创建自己的镜像,也可以仅使用其他人创建并在注册表中发布的镜像。 要构建您自己的镜像,您需要使用简单的语法创建一个 Dockerfile,用于定义创建镜像和运行镜像所需的步骤。 Dockerfile 中的每条指令都会在镜像中创建一个层。 当您更改 Dockerfile 并重建映像时,只会重建那些已更改的层。 与其他虚拟化技术相比,这是使映像如此轻巧、小巧和快速的部分原因。
容器A container is a runnable instance of an image. You can create, start, stop, move, or delete a container using the Docker API or CLI. You can connect a container to one or more networks, attach storage to it, or even create a new image based on its current state.
By default, a container is relatively well isolated from other containers and its host machine. You can control how isolated a container’s network, storage, or other underlying subsystems are from other containers or from the host machine.
A container is defined by its image as well as any configuration options you provide to it when you create or start it. When a container is removed, any changes to its state that are not stored in persistent storage disappear.
容器是镜像的可运行实例。 您可以使用 Docker API 或 CLI 创建、启动、停止、移动或删除容器。 您可以将容器连接到一个或多个网络,为其附加存储,甚至可以根据其当前状态创建新镜像。
默认情况下,容器与其他容器及其主机相对隔离。 您可以控制容器的网络、存储或其他底层子系统与其他容器或主机之间的隔离程度。
容器由其镜像以及您在创建或启动它时提供给它的任何配置选项定义。 当容器被移除时,未存储在持久存储中的对其状态的任何更改都会消失。
Dockerfile Dockerfile命令在 Dockerfile 文件的存放目录下,执行构建动作。
以下示例,通过目录下的 Dockerfile 构建一个 nginx:v3(镜像名称:镜像标签)。
docker build -t nginx:v3 .
-
FROM: 定制的镜像都是基于 FROM 的镜像,后续的操作都是基于 该镜像,并且后续的操作每一行都会新建一层镜像层。
-
RUN: 用于执行后面跟着的命令行命令,有以下两个格式
-
shell:
RUN <命令行命令> # <命令行命令> 等同于,在终端操作的 shell 命令。
-
exec:
RUN ["可执行文件", "参数1", "参数2"] # 例如: # RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
-
-
COPY: 复制指令,从上下文目录中复制文件或者目录到容器指定路径
COPY [--chown=
: ] <源路径1>... <目标路径> COPY [--chown= : ] ["<源路径1>",... "<目标路径>"] -
ADD: ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:
优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
等等等等,不在赘述
从Dockfile命令看镜像分层Docker 镜像由一系列层构建而成。 每一层代表镜像的 Dockerfile 中的一条指令。 除了最后一层之外,每一层都是只读的。 考虑以下 Dockerfile:
# syntax=docker/dockerfile:1 FROM ubuntu:18.04 LABEL org.opencontainers.image.authors="org@example.com" COPY . /app RUN make /app RUN rm -r $HOME/.cache CMD python /app/app.py
这个 Dockerfile 包含四个命令。修改文件系统的命令会创建一个层。 FROM 语句首先从 ubuntu:18.04 镜像创建一个层。 LABEL 命令仅修改镜像的元数据,不会生成镜像层。 COPY 命令从 Docker 客户端的当前目录添加一些文件。第一个 RUN 命令使用 make 命令构建您的应用程序,并将结果写入新层。第二个 RUN 命令删除缓存目录,并将结果写入新层。最后,CMD 指令指定在容器内运行命令(运行docker run命令时触发),它只修改镜像的元数据,不会产生镜像层。
每一层只是与它之前的层的有差异。请注意,添加和删除文件都会产生一个新层。在上面的例子中,$HOME/.cache 目录被删除了,但在上一层仍然可用,并且加起来就是镜像的总大小。请参阅 Best practices for writing Dockerfiles and use multi-stage builds 部分优化Dockerfile以获得更高效的镜像
这些层堆叠在彼此的顶部。当您创建一个新容器时,您会在镜像层之上添加一个新的可写层。这一层通常被称为“容器层”。对正在运行的容器所做的所有更改,例如写入新文件、修改现有文件和删除文件,都将写入这个薄的可写容器层。下图显示了一个基于 ubuntu:15.04 镜像的容器。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ewZinZMY-1636533770869)(D:resourcepicturecontainer-layers.jpg)]
容器和镜像之间的主要区别在于顶部可写层。 添加新数据或修改现有数据的所有写入容器都存储在此可写层中。 当容器被删除时,可写层也被删除。 底层镜像保持不变。
因为每个容器都有自己的可写容器层,所有的变化都存储在这个容器层中,所以多个容器可以共享对同一个底层镜像的访问,同时又拥有自己的数据状态。 下图显示了共享同一个 Ubuntu 15.04 镜像的多个容器。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m88f9vdP-1636533770870)(D:resourcepicturesharing-layers.jpg)]
修改时复制策略 copy-on-write (CoW)docker通过一个叫做copy-on-write (CoW) 的策略来保证base镜像的安全性,以及更高的性能和空间利用率。
Copy-on-write is a strategy of sharing and copying files for maximum efficiency. If a file or directory exists in a lower layer within the image, and another layer (including the writable layer) needs read access to it, it just uses the existing file. The first time another layer needs to modify the file (when building the image or running the container), the file is copied into that layer and modified. This minimizes I/O and the size of each of the subsequent layers. These advantages are explained in more depth below.
Copying makes containers efficientWhen you start a container, a thin writable container layer is added on top of the other layers. Any changes the container makes to the filesystem are stored here. Any files the container does not change do not get copied to this writable layer. This means that the writable layer is as small as possible.
When an existing file in a container is modified, the storage driver performs a copy-on-write operation. The specifics steps involved depend on the specific storage driver. For the aufs, overlay, and overlay2 drivers, the copy-on-write operation follows this rough sequence:
Search through the image layers for the file to update. The process starts at the newest layer and works down to the base layer one layer at a time. When results are found, they are added to a cache to speed future operations.
Perform a copy_up operation on the first copy of the file that is found, to copy the file to the container’s writable layer.
Any modifications are made to this copy of the file, and the container cannot see the read-only copy of the file that exists in the lower layer.
Btrfs, ZFS, and other drivers handle the copy-on-write differently. You can read more about the methods of these drivers later in their detailed descriptions.
Containers that write a lot of data consume more space than containers that do not. This is because most write operations consume new space in the container’s thin writable top layer.
简单的说,启动容器的时候,最上层容器层是可写层,之下的都是镜像层,只读层。
当容器需要读取文件的时候
从最上层镜像开始查找,往下找,找到文件后读取并放入内存,若已经在内存中了,直接使用。(即,同一台机器上运行的docker容器共享运行时相同的文件)。
当容器需要添加文件的时候
直接在最上面的容器层可写层添加文件,不会影响镜像层。
当容器需要修改文件的时候
从上往下层寻找文件,找到后,复制到容器可写层,然后,对容器来说,可以看到的是容器层的这个文件,看不到镜像层里的文件。容器在容器层修改这个文件。
当容器需要删除文件的时候
从上往下层寻找文件,找到后在容器中记录删除。即,并不会真正的删除文件,而是软删除。这将导致镜像体积只会增加,不会减少。
综上,Docker镜像通过分层实现了资源共享,通过copy-on-write实现了文件隔离。
参考链接https://www.runoob.com/docker/docker-dockerfile.html
https://docs.docker.com/storage/storagedriver/
https://www.cnblogs.com/woshimrf/p/docker-container-lawyer.html



