Docker 入门(2)技术实现和核心组成

1. Docker 的技术实现

Docker 的实现,主要归结于三大技术:

  • 命名空间 ( Namespaces )
  • 控制组 ( Control Groups )
  • 联合文件系统 ( Union File System )

image.png

1.1 Namespace

命名空间可以有效地帮助Docker分离进程树、网络接口、挂载点以及进程间通信等资源。Linux 的命名空间机制提供了以下七种不同的命名空间,包括 CLONE_NEWCGROUP、CLONE_NEWIPC、CLONE_NEWNET、CLONE_NEWNS、CLONE_NEWPID、CLONE_NEWUSER 和 CLONE_NEWUTS,通过这七个选项我们能在创建新的进程时设置新进程应该在哪些资源上与宿主机器进行隔离。

命名空间是 Linux 核心在 2.4 版本后逐渐引入的一项用于运行隔离的模块。以进程为例,通过 PID Namespace,我们可以造就一个独立的进程运行空间,在其中进程的编号又会从 1 开始。在这个空间中运行的进程,完全感知不到外界系统中的其他进程或是其他进程命名空间中运行的进程。

image.png
当前机器上有很多的进程正在执行,在上述进程中有两个非常特殊,一个是 pid 为 1 的 /sbin/init 进程,另一个是 pid 为 2 的 kthreadd 进程,这两个进程都是被 Linux 中的上帝进程 idle 创建出来的,其中前者负责执行内核的一部分初始化工作和系统配置,也会创建一些类似 getty 的注册进程,而后者负责管理和调度其他的内核进程。

如果我们在当前的 Linux 操作系统下运行一个新的 Docker 容器,并通过 exec 进入其内部的 bash 并打印其中的全部进程,我们会得到以下的结果:

root@iZ255w13cy6Z:~# docker run -it -d ubuntu
b809a2eb3630e64c581561b08ac46154878ff1c61c6519848b4a29d412215e79
root@iZ255w13cy6Z:~# docker exec -it b809a2eb3630 /bin/bash
root@b809a2eb3630:/# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 15:42 pts/0    00:00:00 /bin/bash
root         9     0  0 15:42 pts/1    00:00:00 /bin/bash
root        17     9  0 15:43 pts/1    00:00:00 ps -ef

也出现了pid为1的进程,证明当前的 Docker 容器成功将容器内的进程与宿主机器中的进程隔离。这就是在使用 clone(2) 创建新进程时传入 CLONE_NEWPID 实现的,也就是使用 Linux 的命名空间实现进程的隔离,Docker 容器内部的任意进程都对宿主机器的进程一无所知。

image.png

1.2 Control Groups

资源控制组 ( 常缩写为 CGroups ) 是 Linux 内核在 2.6 版本后逐渐引入的一项对计算机资源控制的模块。

顾名思义,资源控制组的作用就是控制计算机资源的与以隔离进程、网络、文件系统等虚拟资源为目的 Namespace 不同,CGroups 主要做的是硬件资源的隔离

虚拟化除了制造出虚拟的环境隔离同一物理平台运行的不同程序之外,另一大作用就是控制硬件资源的分配,CGroups 的使用正是为了这样的目的。CGroups 除了资源的隔离,还有资源分配这个关键性的作用。通过 CGroups,我们可以指定任意一个隔离环境对任意资源的占用值或占用率

我们通过 Linux 的命名空间为新创建的进程隔离了文件系统、网络并与宿主机器之间的进程相互隔离,但是命名空间并不能够为我们提供物理资源上的隔离,比如 CPU 或者内存,如果在同一台机器上运行了多个对彼此以及宿主机器一无所知的『容器』,这些容器却共同占用了宿主机器的物理资源。

如果其中的某一个容器正在执行 CPU 密集型的任务,那么就会影响其他容器中任务的性能与执行效率,导致多个容器相互影响并且抢占资源。如何对多个容器的资源使用进行限制就成了解决进程虚拟资源隔离之后的主要问题,而 Control Groups(简称 CGroups)就是能够隔离宿主机器上的物理资源,例如 CPU、内存、磁盘 I/O 和网络带宽。

每一个 CGroup 都是一组被相同的标准和参数限制的进程,不同的 CGroup 之间是有层级关系的,也就是说它们之间可以从父类继承一些用于限制资源使用的标准和参数

image.png
在 CGroup 中,所有的任务就是一个系统的一个进程,而 CGroup 就是一组按照某种标准划分的进程,在 CGroup 这种机制中,所有的资源控制都是以 CGroup 作为单位实现的,每一个进程都可以随时加入一个 CGroup 也可以随时退出一个 CGroup。

