Docker --- 理论及面试题
1. Docker 理论
1.1 官方文档
1. 官方文档
https://docs.docker.com/install/linux/docker-ce/centos/
2. Docker Hub
https://hub.docker.com
1.2 发展历程
Docker是一个开源的应用容器引擎,使用Go语言开发,基于Linux内核的cgroup,namespace,Union FS等技术,对应用进程进行封装隔离,并且独立于宿主机与其他进程,这种运行时封装的状态称为容器。
Linux容器是与系统其他部分隔离开的一系列进程,从另一个镜像运行,并由该镜像提供支持进程所需的全部文件。容器提供的镜像包含了应用的所有依赖项,因而在从开发到测试再到生产的整个过程中,它都具有可移植性和一致性。
1. 容器不就是虚拟化吗
是,但也不竟然。虚拟化使得许多操作系统可同时在单个系统上运行。容器则可共享同一个操作系统内核,将应用进程与系统其他部分隔离开。
2. 容器和虚拟化的区别
ux容器技术,容器虚拟化和kvm虚拟化的区别 kvm虚拟化: 需要硬件的支持,需要模拟硬件,可以运行不同的操作系统,启动时间分钟级(开机启动流程)
linux开机启动流程: bios开机硬件自检 basic input output system 根据bios设置的优先启动项boot 网卡 硬盘 u盘 光驱 读取mbr引导 2T UEFI(gpt分区) mbr硬盘分区信息,内核加载路径,
加载内核 启动第一个进程/sbin/init systemd 系统初始化完成 运行服务(nginx,httpd,mysql)
容器启动流程: 共用宿主机内核: 第一个进程直接启动服务(nginx,httpd,mysql)
容器:共用宿主机内核,轻量级,损耗少,启动快,性能高,只能运行在linux系统上 虚拟机:需要硬件的支持,需要模拟硬件,需要走开机启动流程,可以运行不同的操作系统
1.3 架构图



1.4 三大核心要素概念
1. 镜像
Docker镜像(Image) 就是一个只读模板,镜像可以用来创建Docker容器,一个镜像可以创建很多容器.
它也相当于是一个root文件系统.比如官方镜像 centos:7 就包含了完整的一套 centos:7 最小系统的root文件系统,相当于容器的"源代码",
1. 镜像的分层
2. 容器
镜像的运行时,可以对外提供服务,本质上是利用namespace和cgroup等技术再宿主机中创建的独立的虚拟空间
3. 仓库
用来存放镜像的仓库,我们可以将镜像发布到仓库中,需要的时候再从仓库中拉下来就可以了
仓库分为公开仓库(Public)和私有仓库(Private)两种形式
最大的公开仓库是Docker Hub
国内的公开仓库包括阿里云、网易云等
1.5 工作原理
Docker 是一个 Client-Server 架构的系统,Docker守护进程运行在主机上,然后通过Socket连接到客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器.
1.6 整体架构及底层通信原理



