zoukankan      html  css  js  c++  java
  • Docker底层原理介绍

    1.docker介绍

    1.1什么是docker

    Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源。

    Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上。

    1.2docker能解决什么问题

    1.2.1高效有序利用资源

    • 机器资源有限;

    • 单台机器得部署多个应用;

    • 应用之间互相隔离;

    • 应用之间不能发生资源抢占,每个应用只能使用事先注册申请的资源。

    1.2.2一次编译,到处运行

    • 类似于java代码,应用及依赖的环境构建一次,可以到处运行。

    1.2.docker底层原理介绍

    1.2.1Linux的namespace和cgroup简单理解

    namespace:类似于JAVA的命名空间

    controll groups : controll (system resource) (for) (process)groups

    1.2.2Linux中的namespace

    在Linux系统中,可以同时存在多用户多进程,那么对他们的运行协调管理,通过进程调度和进度管理可以解决,但是,整体资源是有限的,怎么把有限的资源(进程号、网络资源等等)合理分配给各个用户所在的进程?

     
    image

    Linux Namespaces机制提供一种资源隔离方案。PID,IPC,Network等系统资源不再是全局性的,而是属于某个特定的Namespace。每个namespace下的资源对于其他namespace下的资源都是透明,不可见的。因此在操作系统层面上看,就会出现多个相同pid的进程。系统中可以同时存在两个进程号为0,1,2的进程,由于属于不同的namespace,所以它们之间并不冲突。而在用户层面上只能看到属于用户自己namespace下的资源,例如使用ps命令只能列出自己namespace下的进程。这样每个namespace看上去就像一个单独的Linux系统。

     
    image

    命名空间建立系统的不同视图, 对于每一个命名空间,从用户看起来,应该像一台单独的Linux计算机一样,有自己的init进程(PID为0),其他进程的PID依次递增,A和B空间都有PID为0的init进程,子容器的进程映射到父容器的进程上,父容器可以知道每一个子容器的运行状态,而子容器与子容器之间是隔离的。

    | Mount namespaces | Linux 2.4.19 | 文件系统挂接点 |

    将一个文件系统的顶层目录挂到另一个文件系统的子目录上,使它们成为一个整体,称为挂载。把该子目录称为挂载点。

    Mount namespace用来隔离文件系统的挂载点, 使得不同的mount namespace拥有自己独立的挂载点信息,不同的namespace之间不会相互影响,这对于构建用户或者容器自己的文件系统目录非常有用。

    |
    | UTS namespaces | Linux 2.6.19 | nodename 和 domainname |

    UTS,UNIX Time-sharing System namespace提供了主机名和域名的隔离。能够使得子进程有独立的主机名和域名(hostname),这一特性在Docker容器技术中被用到,使得docker容器在网络上被视作一个独立的节点,而不仅仅是宿主机上的一个进程。

    |
    | IPC namespaces | Linux 2.6.19 | 特定的进程间通信资源,包括System V IPC 和 POSIX message queues |

    IPC全称 Inter-Process Communication,是Unix/Linux下进程间通信的一种方式,IPC有共享内存、信号量、消息队列等方法。所以,为了隔离,我们也需要把IPC给隔离开来,这样,只有在同一个Namespace下的进程才能相互通信。如果你熟悉IPC的原理的话,你会知道,IPC需要有一个全局的ID,即然是全局的,那么就意味着我们的Namespace需要对这个ID隔离,不能让别的Namespace的进程看到。

    |
    | PID namespaces | Linux 2.6.24 | 进程 ID 数字空间 (process ID number space) |

    PID namespaces用来隔离进程的ID空间,使得不同pid namespace里的进程ID可以重复且相互之间不影响。

    PID namespace可以嵌套,也就是说有父子关系,在当前namespace里面创建的所有新的namespace都是当前namespace的子namespace。父namespace里面可以看到所有子孙后代namespace里的进程信息,而子namespace里看不到祖先或者兄弟namespace里的进程信息。

    |
    | Network namespaces | 始于Linux 2.6.24 完成于 Linux 2.6.29 | 网络相关的系统资源 | 每个容器用有其独立的网络设备,IP 地址,IP 路由表,/proc/net 目录,端口号等等。这也使得一个 host 上多个容器内的同一个应用都绑定到各自容器的 80 端口上。 |
    | User namespaces | 始于 Linux 2.6.23 完成于 Linux 3.8) | 用户和组 ID 空间 |

    User namespace用来隔离user权限相关的Linux资源,包括user IDs and group IDs。

    这是目前实现的namespace中最复杂的一个,因为user和权限息息相关,而权限又事关容器的安全,所以稍有不慎,就会出安全问题。

    在不同的user namespace中,同样一个用户的user ID 和group ID可以不一样,换句话说,一个用户可以在父user namespace中是普通用户,在子user namespace中是超级用户

    |

    1.2.3linux cgroup介绍

    (1)有了namespace为什么还要cgroup:

    Docker 容器使用 linux namespace 来隔离其运行环境,使得容器中的进程看起来就像一个独立环境中运行一样。但是,光有运行环境隔离还不够,因为这些进程还是可以不受限制地使用系统资源,比如网络、磁盘、CPU以及内存 等。关于其目的,一方面,是为了防止它占用了太多的资源而影响到其它进程;另一方面,在系统资源耗尽的时候,linux 内核会触发 OOM,这会让一些被杀掉的进程成了无辜的替死鬼。因此,为了让容器中的进程更加可控,Docker 使用 Linux cgroups 来限制容器中的进程允许使用的系统资源。

    (2)原理

    Linux Cgroup 可为系统中所运行任务(进程)的用户定义组群分配资源 — 比如 CPU 时间、系统内存、网络带宽或者这些资源的组合。可以监控管理员配置的 cgroup,拒绝 cgroup 访问某些资源,甚至在运行的系统中动态配置 cgroup。所以,可以将 controll groups 理解为 controller (system resource) (for) (process)groups,也就是是说它以一组进程为目标进行系统资源分配和控制。它主要提供了如下功能:

    • Resource limitation: 限制资源使用,比如内存使用上限以及文件系统的缓存限制。

    • Prioritization: 优先级控制,比如:CPU利用和磁盘IO吞吐。

    • Accounting: 一些审计或一些统计,主要目的是为了计费。

    • Controll: 挂起进程,恢复执行进程。

    使用 cgroup,系统管理员可更具体地控制对系统资源的分配、优先顺序、拒绝、管理和监控。可更好地根据任务和用户分配硬件资源,提高总体效率。

    在实践中,系统管理员一般会利用CGroup做下面这些事:

    • 隔离一个进程集合(比如:nginx的所有进程),并限制他们所消费的资源,比如绑定CPU的核。

    • 为这组进程分配其足够使用的内存

    • 为这组进程分配相应的网络带宽和磁盘存储限制

    • 限制访问某些设备(通过设置设备的白名单)

    1.3docker与虚拟机的区别

    1.3.1虚拟机结构介绍

     
    image
    • 基础设施(Infrastructure)。它可以是你的个人电脑,数据中心的服务器,或者是云主机。

    • 主操作系统(Host Operating System)。你的个人电脑之上,运行的可能是MacOS,Windows或者某个Linux发行版。

    • 虚拟机管理系统(Hypervisor)。利用Hypervisor,可以在主操作系统之上运行多个不同的从操作系统。类型1的Hypervisor有支持MacOS的HyperKit,支持Windows的Hyper-V以及支持Linux的KVM。类型2的Hypervisor有VirtualBox和VMWare。

    • 从操作系统(Guest Operating System)。假设你需要运行3个相互隔离的应用,则需要使用Hypervisor启动3个从操作系统,也就是3个虚拟机。这些虚拟机都非常大,也许有700MB,这就意味着它们将占用2.1GB的磁盘空间。更糟糕的是,它们还会消耗很多CPU和内存。

    • 各种依赖。每一个从操作系统都需要安装许多依赖。如果你的的应用需要连接PostgreSQL的话,则需要安装libpq-dev;如果你使用Ruby的话,应该需要安装gems;如果使用其他编程语言,比如Python或者Node.js,都会需要安装对应的依赖库。

    • 应用。安装依赖之后,就可以在各个从操作系统分别运行应用了,这样各个应用就是相互隔离的。

    1.3.2docker结构介绍

     
    image
    • 基础设施(Infrastructure)。

    • 主操作系统(Host Operating System)。所有主流的Linux发行版都可以运行Docker。对于MacOS和Windows,也有一些办法”运行”Docker。

    • Docker守护进程(Docker Daemon)。Docker守护进程取代了Hypervisor,它是运行在操作系统之上的后台进程,负责管理Docker容器。

    • 各种依赖。对于Docker,应用的所有依赖都打包在Docker镜像中,Docker容器是基于Docker镜像创建的。

    • 应用。应用的源代码与它的依赖都打包在Docker镜像中,不同的应用需要不同的Docker镜像。不同的应用运行在不同的Docker容器中,它们是相互隔离的。

    Docker守护进程可以直接与主操作系统进行通信,为各个Docker容器分配资源;它还可以将容器与主操作系统隔离,并将各个容器互相隔离。虚拟机启动需要数分钟,而Docker容器可以在数毫秒内启动。由于没有臃肿的从操作系统,Docker可以节省大量的磁盘空间以及其他系统资源;虚拟机更擅长于资源的完全隔离。



    作者:编码前线
    链接:https://www.jianshu.com/p/e1f7b8d5184c
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 相关阅读:
    快速掌握MIPI开发攻略,对接百度人工智能计算卡EdgeBoard
    百度大脑UNIT3.0解读之对话式文档问答——上传文档获取对话能力
    果蔬识别轻松帮你区分车厘子与大樱桃
    远场语音识别套件评测
    智能家居手势识别,只需百度AI即可搞定
    python callable函数(43)
    python range函数(42)
    python len函数(41)
    python filter函数(40)
    python 进程Process模块(40)
  • 原文地址:https://www.cnblogs.com/wangju/p/11809569.html
Copyright © 2011-2022 走看看