Linux 使用文件系统来实现 CGroup,我们可以直接使用下面的命令查看当前的 CGroup 中有哪些子系统:

image.png
大多数 Linux 的发行版都有着非常相似的子系统,而之所以将上面的 cpuset、cpu 等东西称作子系统,是因为它们能够为对应的控制组分配资源并限制资源的使用。

如果我们想要创建一个新的 cgroup 只需要在想要分配或者限制资源的子系统下面创建一个新的文件夹,然后这个文件夹下就会自动出现很多的内容,如果你在 Linux 上安装了 Docker,你就会发现所有子系统的目录下都有一个名为 docker 的文件夹:

$ ls cpu
cgroup.clone_children  
...
cpu.stat  
docker  
notify_on_release 
release_agent 
tasks$ ls cpu/docker/
9c3057f1291b53fd54a3d12023d2644efe6a7db6ddf330436ae73ac92d401cf1 
cgroup.clone_children  
...
cpu.stat  
notify_on_release 
release_agent 
tasks

每一个 CGroup 下面都有一个 tasks 文件,其中存储着属于当前控制组的所有进程的 pid,作为负责 cpu 的子系统,cpu.cfs_quota_us 文件中的内容能够对 CPU 的使用作出限制,如果当前文件的内容为 50000,那么当前控制组中的全部进程的 CPU 占用率不能超过 50%。

image.png

1.3 Union File System

Linux 的命名空间和控制组分别解决了不同资源隔离的问题,前者解决了进程、网络以及文件系统的隔离,后者实现了 CPU、内存等资源的隔离,但是在 Docker 中还有另一个非常重要的问题需要解决 - 也就是镜像。

Docker 镜像其实本质就是一个压缩包,我们可以使用下面的命令将一个 Docker 镜像中的文件导出:

$ docker export $(docker create busybox) | tar -C rootfs -xvf -
$ ls
bin  dev  etc  home proc root sys  tmp  usr  var

你可以看到这个 busybox 镜像中的目录结构与 Linux 操作系统的根目录中的内容并没有太多的区别,可以说 Docker 镜像就是一个文件

联合文件系统 ( Union File System ) 是一种能够同时挂载不同实际文件或文件夹到同一目录,形成一种联合文件结构的文件系统。联合文件系统本身与虚拟化并无太大的关系,但 Docker 却创新的将其引入到容器实现中,用它解决虚拟环境对文件系统占用过量,实现虚拟环境快速启停等问题。

在 Docker 中,提供了一种对 UnionFS 的改进实现,也就是 AUFS ( Advanced Union File System )。

AUFS 将文件的更新挂载到老的文件之上,而不去修改那些不更新的内容,这就意味着即使虚拟的文件系统被反复修改,也能保证对真实文件系统的空间占用保持一个较低水平

AUFS 作为联合文件系统,它能够将不同文件夹中的层联合(Union)到了同一个文件夹中,这些文件夹在 AUFS 中称作分支,整个『联合』的过程被称为联合挂载(Union Mount):

image.png

每一个镜像层都是建立在另一个镜像层之上的,同时所有的镜像层都是只读的,只有每个容器最顶层的容器层才可以被用户直接读写,所有的容器都建立在一些底层服务(Kernel)上,包括命名空间、控制组、rootfs 等等,这种容器的组装方式提供了非常大的灵活性,只读的镜像层通过共享也能够减少磁盘的占用。

AUFS 只是 Docker 使用的存储驱动的一种,除了 AUFS 之外,Docker 还支持了不同的存储驱动,包括 aufs、devicemapper、overlay2、zfs 和 vfs 等等,在最新的 Docker 中,overlay2 取代了 aufs 成为了推荐的存储驱动,但是在没有 overlay2 驱动的机器上仍然会使用 aufs 作为 Docker 的默认驱动。

image.png

2. Docker 的核心组成

2.1 镜像

所谓镜像,可以理解为一个只读的文件包,其中包含了虚拟环境运行最原始文件系统的内容。

image.png
每次对镜像内容的修改,Docker 都会将这些修改铸造成一个镜像层,而一个镜像其实就是由其下层所有的镜像层所组成的。当然,每一个镜像层单独拿出来,与它之下的镜像层都可以组成一个镜像。

另外,由于这种结构,Docker 的镜像实质上是无法被修改的,因为所有对镜像的修改只会产生新的镜像,而不是更新原有的镜像。

2.2 容器

