Docker所运用到Linux底层技术


1. Storage Driver


 1.1 AUFS for ubuntu which has no overlay2

 1.2 overlayfs

 overlay: image分层比较多,促使inode非常大

各个镜像层中,每下一层中的文件以硬链接的方式出现在它的上一层中,以此类推,最终挂载overlayfs的lower dir为最上层镜像层目录imager layer N。与此同时,容器的writable dir作为upper dir,挂载成为容器的rootfs,由于是采用硬链接来串联每个镜像层,导致每个硬链接下目录文件会产生额外的inode,可能导致inode值超过设置。

Overlayfs2 采用多lower层的支持, 解决了inode过多的问题

overlay2: always recommend if driver is in kernel


Overlay2的挂载方式比Overlay的要简单许多,它基于内核overlayfs的Multiple lower layers特性实现,不在需要硬链接,直接将镜像层的各个目录设置为overlayfs的各个lower layer即可(Overlayfs最多支持500层lower dir),对比Overlay Driver将减少inode的使用

1.3 Devicemapper good for RHEL without overlay2 driver


loopback-lvm: bad performance but zero config

direct-lvm: production

1.4 btrfs if host filesystem is btrfs

1.5 vfs for testing purpose, performance is poor


2. 容器启动过程


2.1 image解压,形成一个联合FS, 挂载到指定容器目录 /var/lib/docker/devicemapper/mnt/<container_id>

2.2 docker通过内核申请mnt pid utc network等namespace

2.3 容器namespace是继承父进程的文件系统的,于是给容器目录 挂载特殊目录以及文件例如proc /etc/hosts /etc/hostnames

2.4 容器namespace里面挂载-v所指定的volune到容器目录

2.5 在容器namespace中挂载的任何操作,不影响容器外挂载点。 但是容器仍然与父进程共享非以上挂载点的文件系统

2.6 通过chroot指定容器目录为根目录,隔离容器与外界的FS

2.7 容器naspeace下, 配置网路信息

2.8 容器执行指定命令

3. Network


3.1 none

该模式关闭了容器的网络功能,在以下两种情况下是有用的:容器并不需要网络

3.2 host

与宿主机在同一个网络中,但没有独立IP地址。这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。

3.3 container

这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。

3.4 bridge

容器使用独立network Namespace,并连接到docker0虚拟网卡(默认模式)。通过docker0网桥以及Iptables nat表配置与宿主机通信;bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上。

bridge使用于单个docker host的容器互联, 不适用于多个docker hosts上的container互联,请用overlay

3.5 overlay


The overlay network driver creates a distributed network among multiple Docker daemon hosts. This network sits on top of (overlays) the host-specific networks, allowing containers connected to it to communicate securely when encryption is enabled. Docker transparently handles routing of each packet to and from the correct Docker daemon host and the correct destination container.

需要backend store应用来提供服务发现和DNS解析功能 例如etcd

如果docker host 创建或加入swarm, 则不需要第三方backend,swarm实现其功能

创建一个overlay type的网络(bridge),默认不提供gateway容器连接到docker-gwbridge上,用于访问overlay以外的网络。

连接到overlay网络的容器,会有2块网络,一个连接到overlay的网络, 另外一个连接到docker-gwbridge的bridge上。

连在docker-gwbridge上的容器是不同通过bridge访问的,default的setting是icc=false

overlay 网络内的路由走overlay那块网卡

访问overlay以外的网络,走gwbridge的网关,这个网关可以通过host上的ip命令查看。

3.6 macvlan


当容器需要直连入物理网络时,可以使用Macvlan。Macvlan本身不创建网络,接下来就是在这张物理网卡上创建虚拟网卡,并为虚拟网卡指定MAC地址,实现一卡多用,在物理网络看来,每张虚拟网卡都是一个单独的接口。如果各个macvlan需要存在三层路由,用IPVlan代替MACVlan

从长远来看bridge网络与overlay网络是更好的选择,原因就是虚拟网络应该与物理网络隔离而不是共享。

3.6.1 bridge 模式

Macvlan网络流量直接使用宿主机物理网卡。容器使用docker主机物理网络。网段,掩码,网关都是用所指定网口的物理网络

3.6.2  802.1q trunk bridge模式

Macvlan网络流量使用Docker动态创建的802.1q子接口,对于路由与过虑,这种模式能够提供更细粒度的控制。指定网口虚拟出子网口去对应相应的物理vlan

4. Linux Namespace

Docker利用Linux Namespace内核技术实现容器的资源隔离。

宿主机有的资源容器进程都可以享有,但彼此之间是隔离的,同样,不同容器进程之间使用资源也是隔离的,这样,彼此之间进行相同的操作,都不会互相干扰,安全性得到保障

为了在分布式的环境下进行通信和定位,容器必须要有独立的 IP、端口和路由等,这就需要对网络进行隔离。同时容器还需要一个独立的主机名以便在网络中标识自己。接下来还需要进程间的通信、用户权限等的隔离。最后,运行在容器中的应用需要有进程号(PID),自然也需要与宿主机中的 PID 进行隔离。也就是说这六种隔离能力是实现一个容器的基础

4.1 uts

隔离hostname和域名, 为每个container有不同的hostname, 相互不影响。在网络上就可以被视为一个独立的节点,在容器中对 hostname 的命名不会对宿主机造成任何影响

4.2 mount