Docker 是一个 C/S模式的架构,后端是一个松耦合架构,众多模块各司其职
# Docker 运行的基本流程:
1. 用户使用Docker Client 与 Docker Daemon 建立通信,并发送请求给后者
2. Docker Daemon 作为 Docker 架构中的主体部分,首先提供 Docker Server 的功能使其可以接受 Docker Client的请求
3. Docker Engine 执行 Docker 内部的一些列工作,每一项工作都是以一个 Job 的形式存在
4. Job 的运行过程中,当需要容器镜像时,则从 Docker Registry中下载镜像,并通过镜像管理驱动 Graph driver 将下载镜像以 Graph的形式存储
5.当需要为Docker 创建网络环境时,通过网络管理驱动 Network driver 创建并配置Docker 容器网络环境
6.当需要限制 Docker 容器运行资源或执行用户指令等操作时,则通过 Exec driver 来完成
7. Libcontainer 是一项独立的容器管理包, Network driver 以及 Exec driver 都是通过 Libcontainer 来实现具体对容器进行的操作
1.7 为什么会出现(开发时的痛点)
在开发过程中,开发环境具有特定的配置,其他开发人员身处的环境配置也各有不同,假如正在开发的引用依赖于当前配置且还要依赖于某些配置文件,同时企业还拥有一套标准化的测试和生产环境,则会导致开发和部署的版本,环境,配置问题
环境配置相当麻烦,换一台机器就要重来一次,费时费力
Docker之所以发展如此迅速,也是因为它对此给出了一个标准化的解决方案----系统平滑移植即容器虚拟化技术
1.8 理念
Docker就是通过Linux的容器技术的基础上发展过来的,将应用达成镜像,通过镜像成为运行在Docker容器上面的实例,而Docker容器在任何操作系统上都是移植的,这就实现了跨平台,跨服务器,一次镜像,处处运行
1.9 容器技术和虚拟机技术比较
传统虚拟机技术是基于安装在主操作系统上的虚拟机管理系统(如:VirtualBox和VMWare等),创建虚拟机(虚拟出各种硬件),在虚拟机上安装 从 操作系统,在从操作系统中安装部署各种应用
# 虚拟机技术的缺点:
1. 资源占用多
2. 冗余步骤多
3. 启动慢
由于上述虚拟机技术存在很多缺点,Linux发展出了另一种虚拟化技术:Linux容器(Linux Containers,缩写为LXC)
Linux容器是与系统其他部分隔离开的一系列进程,从另一个镜像运行,并由该镜像提供共支持进程所需的全部文件,容器提供的镜像包含了应用的所有依赖项,因此在开发到测试再到生产的整个过程中,它都具有可移植性和一致性
Linux容器不是模拟一套完整的操作系统而是对进程进行隔离,有了容器,就可以将软件运行所需的所有资源打包到一个隔离的容器中,容器与虚拟机不同,不需要捆绑一整套操作系统,只需要软件工作时所需的库资源和配置,系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一的运行
# 容器技术的优点:
Docker容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统虚拟机则是在硬件层面实现虚拟化.与传统的虚拟机相比,Docker优势体现为启动速度快,占用体积小
# 总结:
1. 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程
2. 容器内的应用进程直接运行与宿主的内核,容器内没有自己的内核且也没有进行硬件虚拟,因此容器要比传统虚拟机更为轻便
3. 每个容器之间相互隔离,每个容器有自己的文件系统,容器之间进程不会相互影响,能区分计算资源
# 1. Docker 有着比虚拟机更少的抽象层
由于 Docker 不需要 Hypervisor(虚拟机) 实现硬件资源虚拟化,运行在 Docker容器 上的程序直接使用的都是实际物理机的硬件资源,因此在CPU、内存利用率上 Docker 将会在效率上有明显优势
# 2. Docker 利用的是宿主机的内核,而不需要加载操作系统OS内核
当新建一个容器时, Docker 不需要和虚拟机一样重新加载一个操作系统内核.进而避免引寻、加载操作系统内核返回等比较费时费资源的过程,当创建一个虚拟机时,虚拟机软件需要加载OS, 返回新建过程是分钟级别的.而 Docker 由于直接利用宿主机的操作系统,则省略了返回过程,因此新建一个 Docker 容器只需要几秒钟
1.10 容器带来的好处
1. 更快速的应用交付和部署(只需交付少量容器文件,在正式生产环境加载镜像并运行即可,应用安装配置在镜像内已经完成,大大节省部署配置和测试验证时间)
2. 更便捷的升级和扩缩容(当现有的容器不足以支撑业务处理时,可通过镜像运行新的容器进行快速扩容,使应用系统的扩容从原来的天级变成分钟级甚至秒级)
3. 更简单的系统运维(生产测试开发环境高度一致,当出现程序异常时可以通过测试环境的相同容器进行快速定位和回复)
4. 更高效的计算资源利用(Docker是内核级虚拟化,不像传统的虚拟化技术一样需要额外的Hypervisor支持,所以在一台物理机上可以运行很多个容器实例,大大提升物理服务器的CPU和内存利用率)
1.11 镜像的分层
1. 镜像的分层现象
当拉取镜像的过程中,可以看到Docker的镜像是一层一层的在下载

2. 镜像底层原理(UnionFS -- 联合文件系统)
UnionFS (联合文件系统): 是一种分层、轻量级且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统(unite several directories into a single virtual filesystem)下.
Union 文件系统是Docker 镜像的基础,镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像
# 特性
一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
3. 镜像的加载原理

Docker 的镜像实际上由一层一层的文件系统组成,这种层级的文件系统为UnionFS
bootfs(boot file system) 主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker 镜像的最底层是引导文件系统bootfs. 这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核,当boot 加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bottfs.
rootfs在bootfs之上,包含的就是典型Linux系统中的/dev /proc /bin /etc 等标准目录和文件,rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等
# 在虚拟机中的CentOS都是好几个G,为什么docker这里才200M?
对于一个精简的OS,rootfs可以很小,只包含最基本的命令 工具和程序库就可以了,因为底层用Host的kernel,自己只需要提供rootfs就行了,由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以共用bootfs
3. 镜像分层的好处
复用,节省磁盘空间,相同的内容只需加载一份到内存。 修改dockerfile之后,再次构建速度快
4. 容器和镜像的关系
当容器启动时,一个新的可写层被加载到镜像的顶部.这一层通常被称作"容器层","容器层"之下的都叫"镜像层"
所有对容器的改动--无论添加、删除、修改文件都只会发生在容器层中,只有容器层是可写的,容器层下面的所有镜像层都是只读的
2. 面试题
1. 怎么查看镜像、容器
docker system df
2. Docker 的虚悬镜像是什么

# 虚悬镜像
仓库名和标签都是 <none> 的镜像,称之为虚悬镜像(dangling image)
Docker 在构建镜像的时候可能会出现问题,则会出现这种虚悬镜像,这种虚悬镜像是没有任何作用的,建议删除
python防脱发技巧

浙公网安备 33010602011771号