Docker容器初识

什么是 Docker?

Docker 最初是 dotCloud 公司创始人在法国期间发起的一个公司内部项目,它是基于dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。 在 2013 年底,dotCloud 公司决定改名为 Docker。Docker 最初是在 Ubuntu 12.04 上开发实现的;Red Hat 则从 RHEL 6.5 开始对 Docker 进行支持。

Docker 使用 Google 公司推出的 Go 语言进行开发实现,基于操作系统内核中的 Cgroup(资源控制)、Namespace(资源隔离)与 OverlayFS(数据存储)等技术,实现基于操作系统层面的(应用)虚拟化技术。

最初实现是基于 LXC 技术,从 0.7 版本以后开始去除 LXC,转而使用自行开发的libcontainer(容器管理技术)。

Docker发行版本

Docker 从 1.13.x 版本开始,版本分为企业版 EE 和社区版 CE,版本号也改为按照时间线来发布,比如 17.03 就是 2017 年 3 月,有点类似于 ubuntu 的版本发布方式。

Docker EE(企业版),Docker CE(社区版)

Docker 基本实现原理

通过三个方面实现容器化技术的前置:

​ (1)操作系统的 NameSpace 隔离系统资源技术,通过隔离网络、PID 进程、系统信号量、文件系统挂载、主机名与域名, 来实现在同一宿主机系统中,运行不同的容器,而每个容器之间相互隔离运行互不干扰

​ (2)使用系统的 Cgroups 系统资源配额功能, 限制资源包括: CPU、Memory、Blkio(块设备)、Network。

​ (3)通过 OverlayFS 数据存储技术, 实现容器镜像的物理存储与新建容器存储。

Linux NameSpace

当一台物理主机(宿主机)运行容器的时候, 为了避免容器所需系统资源之间相互干扰。所以 Docker 利用操作系统的隔离技术-NameSpace, 来实现在同一个操作系统中,不同容器之间的资源独立运行。 Linux Namespace 是 Linux 系统提供的一种资源隔离机制,可实现系统资源隔离的列表如下:

    Mount - 用于隔离文件系统的挂载点 

    UTS - 用于隔离 HostName 和 DomianName 

    IPC - 用于隔离进程间通信 

    PID - 用于隔离进程 ID 

    Network - 用于隔离网络 

    User - 用于隔离用户和用户组 UID/GID 

查看系统资源隔离

[root@node111 ~]#ps aux | grep ssh
root      10495  0.0  0.0 112756  4352 ?        Ss   Sep15   0:00 /usr/sbin/sshd -D
root      32003  0.8  0.0 159236  5944 ?        Ss   17:52   0:00 sshd: root@pts/0
root      32153  0.0  0.0 112712   976 pts/0    S+   17:52   0:00 grep --color=auto ssh
[root@node111 ~]# ll /proc/10495/ns/
total 0
lrwxrwxrwx 1 root root 0 Sep 21 17:54 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 Sep 21 17:54 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 Sep 21 17:54 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 Sep 21 17:54 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 Sep 21 17:54 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Sep 21 17:54 uts -> uts:[4026531838]

Cgroups (资源控制)

在操作系统解决了资源相互隔离的问题以后,还需要解决资源限制的问题,也就是避免在同一个操作系统中,防止有些资源消耗较大的容器,将整个物理机器(宿主机)的硬件资源(CPU, Memory) 占满

Linux 系统中能够控制的资源列表如下:

Memory - 内存限制 
hugetlb - huge pages 使用量 
cpu - CPU使用率 
cpuacct - CPU使用率 
cpuset - 绑定cgroups到指定CPUs和NUMA节点 
innodb_lock_wait_timeout - block设备的IO速度 
net_cls - 网络接口设置优先级 
devices - mknode访问设备权限 
freezer - suspend和restore cgroups进程 
perf_event - 性能监控 
pids - 限制子树cgroups总进程数

系统实现的限制资源

[root@node111 ~]#cat /proc/cgroups
#subsys_name	hierarchy	num_cgroups	enabled
cpuset	10	78	1
cpu	4	261	1
cpuacct	4	261	1
memory	7	261	1
devices	11	261	1
freezer	6	78	1
net_cls	5	78	1
blkio	3	261	1
perf_event	2	78	1
hugetlb	8	78	1
pids	9	261	1
net_prio	5	78	1

OverlayFS

OverlayFS 是一种堆叠文件系统,它依赖并建立在其它的文件系统之上(例如 ext4fs 和 xfs 等),并不直接参与磁盘空间结构的划分,仅仅将原来系统文件中的文件或者目录进行"合并一起", 最后向用户展示"合并"的文件是在同一级的目录, 这就是联合挂载技术, 相对于 AUFS(<1.12 早期使用的存储技术), OverlayFS 速度更快,实现更简单。

Linux 内核为 Docker 提供的 OverlayFS 驱动有两种:Overlay 和 Overlay2。而 Overlay2 是相对于 Overlay 的一种改进,在 Inode 利用率方面比 Overlay 更有效。但是 Overlay 有环境需求:Docker 版本 17.06.02+,宿主机文件系统需要是 EXT4 或 XFS 格式

OverlayFS 实现方式

OverlayFS 通过三个目录:lower 目录、upper 目录、以及 work 目录实现,其中 lower 目录可以是多个, upper 目录为可以进行读写操作的目录, work 目录为工作基础目录,挂载后内容会被清空,且在使用过程中其内容用户不可见,最后联合挂载完成给用户呈现的统一视图称为merged 目录。

Overlay2 命令行挂载操作
创建文件
[root@node111 ~]#mkdir /lower{1..3}
[root@node111 ~]#mkdir /upper /merged

挂载upper
[root@node111 ~]#mount -t overlay overlay -o lowerdir=/lower1:/lower2:/lower3,upperdir=/upper,workdir=/work /merged

upper写入文件
[root@node111 ~]#touch /upper/upper.txt

/upper目录中写入文件,在 merged 中可以显示
[root@node111 ~]#ll /merged/
total 0
-rw-r--r-- 1 root root 0 Sep 21 18:25 upper.txt

merged 中写入文件, 实际存储到了/uppper
[root@node111 ~]#touch /merged/merged.txt
[root@node111 ~]#ll /upper/
total 0
-rw-r--r-- 1 root root 0 Sep 21 18:25 merged.txt
-rw-r--r-- 1 root root 0 Sep 21 18:25 upper.txt
[root@node111 ~]#umount /merged

如果没有upperdir,merged是只读的
[root@node111 ~]#mount -t overlay overlay -o lowerdir=/lower1:/lower2 /merged
[root@node111 ~]#touch /merged/lower.txt
touch: cannot touch ‘/merged/lower.txt’: Read-only file system

NameSpace、Cgroup 与 OverlayFS 关系

在操作系统中, 可以根据宿主机的资源情况,创建不同应用与数量不同的容器。每个容器的 CPU、Memory、Network 由系统的内核 NameSpace 进行隔离, 相互之间不影响。

为了防止某个正在运行的容器大量占用宿主机的系统资源(CPU、Memory、Network), 那么将由操作系统的 Cgroups 功能进行资源限制(防止独占)。

容器运行的基础是需要镜像,并且新容器的运行也是需要存储支持的。在 Docker 中使用OverlayFS 解决这一问题。

posted @ 2020-09-21 18:37  rxg456  阅读(132)  评论(0)    收藏  举报