mount namespace 可以实现不同mount 命名空间的进程看到的文件系统层次不一样。也就是说,不同的容器,以及容器与主机之间,可以出现不同目录结构;

mount()和umount()系统调用的影响不再是全局的而只影响其调用进程指向的名称空间。所以容器A里面mount了xxx到目录yyy,容器B也看不见,当然主机的yyy 目录也不会指向xxx

4.3 network

在逻辑上是网络堆栈的一个副本,它有自己的路由、防火墙规则和网络设备network namespace 可以创建相互独立的网络栈,从而实现网络的隔离.

4.4 PID

PID namespace完成的是进程号的隔离一个进程进入新创建的PID namespace,这个进程的进程号变为1。

在Linux里面1号进程非常特殊,init进程的PID是1,容器化后,应该每个容器都有一个1以及由1衍生的子进程和子进程的子进程,1号进程用于管理器子进程的监控‘回收等特性

4.5 IPC

隔离IPC, 每个container 有自己的IPC资源。例如共享内存 信号量,共享队列。IPC相关知识 可以google

4.6 user

同样一个用户的 user ID 和 group ID 在不同的 user namespace 中可以不一样。一个用户可以在一个 user namespace 中是普通用户,但在另一个 user namespace 中是超级用户。

User namespace 可以嵌套(目前内核控制最多32层),除了系统默认的 user namespace 外,所有的 user namespace 都有一个父 user namespace,每个 user namespace 都可以有零到多个子 user namespace

5. Linux cgroups


Linux 系统中,一切皆文件。Linux 将 cgroups 实现成了文件系统,方便用户使用。mount -t cgroup, 用户可以通过读写文件的方式对cgroup进行配置。

cgroup被内核load起来后, 会在/sys/fs/cgroup下建立一些默认的hierarchy(root group), 例如cpu, memory,cpu下有cpu相关的subsystem, memory下有memory相关的subsystem。

docker会在每个root hierarchy为docker建立一个cgroup,每个容器会在docker的cgroup下载建立子cgroup。

子层次继承父层次的属性。

资源限制:cgroups 可以对任务使用的资源总额进行限制,如设定应用运行时使用内存的上限,一旦超过这个配额就发出 OOM(Out of Memory)提示。

优先级分配:通过分配的 CPU 时间片数量和磁盘 IO 带宽大小,实际上就相当于控制了任务运行的优先级。

资源统计:cgroups 可以统计系统的资源使用,如 CPU 使用时长、内存用量等,这个功能非常适用于计费。

任务控制:cgroups 可以对任务执行挂起、恢复等操作。

https://www.infoq.cn/article/docker-kernel-knowledge-cgroups-resource-isolation/

https://www.cnblogs.com/sammyliu/p/5886833.html

6.1 Task

任务就是系统的一个进程。一个任务可以是多个 cgroup 的成员,但是这些 cgroup 必须在不同的层级

6.2 cgroup

控制族群就是一组按照某种标准划分的进程。Cgroups 中的资源控制都是以控制族群为单位实现。一个进程可以加入到某个控制族群,也从一个进程组迁移到另一个控制族群。一个进程组的进程可以使用 cgroups 以控制族群为单位分配的资源,同时受到 cgroups 以控制族群为单位设定的限制

系统中的进程(任务)创建子进程(任务)时,该子任务自动成为其父进程所在 cgroup 的成员。然后可根据需要将该子任务移动到不同的 cgroup 中,但开始时它总是继承其父任务的 cgroup。

docker 会为docker 在每个hierarchy下创建一个docker的cgroup, 每个container会在docker的cgroup下创建自己的cgroup。

6.3 Hierarchy

控制族群可以组织成 hierarchical 的形式,既一颗控制族群树。控制族群树上的子节点控制族群是父节点控制族群的孩子,继承父控制族群的特定的属性

cgroup的内核会默认创建多个hierarchy(root cgroup),每个hierarchy会加入相关的subsystem, 加入的subsystem种类决定了这个hierarchy下的cgroup所拥有的subsystem。用户可以在某个hierarchy下创建新的cgroup,cgroup里面会自动继承hierarchy的subsystem。

hierarchy是个抽象的概念,没有实际的文件目录和它对应。他决定这个root cgroup下控制能力(subsystem)

一个hierarchy可以附加多个subsystem

6.4 subsystem

一个子系统就是一个资源控制器,比如 cpu 子系统就是控制 cpu 时间分配的一个控制器。子系统必须附加(attach)到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的所有控制族群都受到这个子系统的控制。一个subsystem最多只能附加到一个hierarchy(root hierarchy)

  Block IO

  CPU

  Memory

  Device

  网络流量限制

net_cls 和 tc 一起使用可用于限制进程发出的网络包所使用的网络带宽。当使用 cgroups network controll net_cls 后,指定进程发出的所有网络包都会被加一个 tag,然后就可以使用其他工具比如 iptables 或者 traffic controller(TC)来根据网络包上的 tag 进行流量控制

Docker没有直接的命令去设置网络流量,可以根据上述方法自己开发

7. Linux chroot

容器启动时,通过 chroot 命令切换根目录的挂载点,从而隔离文件系统。

docker 启动一个container,images extract出来的联合文件系统,为作为容器的根目录的挂载点。这样不同的imgae的创建的容器,根目录层次结构/context理论上是不同的,即使相同image创建的容器,有着相同的根目录层次结构,但由于extract出来到不同路径,container的根目录不会相互影响,也不会和host的文件系统产生冲突,起到隔离的效果。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343