容器 ( Container ) 就更好理解了,在容器技术中,容器就是用来隔离虚拟环境的基础设施,而在 Docker 里,它也被引申为隔离出来的虚拟环境

如果把镜像理解为编程中的类,那么容器就可以理解为类的实例。镜像内存放的是不可变化的东西,当以它们为基础的容器启动后,容器内也就成为了一个“活”的空间。

容器的组成

  • 一个 Docker 镜像
  • 一个程序运行环境
  • 一个指令集合

2.3 网络

网络是进程间通信方式的一种,网络通讯是目前最常用的一种程序间的数据交换方式了。

在 Docker 中,实现了强大的网络功能,我们不但能够十分轻松的对每个容器的网络进行配置,还能在容器间建立虚拟网络,将数个容器包裹其中,同时与其他网络环境隔离

另外,利用一些技术,Docker 能够在容器中营造独立的域名解析环境,这使得我们可以在不修改代码和配置的前提下直接迁移容器,Docker 会为我们完成新环境的网络适配。

Docker 虽然可以通过命名空间创建一个隔离的网络环境,但是 Docker 中的服务仍然需要与外界相连才能发挥作用。

每一个使用 docker run 启动的容器其实都具有单独的网络命名空间,Docker 为我们提供了四种不同的网络模式,Host、Container、None 和 Bridge 模式。

2.4 Docker Engine

虽然我们说 Docker Engine 是一款软件,但实实在在去深究的话,它其实算是由多个独立软件所组成的软件包。在这些程序中,最核心的就是 docker daemondocker CLI 这俩了。

所有我们通常认为的 Docker 所能提供的容器管理、应用编排、镜像分发等功能,都集中在了 docker daemon 中,而我们之前所提到的镜像模块、容器模块、数据卷模块和网络模块也都实现在其中。在操作系统里,docker daemon 通常以服务的形式运行以便静默的提供这些功能,所以我们也通常称之为 Docker 服务。

在 docker daemon 管理容器等相关资源的同时,它也向外暴露了一套 RESTful API,我们能够通过这套接口对 docker daemon 进行操作。如果我们在控制台中编写一个 HTTP 请求以借助 docker daemon 提供的 RESTful API 来操控它,那显然是个费脑、费手又费时间的活儿。所以在 Docker Engine 里还直接附带了 docker CLI 这个控制台程序。

参考资料

《开发者必备的 Docker 实践指南》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/391298.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

marlin 三角洲_带火花的三角洲湖:什么和为什么?

marlin 三角洲Let me start by introducing two problems that I have dealt time and again with my experience with Apache Spark:首先,我介绍一下我在Apache Spark上的经历反复解决的两个问题: Data “overwrite” on the same path causing data l…

eda分析_EDA理论指南

eda分析Most data analysis problems start with understanding the data. It is the most crucial and complicated step. This step also affects the further decisions that we make in a predictive modeling problem, one of which is what algorithm we are going to ch…

基于ssm框架和freemarker的商品销售系统

项目说明 1、项目文件结构 2、项目主要接口及其实现 (1)Index: 首页页面:展示商品功能,可登录或查看商品详细信息 (2)登录:/ApiLogin 3、dao层 数据持久化层,把商品和用户…

简·雅各布斯指数第二部分:测试

In Part I, I took you through the data gathering and compilation required to rank Census tracts by the four features identified by Jane Jacobs as the foundation of a great neighborhood:在第一部分中 ,我带您完成了根据简雅各布斯(Jacobs Jacobs)所确定…

Docker 入门(3)Docke的安装和基本配置

