docker基础

1、概念

      容器是一种基础工具;从广泛定义来讲泛指任何可以用容纳其他工具的物品,可以部分或者完全封闭,被用于容纳、储存或运输物品;物体可以被放置在容器中,而容器则可以保护内容物。(轻量级/操作系统虚拟化方式,由Linux内核支持)

2、容器的定义以及技术栈的概念

      我们买回来一台计算机的主要目标,不是为了运行操作系统,而是为了运行某一特定的应用程序,比如:word(桌面交互的编辑工具)、httpd或者是mysql、redis这样的存储系统等。这个特定的进程建构在现在的操作系统之上,他通常应该是运行在操作系统的用户空间中,而后内核主要是底层硬件的虚拟接口。它可以把底层一组计算设备或者叫计算资源,给它做第一部分的抽象和分割,从而能够支持在用户空间同时运行多个进程。而我们反复强调用户空间,就是指进程运行时所处的一个位置,如果这个用户空间能够被分割出来,分别用于容纳运行1到多个特定的应用程序,从而能够实现能够给根其他用户空间中的应用程序分割开来(或者是隔离开来);那么这时每个独立的单独用于运行进程的用户空间就叫做容器,因为它容纳了并且隔离了其它的用户空间,使得进程在当前用户空间运行时与其它用户空间得进程彼此间互相干扰。所以这里体现了上述所说的容器的作用或者基本功用。

        就算我们使用KVM虚拟机,它所提供的无非就是在一个物理硬件上或者一组物理硬件上运行出多个虚拟机来,每一个虚拟机内部也可以运行多个进程,比如我们现在需要运行两个httpd进程,各自都还要监听在80端口上,而且彼此之间很有可能监听的是本机所有可用地址的80端口,很显然我们把它放在同一个物理机上是做不到的。所以在同一个物理机上,我们做了两个虚拟机,每一个虚拟机中运行一个httpd,这样就能达到目的。所以从本质上来讲,虚拟机也不过是提供进程的、隔离运行环境的而已。只不过这个“隔离提供环境”的代价有点大,因为我们不得不在底层加一个内核,但最终目的还是为了运行进程,还是为了隔离运行进程,所以后来linux内核就开始提供一种机制,让用户空间中必备其支撑运行的资源,在内核级给它们就隔离开来或者是在内核级就支持进行虚拟机制,使得我们在一个内核之上所支持的用户空间就不止一个,我们就可以完完全全在一组内核之上,多组织几个用户空间来,那么每一个用户空间就可以独立的运行自己的应用程序,就好像当前用户空间是唯一运行在当前内核上的用户空间一样,用户对此是无所感知的,这比起来主机级虚拟化,显然少了一层内核,因此也少了很多资源消耗,但这里有基本前提,就是linux内核必须(有6种名称空间机制)这就是支持所谓能够把用户空间给它分割开来的一个重要的底层技术。

        容器技术最早并不是出现在linux之上,在2000年前后freeBSD中上一个叫做JAIL的技术,所描述的就是我们刚才所提供的功能,从本质上来讲它更像是在linux当中的使用chroot机制,我们运行dns就是运行bind应用程序,可以以其中一种方式让它运行在某一个目录下,使得即便将来进程被人劫持了,那么所看到的也不是操作系统的真正根环境,而是切换以后的根环境,进程运行只需要给它提供必备的资源就行,一般来讲一个进程运行无非要用到所谓的程序文件、库文件、配置文件和它本身数据如果有变化所需要用到的一个简单的临时存储目录就行。所以为了运行bind就完全可以切根,把bind自身的应用程序和依赖的基本的最小的库文件合集,给它放在一个目录下,然后切换过去以后在这个目录下运行。就好像named这个守护进程运行时,就以这个目标目录为根,而不再是真正的根文件系统,这就是jail当初时的雏形。但是切入的自身最多只能实现叫文件系统的切换和切根,但事实上,我们操作系统真正运行起来以后,它是有两棵树来支撑:第一是静态的或者叫半静态的,放在磁盘之上后来被装入到内存中,称为文件系统树;除此之外,还有一个是进程树,所有的进程都是由init进程所生成的子进程,一切都归init统管,我们称为init。Init实验形式,不同级别的或者发行不同的主版本,以centos为例,都是不同的。继freeBSD之后,linux发现自己可能也需要用到类似的技术,所以2001年Linux至少在开源领域当中出现了一个新的产品叫VServer,它在实现逻辑上就是复刻了freeBSD jail的实现思想和逻辑并能得以在linux上运行。所以从这个角度来讲,linux container只不过是一组进程而已,这组进程在运行时从或者同当前系统上的其他进程完全的隔离开来,所以这就叫容器。对linux来讲或者是对计算机领域的容器来讲无非就是进程的或者程序的运行的隔离环境环境。只不过容器技术不是新生技术,在2001年就有了。

 

