文章首发于我的 github 仓库-cv算法工程师成长之路,欢迎关注我的公众号-嵌入式视觉。
本人水平有限,文章如有问题,欢迎及时指出。如果看完文章有所收获,一定要先点赞后收藏。毕竟,赠人玫瑰,手有余香。
一,Docker 简介
1.1,什么是 Docker
Docker
使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 OverlayFS 类的 Union FS 等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。Docker容器与虚拟机类似,但二者在原理上不同。容器是将操作系统层虚拟化,虚拟机则是虚拟化硬件,因此容器更具有便携性、能更高效地利用服务器。
专业名词 Docker
有两个意思:
- 代指整个 Docker 项目。
- 代指 Docker 引擎。
Docker
引擎(Docker Engine)是指一个服务端-客户端结构的应用,主要有这些部分:Docker 守护进程、Docker Engine API(页面存档备份,存于互联网档案馆)、Docker 客户端。
1.2,Docker 与虚拟机的区别
- 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程。
- Docker 容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
特性 | Docker | 虚拟机 |
---|---|---|
启动 | 秒级 | 分钟级 |
硬盘使用 | 一般为 MB | 一般为 GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
1.3,Docker 架构
runc 是一个 Linux 命令行工具,用于根据 OCI容器运行时规范 创建和运行容器。
containerd 是一个守护程序,它管理容器生命周期,提供了在一个节点上执行容器和管理镜像的最小功能集。
1.4,为什么用 Docker
Docker 作为一种新的虚拟化技术,跟传统的虚拟化技术相比具有众多的优势:
- 更高效的利用系统资源:不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。
- 更快速的启动时间:Docker 容器应用直接运行于宿主内核,不需要启动完整的操作系统,所以启动时间可做到秒级的启动时间。
- 一致的运行环境:Docker 镜像提供了除内核外完整的运行时环境,确保开发环境、测试环境、生产环境的一致性。
- 持续交付和部署:开发人员可以通过 Dockerfile 来进行镜像构建,并结合持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合持续部署(Continuous Delivery/Deployment) 系统进行自动部署。
- 更轻松的迁移:Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。
- 更轻松的维护和扩展。
二,Docker 基本概念
Docker 三个基本概念:
- 镜像(Image)
- 容器(Container)
- 仓库(Repository)
2.1,镜像
操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:18.04 就包含了完整的一套 Ubuntu 18.04 最小系统的 root 文件系统。
Docker 镜像 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像 不包含 任何动态数据,其内容在构建之后也不会被改变。
Docker 镜像并非是像一个 ISO
那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。其被设计为分层存储的架构,镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。
2.2,容器
镜像(Image
)和容器(Container
)的关系,类似面向对象程序设计中的类和实例的关系。可以把 Docker容器(Container) 看做是一个简易版的 Linux 环境(包括 root 用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。它可以被启动、开始、停止、 删除。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的 命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。
容器和镜像一样都是使用分层存储,每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。
2.3,仓库
镜像构建完成后,可以很容器的在当前宿主主机上运行,但是如果需要在其他服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,即仓库(Repository)-集中存放镜像的地方。
Docker
仓库(Registry
) 分为公开仓库(Public
)和私有仓库(Private
)两种形式。目前 Docker
官方维护了一个公共仓库 Docker Hub,其中已经包括了数量超过 2,650,000 的镜像。大部分需求都可以通过在 Docker Hub
中直接下载镜像来实现。
有时候使用 Docker Hub
这样的公共仓库可能不方便,用户可以创建一个本地仓库供私人使用。Docker Registry 是官方提供的工具,可以用于构建私有的镜像仓库。
一个 Docker Registry
中可以包含多个仓库(Repository
);每个仓库可以包含多个标签(Tag
);每个标签对应一个镜像。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签>
的格式来指定具体是这个软件哪个版本的镜像。如:ubuntu: 14.04
、ubuntu: 16.04
等等。
$ docker image ls ubuntu
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 18.04 329e