Docker 基础
欢迎光临我的博客[http://poetize.cn],前端使用Vue2,聊天室使用Vue3,后台使用Spring Boot
Docker 是一个开源的应用容器引擎,基于 Go 语言,并遵从Apache2.0协议开源,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
Docker(Docker 引擎)
组件构成:Docker 客户端(Docker Client)
、Docker 守护进程(Docker daemon)
(细分为containerd
、shim
以及 runc
)。它们共同负责容器的创建和运行。
Docker 引擎的架构示意图:
containerd
:它的主要任务是容器的生命周期管理——start | stop | pause | rm,但是它并不负责创建容器,而是指挥 runc 去做。
containerd-shim
是一个真实运行容器的载体,每启动一个容器都会起一个新的containerd-shim的一个进程,其主要作用是:
- 它允许容器运行时(即 runC)在启动容器之后退出,简单说就是不必为每个容器一直运行一个容器运行时(runC)
- 即使在 containerd 和 dockerd 都挂掉的情况下,容器的标准 IO 和其它的文件描述符也都是可用的
- 向 containerd 报告容器的退出状态
runc
生来只有一个作用——创建容器。runc 与操作系统内核接口进行通信,基于所有必要的工具(Namespace、CGroup等)来创建容器。容器进程作为 runc 的子进程启动,启动完毕后,runc 将会退出。
Docker 架构
Docker 使用客户端-服务器 (C/S) 架构模式
。Docker 容器通过 Docker 镜像来创建。容器与镜像
的关系类似于面向对象编程中的对象与类
。
一个完整的Docker有以下几个部分组成:
- DockerClient客户端
- Docker Daemon守护进程
- Docker Image镜像
- DockerContainer容器
容器技术简介
传统虚拟机,如 VMware , VisualBox 之类的需要模拟整台机器包括硬件
,每台虚拟机都需要有自己的操作系统
。每一台虚拟机包括应用
,必要的二进制和库
,以及一个完整的用户操作系统
。
容器技术是与宿主机共享硬件资源及操作系统
,可以实现资源的动态分配。容器包含应用和其所有的依赖包
,但是与其他容器共享内核
。
容器技术是实现操作系统虚拟化的一种途径,可以让您在资源受到隔离的进程中运行应用程序及其依赖关系
。
Docker Client(客户端)
它其实就是 Docker 提供命令行界面 (CLI) 工具,是许多 Docker 用户与 Docker 进行交互的主要方式。客户端可以构建,运行和停止应用程序,还可以远程与Docker_Host进行交互。最常用的 Docker 客户端就是docker 命令
,我们可以通过 docker 命令很方便地在 host 上构建和运行 docker 容器
。
Docker daemon(服务端)(后台运行程序)
Docker daemon 是服务器组件,以 Linux 后台服务的方式运行,是 Docker 最核心的后台进程,我们也把它称为守护进程
。Docker Daemon 运行在 Docker host 上,负责创建、运行、监控容器
,构建、存储镜像
。
从Docker 1.11之后,Docker Daemon被分成了多个模块以适应OCI标准。
Image(镜像)
Docker 镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置
等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)
。镜像不包含任何动态数据
,其内容在构建之后也不会被改变。
镜像中不包含内核——容器都是共享所在 Docker 主机的内核。所以有时会说容器仅包含必要的操作系统(通常只有操作系统文件和文件系统对象)。
Docker 通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统。上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。
由于 Docker 镜像是多层存储结构,并且可以继承、复用,因此不同镜像可能会因为使用相同的基础镜像,从而拥有共同的层。由于 Docker 使用 Union FS,相同的层只需要保存一份即可,因此实际镜像硬盘占用空间很可能要比这个列表镜像大小的总和要小的多。
Container (容器)
Docker 容器就是 Docker 镜像的运行实例,是真正运行项目程序、消耗系统资源、提供服务的地方。
启动容器之时,让容器运行 Bash Shell(/bin/bash)。这使得 Bash Shell 成为容器中运行的且唯一运行的进程。
如果通过输入 exit 退出 Bash Shell,那么容器也会退出(终止)。
原因是容器如果不运行任何进程则无法存在,杀死 Bash Shell 即杀死了容器唯一运行的进程,导致这个容器也被杀死。
按下Ctrl+P+Q
组合键则会退出容器但并不终止容器运行。这样做会切回到 Docker 主机的 Shell,并保持容器在后台运行。
除非你使用了数据卷(Volume)或数据容器,否则容器内运行期间产生的数据在容器关闭后,又回到你启动容器时的原始镜像状态.
Repository (仓库)
Docker 仓库是集中存放镜像文件的场所。
容器化
完整的应用容器化过程主要分为以下几个步骤。
- 编写应用代码。
- 创建一个
Dockerfile
,其中包括当前应用的描述、依赖以及该如何运行这个应用。 - 对该 Dockerfile 执行
docker image build
命令。 - 等待 Docker 将应用程序构建到 Docker 镜像中。
Dockerfile
- 对当前应用的描述。
- 指导 Docker 完成应用的容器化(创建一个包含当前应用的镜像)。
每个 Dockerfile 文件第一行都是 FROM 指令
。
FROM
指令指定的镜像,会作为当前镜像的一个基础镜像层
,当前应用的剩余内容会作为新增镜像层添加到基础镜像层之上。RUN
后面跟的是一些shell命令,通过&&将这些脚本连接在了一行执行,这么做的原因是为了减少镜像的层数COPY
指令将应用相关文件从构建上下文复制到了当前镜像中,并且新建一个镜像层来存储。Dockerfile
通过WORKDIR
指令,为 Dockerfile 中尚未执行的指令设置工作目录。
该目录与镜像相关,并且会作为元数据记录到镜像配置中,但不会创建新的镜像层
。EXPOSE
指令用于记录应用所使用的网络端口。ENTRYPOINT
指令来指定当前镜像的入口程序。ENTRYPOINT 指定的配置信息也是通过镜像元数据的形式保存下来,而不会新增镜像层
。