容器时一种基础工具;泛指任何可以用于容纳其他物品的工具,可以部分或完全封闭,被用于容纳、存储、运输物品;物体可以被放置在容器中,而容器则可以保护内容物
关键词
docker说明
docker时LXC的增强版,docker本身不是容器,而是容器的易用工具/前端工具,容器是linux内核的一种技术,而docker仅是把这种技术进行简化、普及、与使用
为每一个封闭的实例,提供的是一个从底层硬件开始一直到高层的基础环境。也就意味着说我们每一个对应的虚拟机实例就拥有自己可视的,而且是隔离于其它实例的基础硬件,包括CPU,内存等等,所以它在硬件完成资源划分以后,提供给了我们每一个实例一个基础环境,使得我们每一个实例都得安装操作系统,从而就拥有自己的内核空间和用户空间,所以这么一来,做为当前实例的使用者,就得安装操作系统,提供环境,安装程序并提供配置文件,最终才可用服务。
主机级虚拟化,由于做了两级内核,虚拟机自己有一级,hypervisor会有性能损耗,但是隔离性是非常好的。但过于重量级。
Hypervisor说明
Hypervisor,又称虚拟机监视器(英语:virtual machine monitor,缩写为 VMM),是用来建立与执行虚拟机器的软件、固件或硬件。
被Hypervisor用来执行一个或多个虚拟机器的电脑称为主体机器(host machine),这些虚拟机器则称为客体机器(guest machine)。hypervisor提供虚拟的作业平台来执行客体操作系统(guest operating systems),负责管理其他客体操作系统的执行阶段;这些客体操作系统,共同分享虚拟化后的硬件资源。
如果现在我打算在一台完全隔离的环境中,尽量不影响其他应用的情况下,安装一个tomcat。如果目前提供的是一个虚拟机,那么我们除了要安装好操作系统之外,还要安装tomcat等服务,会非常麻烦,整个环境也很重(实际上我也只是仅需要一个tomcat服务而已)。因为我们额外的步骤会非常多,所以这种虚拟化方式过于重量级,尤其是在某些轻量级的需求面前它就显得欲发重量。所以这种情况下就出现了容器技术
**用户空间(namespace)**仅仅运行用户进程而已,就不需要再主机级虚拟化技术上实现,它自己管理自己的内核,把虚拟出来的内核给剥离掉。给用户一个chroot环境,在这个虚根下,能够隔离和其它用户相关的用户环境。
在内核中的一个逻辑级别能够设置成隔离开来的区域,彼此之间互相不干扰,不影响的话,那么我们就可以做出来仅在用户空间,就能实现隔离的组件来。那这个在用户空间就能实现隔离的组件就称之为容器。每个空间就称为一个容器,因为每一个空间都容纳了一堆的进程和用户账号文件等等。
将内核分为多个空间,然后每个空间提供一个完整意义上的程序运行环境,容纳了文件,系统和进程以及彼此间交互的一些组件。我们把这些技术称之为容器
linux系统从版本2.4.19开始陆续引入了namespace的概念。当一个程序运行于主机之中时,其基本要求有:系统跟文件目录、运行pid进程号、主机名、网卡、ipc通信、程序运行用户这六大类。
linux将以上六类进行了内核级别的虚拟化,这六大类统称为namespace
namespace名称空间 | 被隔离的全局系统资源 | 在容器环境下的隔离效果 | 完成的内核版本 |
---|---|---|---|
UTS | 主机名和域名 | 每个容器能看到自己的hostname | 2.6.19 |
IPC | 信号量、消息队列和共享内存(进程间通信) | 同一个IPC namespace的进程之间能互相通讯 | 2.6.19 |
PID | 进程编号 | 每个PID namespace中的进程可以有其独立的PID,每个容器可以有其PID为1的root进程 | 2.6.24 |
Network | 网络设备、网络栈、端口等(网络相关的系统资源) | 每个容器拥有其独立的网络设备,IP地址,IP路由表,/proc/net目录,端口号 | 2.6.29 |
Mount | 挂载点(文件系统) | 每个容器能看到不同的文件系统层次结构 | 2.4.19 |
User | 用户和用户组空间 | 每个container可以有不同的user和group id | 3.8 |
注意:
因为centos6的内核为2.6,所以user name不支持,所以centos6天然不太支持容器,虽然可以通过升级内核来进行支持,不过建议直接使用centos7以上的系统
chroot,即 change root directory (更改 root 目录)。在 linux 系统中,系统默认的目录结构都是以 /
,即是以根 (root) 开始的。而在使用 chroot 之后,系统的目录结构将以指定的位置作为 /
位置。
在经过 chroot 之后,系统读取到的目录和文件将不在是旧系统根下的而是新根下(即被指定的新的位置)的目录结构和文件
内核级必须实现可以限制每一个用户空间中进行所有可用的资源的总量,防止出现类似OOM等资源使用问题
可以在整体空间上做比例分配(比如1:2:1),也可以在单个空间中做具体的限制(比如该用户空间最高可用2G内存),此处引入````cgroups```概念
cgroups:Linux control groups
,linux为运行的任务分配cpu、ram等,当namespace为容器进行隔离之后,还需要对每个容器进行资源的使用进行控制,不能让其抢占其它容器的资源。
cgroups主要对一下内容进行资源控制:
AUFS,Union File System,联合文件系统,主要功能是将位于不同物理位置的目录合并成同一个目录,有点类似于hadoop中hdfs的分布式存储
linux系统启动,至少需要两种文件系统,一种是bootfs
,一种是rootfs
同一个内核版本的所有linux系统的bootfs是相同的,rootfs不同
在docker images中,其采用的是分层技术,基础镜像中的rootfs会一直保存只读模式,docker利用union mount(联合挂载)来在这个rootfs上增加更多的只读文件系统,最后他们看起来就像一个文件系统即容器的rootfs
在docker的分层镜像中,除了支持aufs之外,还支持devicemapper,因为在aufs暂时还未被纳入linux内核主干,ununtu14支持aufs,所以docker在ubuntu上面使用aufs,而作为比较老旧的redhat系列上,docker使用的devicemapper(Centos7.4之前),Centos7.4之后使用的是overlay2
基于LXC
的,容器的创建、启用、停止、销毁也是用LXC的命令一个容器只运行一个进程
(注1:该进程+其子进程)(注2:LXC本身是没这个限制的)联合挂载
来实现(如底层是centos,上层分别是nginx、mysql,然后centos与nginx、centos与mysql分别进行联合挂载,且默认centos只读
),若想centos可改,就需要在这两层之间加中间层来实现;同时为了方便迁移,通常不在容器本地保存有效数据,而是在容器外部挂载一个共享存储容器编排工具
来解决这个问题(如,docker的machine+swarm+compose组合、asf的mesos+marathon组合、kubernetes即k8s)libcontainer
容器引擎,替换了最开始的LXC
;后来为了标准化的标准,又替换为了runC
(runContainer)