1. Docker Linux下的安装 1.1 Docker Engine 的版本 社区版 ( CE, Community Edition ) 社区版 ( Docker Engine CE ) 主要提供了 Docker 中的容器管理等基础功能,主要针对开发者和小型团队进行开发和试验企业版 ( EE, Enterprise Edition ) 企业版 ( Docker Engi…

python:单元测试框架pytest的一个简单例子

之前一般做自动化测试用的是unitest框架,发现pytest同样不错,写一个例子感受一下 test_sample.py import cx_Oracle import config from send_message import send_message from insert_cainiao_oracle import insert_cainiao_oracledef test_cainiao_mo…

抑郁症损伤神经细胞吗_使用神经网络探索COVID-19与抑郁症之间的联系

抑郁症损伤神经细胞吗The drastic changes in our lifestyles coupled with restrictions, quarantines, and social distancing measures introduced to combat the corona virus outbreak have lead to an alarming rise in mental health issues all over the world. Social…

Docker 入门(4)镜像与容器

1. 镜像与容器 1.1 镜像 Docker镜像类似于未运行的exe应用程序,或者停止运行的VM。当使用docker run命令基于镜像启动容器时,容器应用便能为外部提供服务。 镜像实际上就是这个用来为容器进程提供隔离后执行环境的文件系统。我们也称之为根文件系统&a…

python:pytest中的setup和teardown

原文:https://www.cnblogs.com/peiminer/p/9376352.html  之前我写的unittest的setup和teardown,还有setupClass和teardownClass(需要配合classmethod装饰器一起使用),接下来就介绍pytest的类似于这类的固件。 &#…

如何开始使用任何类型的数据? - 第1部分

从数据开始 (START WITH DATA) My data science journey began with a student job in the Advanced Analytics department of one of the biggest automotive manufacturers in Germany. I was nave and still doing my masters.我的数据科学之旅从在德国最大的汽车制造商之一…

iHealth基于Docker的DevOps CI/CD实践

本文由1月31日晚iHealth运维技术负责人郭拓在Rancher官方技术交流群内所做分享的内容整理而成,分享了iHealth从最初的服务器端直接部署,到现在实现全自动CI/CD的实践经验。作者简介郭拓,北京爱和健康科技有限公司(iHealth)。负责公…

机器学习图像源代码_使用带有代码的机器学习进行快速房地产图像分类

机器学习图像源代码RoomNet is a very lightweight (700 KB) and fast Convolutional Neural Net to classify pictures of different rooms of a house/apartment with 88.9 % validation accuracy over 1839 images. I have written this in python and TensorFlow.RoomNet是…

leetcode 938. 二叉搜索树的范围和

给定二叉搜索树的根结点 root,返回值位于范围 [low, high] 之间的所有结点的值的和。 示例 1: 输入:root [10,5,15,3,7,null,18], low 7, high 15 输出:32 示例 2: 输入:root [10,5,15,3,7,13,18,1,nul…

COVID-19和世界幸福报告数据告诉我们什么?

For many people, the idea of ​​staying home actually sounded good at first. This process was really efficient for Netflix and Amazon. But then sad truths awaited us. What was boring was the number of dead and intubated patients one after the other. We al…

iOS 开发一定要尝试的 Texture(ASDK)

原文链接 - iOS 开发一定要尝试的 Texture(ASDK)(排版正常, 包含视频) 前言 本篇所涉及的性能问题我都将根据滑动的流畅性来评判, 包括掉帧情况和一些实际体验 ASDK 已经改名为 Texture, 我习惯称作 ASDK 编译环境: MacOS 10.13.3, Xcode 9.2 参与测试机型: iPhone 6 10.3.3, i…

lisp语言是最好的语言_Lisp可能不是数据科学的最佳语言,但是我们仍然可以从中学到什么呢?...

lisp语言是最好的语言This article is in response to Emmet Boudreau’s article ‘Should We be Using Lisp for Data-Science’.本文是对 Emmet Boudreau的文章“我们应该将Lisp用于数据科学”的 回应 。 Below, unless otherwise stated, lisp refers to Common Lisp; in …

static、volatile、synchronize

原子性(排他性):不论是多核还是单核,具有原子性的量,同一时刻只能有一个线程来对它进行操作!可见性:多个线程对同一份数据操作,thread1改变了某个变量的值,要保证thread2…

1.10-linux三剑客之sed命令详解及用法

内容:1.sed命令介绍2.语法格式,常用功能查询 增加 替换 批量修改文件名第1章 sed是什么字符流编辑器 Stream Editor第2章 sed功能与版本处理出文本文件,日志,配置文件等增加,删除,修改,查询sed --versionsed -i 修改文件内容第3章 语法格式3.1 语法格式sed [选项] [sed指令…

python pca主成分_超越“经典” PCA:功能主成分分析(FPCA)应用于使用Python的时间序列...

python pca主成分FPCA is traditionally implemented with R but the “FDASRSF” package from J. Derek Tucker will achieve similar (and even greater) results in Python.FPCA传统上是使用R实现的,但是J. Derek Tucker的“ FDASRSF ”软件包将在Python中获得相…

初探Golang(2)-常量和命名规范

1 命名规范 1.1 Go是一门区分大小写的语言。 命名规则涉及变量、常量、全局函数、结构、接口、方法等的命名。 Go语言从语法层面进行了以下限定:任何需要对外暴露的名字必须以大写字母开头,不需要对外暴露的则应该以小写字母开头。 当命名&#xff08…