3、Linux   Namespaces概念(名称空间)

Namespace属于隔离技术的第一层,确保容器内的进程看不到也影响不到外部的进程。

        Linux 内核实现 namespace 的一个主要目的就是实现轻量级虚拟化(容器)服务。在同一个 namespace 下的进程可以感知彼此的变化,而对外界的进程一无所知。这样就可以让容器中的进程产生错觉,认为自己置身于一个独立的系统中,从而达到隔离的目的。也就是说 linux 内核提供的 namespace 技术为 docker 等容器技术的出现和发展提供了基础条件。

        所谓名称空间就是用来封装一个全局级别的资源,在一个抽象层上,从而使得我们可以把它进行切分,这种资源主要包括以下六类系统资源的隔离机制:

Namespaces(名称空间隔离类型)

作用

隔离内容

系统参数

内核版本

IPC

同一主机之上进程间通信的隔离的跨主机的通信

消息队列、共享内存和信号量

CLONE_NEWIPC

2.6.19

Network

网络隔离

网络设备、网络协议栈和端口

CLONE_NEWNET

2.6.29

Mount

磁盘挂载点和文件系统的隔离

挂载点(文件系统)

CLONE_NEWNS

2.4.19

PID

进程间隔离

进程编号

CLONE_NEWPID

2.6.24

User

用户隔离

用户和组

CLONE_NEWUSER

3.8

UTS

主机名隔离

主机名和域名

CLONE_NEWUTS

2.6.19

        我们可以从 docker 实现者的角度考虑该如何实现一个资源隔离的容器。比如是不是可以通过 chroot 命令切换根目录的挂载点,从而隔离文件系统。为了在分布式的环境下进行通信和定位,容器必须要有独立的 IP、端口和路由等,这就需要对网络进行隔离。同时容器还需要一个独立的主机名以便在网络中标识自己。接下来还需要进程间的通信、用户权限等的隔离。最后,运行在容器中的应用需要有进程号(PID),自然也需要与宿主机中的 PID 进行隔离。也就是说这六种隔离能力是实现一个容器的基础。

 

4、Ggroup

实现了对资源的配额和调度  防止资源全部跑到一个虚拟机中规定某个系统他能运行多少内存、cpu、磁盘空间等。

       比如在同一个内核上做了好几个容器,这些容器间的进程是隔离的,如果运行的容器3里面运行了挖矿的代码,它进而把底层硬件的所有算例全拿走了,剩下的容器能得到1%都不到,因此Ggroup就是来把底层主要的三个维度的计算资源:cpu、内存、IO(不需要考虑磁盘空间大小,那是磁盘配额的,对磁盘的使用一般是IO,比如:磁盘的交互能力每秒中只有100兆,它把这100兆都沾满了,那么其他进程将无法存储数据,网络IO也是一样的逻辑)划分成块之后有效的调派到对应的容器之上,比如我们有8核CPU,我们指定第一个容器只能使用两个,第二个容器两个,第三个容器两个,宿主机两个,这样就算容器里运行挖矿的代码,最多也只能耗尽这两个CPU核心的计算能力另外6个它就接触不到,那么这就是Cgroup的作用,因此我们可以把Cgroup可以理解成计算CPU、内存、IO配额的一种接口。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值