简单理解Docker

什么是Docker

Docker使用Go语言进行开发实现,基于Linux内核的cgroupnamespace,以及AUFS类的Union FS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术

由于隔离的进程独立于宿主和其他的隔离的进程,因此也称其为容器

Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极
大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。

基本概念

  • 镜像 (Image)
  • 容器 (Container)
  • 仓库 (Repository)

镜像

Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

在 Docker 设计时,就充分利用 Union FS 的技术,将其设计为分层存储的架构。

镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。

容器

镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层

任何保存于容器存储层的信息都会随容器删除而丢失。

容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。

使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。

仓库

仓库是一个集中的存储、分发镜像的服务

一个 Docker Registry 中可以包含多个仓库( Repository );每个仓库可以包含多个标签( Tag );每个标签对应一个镜像。

镜像的实现原理

每个镜像都由很多层次构成,Docker 使用 Union FS 将这些不同的层结合到一个镜像中去。

通常 Union FS 有两个用途, 一方面可以实现不借助 LVM、RAID 将多个 disk 挂到同一个目录下,另一个更常用的就是将一个只读的分支和一个可写的分支联合在一起,Live CD 正是基于此方法可以允许在镜像不变的基础上允许用户在其上进行一些写操作。

Docker 在 AUFS 上构建的容器也是利用了类似的原理。

Docker数据管理

在容器中管理数据主要有两种方式:

  • 数据卷(Volumes)
  • 挂载主机目录 (Bind mounts)

数据卷

数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:

  • 数据卷 可以在容器之间共享和重用
  • 对 数据卷 的修改会立马生效
  • 对 数据卷 的更新,不会影响镜像
  • 数据卷 默认会一直存在,即使容器被删除

挂载主机目录

  • 挂载一个主机目录作为数据卷
  • 挂载一个本地主机文件作为数据卷

Docker底层实现

Docker 底层的核心技术包括 Linux 上的命名空间(Namespaces)控制组(Control groups)Union 文件系统(Union file systems)容器格式(Container format)

我们知道,在操作系统中,包括内核、文件系统、网络、PID、UID、IPC、内存、硬盘、CPU 等等,所有的资源都是应用进程直接共享的。 要想实现虚拟化,除了要实现对内存、CPU、网络IO、硬盘IO、存储空间等的限制外,还要实现文件系统、网络、PID、UID、IPC等等的相互隔离。 前者相对容易实现一些,后者则需要宿主机系统的深入支持。

随着 Linux 系统对于命名空间功能的完善实现,程序员已经可以实现上面的所有需求,让某些进程在彼此隔离的命名空间中运行。大家虽然都共用一个内核和某些运行时环境(例如一些系统命令和系统库),但是彼此却看不到,都以为系统中只有自己的存在。这种机制就是容器(Container)利用命名空间来做权限的隔离控制,利用 cgroups 来做资源分配

基本架构

Docker 采用了 C/S 架构,包括客户端服务端Docker 守护进程 ( Daemon )作为服务端接受来自客户端的请求,并处理这些请求(创建、运行、分发容器)

客户端和服务端既可以运行在一个机器上,也可通过 socket 或者 RESTful API 来进行通信。

Docker 守护进程一般在宿主主机后台运行,等待接收来自客户端的消息。
Docker 客户端则为用户提供一系列可执行命令,用户用这些命令实现跟 Docker 守护进程交互。

命名空间

命名空间是 Linux 内核一个强大的特性。每个容器都有自己单独的命名空间,运行在其中的应用都像是在独立的操作系统中运行一样。命名空间保证了容器之间彼此互不影响。

  • pid 命名空间
  • net 命名空间
  • ipc 命名空间
  • mnt 命名空间
  • uts 命名空间
  • user 命名空间

控制组

控制组(cgroups)是 Linux 内核的一个特性,主要用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,才能避免当多个容器同时运行时的对系统资源的竞争。

控制组可以提供对容器的内存、CPU、磁盘 IO 等资源的限制和审计管理。

联合文件系统

联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。

联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

Docker 中使用的 AUFS(AnotherUnionFS)就是一种联合文件系统。 AUFS 支持为每一个成员目录(类似 Git 的分支)设定只读(readonly)、读写(readwrite)和写出(whiteoutable)权限, 同时 AUFS 里有一个类似分层的概念, 对只读权限的分支可以逻辑上进行增量地修改(不影响只读部分的)。

Docker 目前支持的联合文件系统包括 OverlayFS , AUFS , Btrfs , VFS , ZFSDevice Mapper

在可能的情况下,推荐使用overlay2 存储驱动overlay2 是目前 Docker 默认的存储驱动,以前则是aufs

容器格式

使用 runCcontainerd

网络

Docker 的网络实现其实就是利用了 Linux 上的网络命名空间虚拟网络设备(特别是 veth pair

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值