一. 简介
1. Docker 是什么
Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 OverlayFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。
传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于。
Docker 在容器的基础上,宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。
2.为什么使用 Docker
对比传统虚拟机总结
| 特性 | 容器 | 虚拟机 |
|---|---|---|
| 启动 | 秒级 | 分钟级 |
| 硬盘使用 | 一般为 MB | 一般为 GB |
| 性能 | 接近原生 | 弱于 |
| 系统支持量 | 单机支持上千个容器 | 一般几十个 |
使用 Docker 的优点(熟悉 Docker 的下面应该可以回答为什么,怎么做到的)
- 更高效的利用系统资源
- 更快速的启动时间
- 一致的运行环境
- 持续交付和部署
- 更轻松的迁移
- 更轻松的维护和扩展
二. Docker 的三大基础概念!
Docker 的优点离不开下面的三大概念,理解了下面三点,就能理解 Docker 的整个生命周期
- 镜像(Image)
- 容器(Container)
- 仓库(Repository)
镜像(Image)
对于 Linux 而言,内核启动后,会挂载
root文件系统为其提供用户空间支持。而 Docker 镜像,就相当于是一个root文件系统。比如官方镜像ubuntu:18.04就包含了完整的一套 Ubuntu 18.04 最小系统的root文件系统。
而 Docker 镜像就是一个特殊的文件系统,Docker 在设计时,使用 Union FS 技术设计为分层存储的架构,什么是分层存储呢?
- 镜像在构建的时候,会一层一层的构建,前一层是后一层的基础,每一层构建完之后不会再发生改变。
例如:现在我们想自己构建一个 新镜像,首先我们选取官方镜像 ubuntu:18.04 作为基础镜像 ,然后在里面新建了一个 1kb 的文本文件,此时就在基础镜像上新增了 1kb,这是第二层,然后我们做了删除操作,看上去我们的文件其实是被删除了,其实是在第二层及基础上又加了第三层,刚才的 1kb 文件会一直伴随着镜像,不会更改。
容器(Container)
容器的实质是进程,但是容器与普通线程又有所不同,它可以拥有自己的
root文件系统、自己的网络配置、自己的进程空间。因此容器是运行在一个隔离的环境里的,使用起来就像在一个独立的操作系统下一样。正因为这样隔离的特性,能使宿主机更加安全。
我们可以把镜像看成安装包,把容器看成用镜像创建的一个独立的进程。
-
前面讲过镜像使用的是分层存储,容器也是如此。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为 容器存储层。
-
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
-
按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。
第三点什么意思呢,就是说我们不应该向容器内写入或更改任何东西,把要修改的目录挂载到宿主机,这样我们只需要备份一下配置目录,每次启动容器挂载这个配置目录,之前的所有修改都是不变的,因此不怕容器被删除或者停止,我们一条命令就可以重新拉起配置好的服务。
例如:我们在创建 Mysql:5.7 容器时把 Mysql 的 data 目录挂载到宿主机,此时你创建的数据库和数据库都会保存在宿主机,只需要备份目录,在新的机器上使用同样的命令就能拉起一个一模一样的服务,数据库没有任何变化。
仓库(Repository)
镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。
一个 Docker Registry 中可以包含多个 仓库(Repository);每个仓库可以包含多个 标签(Tag);每个标签对应一个镜像。
以 Ubuntu 镜像 为例,ubuntu 是仓库的名字,其内包含有不同的版本标签,如,16.04, 18.04。我们可以通过 ubuntu:16.04,或者 ubuntu:18.04 来具体指定所需哪个版本的镜像。如果忽略了标签,比如 ubuntu,那将视为 ubuntu:latest。
此外,我们不仅可以使用公开的仓库如官方的 Docker Hub,我们还可以搭建私有的仓库服务。
镜像 -> 容器 -> 仓库 之间的关系
- 镜像(
Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。 - 仓库(
Repository)是集中存放镜像的地方。 - 容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。
举例:我们拉取了一个 nginx 的官方镜像 nginx:latest,此时我们的 Linux 主机上存在一个镜像,然后我们启动这个镜像时,Docker 会根据这个镜像创建一个实例 假设我们命名为 nginx,实例的配置跟你输入的命令参数有关,这个实例就是一个容器,然后我们进入容器 nginx 做出修改。此时我们删除容器,那我我们的修改不会得到保存,而是随着容器一起被销毁。假设我们做出修改后把新的修改容器保存为一个镜像,然后提交到仓库,我们下次就可以直接使用修改后的镜像。