容器技术:一句话来说明就是“进行了进程隔离和资源限制的进程” |
一、什么是容器?
首先,从现实生活上说,容器是用来省东西的,如柴米油盐酱醋茶、洗发水护发素沐浴露等都需要各式各样的容器来盛装。这是“容器”这个词给人们的第一印象。
而我们这个说的“容器”(英文:Container)也是用来盛装东西的,只是这个东西比较特别,是一个软件应用。在英文中Container这个词含义更偏向于“集装箱”,这也是很多介绍容器的文章中有很多集装箱的配图,为什么老外喜欢用“集装箱”这个含义呢?
因为集装箱规格统一,方便装卸、运输,而不必在意集装箱内部的物品是什么,也许是一箱水果、一箱鸡蛋、一箱药品、一箱Iphone、一箱娃娃、一箱带病毒的海鲜产品等等,只要他们按照自己的要求(添加防腐、防潮、防撞、防变质等措施)放到集装箱中就可以了,码头运输人员、远洋货轮根本就不必关心在意其中的货物。这就大大节省了中间运输的成本,提高了效率。
而互联网中的“容器”技术便是借鉴了这个理念。
将自己的应用及其依赖环境打包成一个“集装箱”,然后这个“集装箱”可以运输到任何需要的地方,然后将其放到相应的环境中直接可以运行、部署,不再需要安装各种动态库、静态库、移植python、移植mysql等等。
为什么就这么懒呢?手动安装不行吗?我又不嫌麻烦,我还想练练手搭建环境呢!!! 这里忽然想到一个冷笑话:
测试人员:这个版本跑不起来呀,一直报错 |
开发人员:可能是你的环境缺少某些库的缘故吧 |
测试人员:那你的环境怎么搭建的? |
开发人员:我使用的环境是别人搭建的 |
测试人员:那个人呢? |
开发人员:他离职了 |
… …全场安静 |
一台也许可以、两台也行,但是现在大公司都是集群化服务,服务器成千上万太,你确定要每一台都搭建一遍吗?当然不是吧,首先能想到的就是做一个打包好的环境,放到设备无需多余配置,直接可以运行的方案,也就是“Build Once, Run anywhere.”(这个Docker的一个口号)。这便是“容器技术”的由来。
说道刚才这个例子,有人可能会有一个疑问:我把的应用程序环境所在的虚拟机直接打包不行吗? 然后拿着我打包好的虚拟机镜像拷贝到成千上万的集群服务器上。关于这个问题,在第四小节中做一个对比。这里我想说的是“容器技术”和“虚拟化技术”有很深的渊源,我们需要对这两个新技术有一个明确的认识。
二、容器是如何实现的?
容器技术,从通俗意义上讲是一种“沙箱技术”(百度百科:沙箱技术在计算机安全领域中是一种安全机制,为运行中的程序提供的隔离环境。通常是作为一些来源不可信、具破坏力或无法判定程序意图的程序提供实验之用)。 容器技术,就是像集装箱装货物一样,将应用程序以及依赖环境打包并装起来,这样应用与应用之间就有了边界而不至于互相干扰,此外被装进“集装箱”的应用程序可以方便的搬移、运输。
下面介绍下:Linux实现容器技术的实现方式。
我们知道一个程序被执行起来之后,它就会从磁盘上的二进制文件,变成了计算机内存中的数据、寄存器里的值、堆栈中的指令、被打开的文件,以及各种设备的状态信息的一个集合也就是一个进程。
所以,对于进程来说,它的静态表现就是程序,平常都安安静静地待在磁盘上;而一旦运行起来,它就变成了计算机里的数据和状态的总和,这就是它的动态表现。而容器技术的核心功能,就是通过约束和修改进程的动态表现,从而为其创造出一个“边界”。正是因为这个边界才会让容器里面的程序看不到宿主机上其他的程序从而给程序一种它就是在一个独立的操作系统上的假象。
Linux Container容器技术的诞生(2008年)就解决了IT世界里“集装箱运输”的问题。Linux Container(简称LXC)它是一种内核轻量级的操作系统层虚拟化技术。Linux Container主要由Namespace和Cgroup两大机制来保证实现。
对于 Docker 等大多数 Linux 容器来说,Cgroups和Namespace 技术就是它们实现的关键。
那么Namespace和Cgroup是什么呢?
刚才我们上面提到了集装箱,集装箱的作用当然是可以对货物进行打包隔离了,不让A公司的货跟B公司的货混在一起,不然卸货就分不清楚了。那么Namespace也是一样的作用,做隔离。
光有隔离还没用,我们还需要对货物进行资源的管理。同样的,航运码头也有这样的管理机制:货物用什么样规格大小的集装箱,货物用多少个集装箱,货物哪些优先运走,遇到极端天气怎么暂停运输服务怎么改航道等等... 通用的,与此对应的Cgroup就负责资源管理控制作用,比如进程组使用CPU、内存、网络、磁盘、IO等资源的限制,进程组的优先级控制,进程组的挂起和恢复等等。
Namespace 和Cgroup是Linux内核提供的用于进程组资源隔离和配额的技术手段。docker等Linux容器都是基于此项技术实现的。
- Namespace
实现内核级虚拟化(容器)服务,让同一个Namespace下的进程可以感知彼此的变化,同时又能确保对外界的进程一无所知,以达到独立和隔离的目的。
目前namespace实现包括如下7种:
namespace种类 | 作用 |
cgroup | 提供基于CGroup的隔离能力 使不同进程组看到的CGroup的能力各不相同 |
IPC | 提供基于System V进程信道的隔离能力 IPC包括共享内存、信号量、消息队列等 IPC隔离使得只有在相同命名空间的进程间才能通讯 |
mnt | 提供基于磁盘挂载点和文件系统的隔离能力 为隔离空间创建独立的mount节点树 在文件系统的隔离作用下,容器中的进程将无法访问容器以外的任何文件。必要的时候可以通过挂在额外的目录与主机共享文件系统 |
net | 提供基于网络协议栈的隔离能力 让每一个容器通过命名空间来隔离和管理自己的网卡配置 虚拟网卡可以通过(NAT、Vxlan、SDN等)连接到实际的物理网卡上,从而实现像普通的物理主机一样网络通讯 |
pid | 提供基于进程的隔离能力 进程隔离使得在容器内的首个进程成为所在命令空间PID为1的进程 PID为1的进程很特殊,它作为所在命名空间所有进程的父进程,有很多特权,如屏蔽信号,接管孤儿进程。 |
User | 提供基于用户的隔离能力 同一系统用户在不同的命名空间中,可以拥有不同的UID和GID,他们之间存在一定的映射关系,so在特定命名空间UID为0的用户不一定为root系统管理用户 该特定限制了容器的用户权限,有利于保护主机系统的安全 |
uts | 提供基于主机名的隔离能力 每一个独立容器空间中的程序可以拥有不同的主机名称信息 主机命令不唯一,可以重复 |
- Cgroup
Linux内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(包括CPU、内存、磁盘I/O速度等)的机制,也是容器管理虚拟化系统资源的手段。
Linux 4.7.1内核中提供了10类不同子系统,分别如下表所示:
CGroup种类 | 作用 |
hugetlb | 限制进程对大页内存(Hugepage)的使用 |
memory | 限制进程对内存和Swap的使用,并生成每个进程使用的内存资源报告 |
pids | 限制每个CGroup中能够创建的进程总数 |
cpuset | 在多核系统中为进程分配独立CPU和内存 |
devices | 允许或拒绝进程访问特定设备 |
net_cls和net_prio | 标记每个网络包,并控制网卡优先级 |
cpu和cpuacct | 限制进程对CPU的用量,并生成每个进程所使用的CPU报告 |
freezer | 挂起或恢复特定的进程 |
blkio | 为进程对块设备(如磁盘、USB等)限制输入/输出 |
perf_event | 监测属于特定的CGroup的所有线程以及运行在特定CPU上的线程 |
参考 <https://www.cnblogs.com/karl-python/p/9224172.html>
参考 <https://cloud.tencent.com/developer/article/1116709>
参考 <https://cloud.tencent.com/developer/article/1461273>
三、容器相关的基本概念
参考:SaaS vs PaaS vs IaaS: What’s The Difference & How To Choose
参考:Kubernetes系列学习文章 - 什么是容器云?(一)
概念 | 含义 |
IAAS | Infrastructure As A Service |
PAAS | Platform As A Service |
SAAS | Software As A Service |
当前,云服务模型通常分为3层:即IAAS层, PAAS层, SAAS层。每一种服务模型都有自己的特点。从技术层面上讲,云计算的发展思路基本按照:虚拟化、网络化、分布式技术---------> IAAS技术-------->PAAS技术------------>SAAS。
每一个阶段业界都有相应的开源或非开源的技术为代表,比如:
- 虚拟化阶段,以Xen、vSphere、KVM等技术
- IAAS层是OpenStack
- PAAS层是Kubernetes(又称为K8s)
- SAAS层,目前开源界还没有典型的代表,AWS推出了Lambda
下面分别简要说明这三种服务模型的差异。
- IAAS: 基础架构即服务
云基础架构服务称为基础架构即服务(IaaS),由高度可扩展和自动化的计算、网络、存储等资源组成。 IaaS是完全自助服务,用于访问和监控计算、网络,存储和其他服务等内容,它允许企业按需求和需要购买资源,而不必购买全部硬件。
IaaS通过虚拟化技术为基础提供云计算基础架构,包括服务器、网络,操作系统和存储等。这些云服务器通常通过仪表盘或API提供给客户端,IaaS客户端可以完全控制整个基础架构。 IaaS提供与传统数据中心相同的技术和功能,而无需对其进行物理上的维护或管理。 IaaS客户端仍然可以直接访问其服务器和存储。
IaaS客户端负责管理应用程序、运行时、操作系统,中间件和数据等方面,IaaS的提供商管理服务器、硬盘驱动器、网络,虚拟化和存储。一些提供商甚至在虚拟化层之外提供更多服务,例如数据库或消息队列。
IAAS的优势:
- 最灵活的云计算模型
- 轻松实现存储、网络、服务器和处理能力的自动部署
- 可以根据消耗量购买硬件
- 使客户端完全能够控制其基础架构
- 可以根据需求购买资源
- 高度可扩展性
- PAAS: 平台即服务
云平台服务或平台即服务(PaaS)为某些软件提供云组件,这些组件主要用于应用程序。 PaaS为开发人员提供了一个框架,使他们可以基于它创建自定义应用程序。所有服务器,存储和网络都可以由企业或第三方提供商进行管理,而开发人员可以负责应用程序的管理。
PaaS的交付模式类似于SaaS,除了通过互联网提供软件,PaaS提供了一个软件创建平台。该平台通过Web提供,使开发人员可以自由地专注于创建软件,同时不必担心操作系统、软件更新,存储或基础架构。
PaaS允许企业使用特殊的软件组件设计和创建内置于PaaS中的应用程序。由于具有某些云特性,这些应用程序或中间件具有可扩展性和高可用性。
PAAS的优势:
- 使得应用程序的开发部署变得简单、经济、高效
- 可扩展
- 高度可用
- 开发人员能够创建自定义应用程序,无需维护软件
- 大大较少编程量
- 自动化业务策略
- 允许轻松迁移到混合模型
- SAAS: 软件即服务
软件即服务(也称为云应用程序服务)代表了云市场中企业最常用的选项。 SaaS利用互联网向其用户提供应用程序,这些应用程序由第三方供应商管理。 大多数SaaS应用程序直接通过Web浏览器运行,不需要在客户端进行任何下载或安装。(例如在线版的邮箱、QQ、音乐、地图、美团外卖等)
由于其网络传输模式,SaaS无需在每台计算机上下载和安装应用程序,而在每台计算机上下载和安装应用程序正是IT员工的噩梦。 通过SaaS,供应商可以管理所有潜在的技术问题,例如数据、中间件,服务器和存储,因此企业可以简化其维护和支持。
SaaS通过大大减少安装,管理和升级软件等繁琐任务所花费的时间和金钱,为员工和公司提供了许多好处。 这让技术人员可以花更多时间来处理组织内更紧迫的事情和问题
SAAS的优势:
- 在统一管理
- 远程托管
- 使用互联网远程访问
- 用户无需负责硬件或者软件的更新维护工作
四、容器与虚拟机的关系
1)虚拟机原理
通过额外的虚拟化层(hypervisor),将虚拟机中运行的操作系统指令翻译成宿主机系统能够执行的系统调用然后操作具体的硬件。
优点:实现虚拟机和宿主机操作系统的异构,如在Linux系统上运行Windows的虚拟机
缺点:依赖于硬件的支持,特别是CPU虚拟化的支持
2)容器原理
完全建立在操作系统内核特性(Linux内核的namespace和Cgroup技术)之上,是一种与运行硬件无关的虚拟化技术。
优点:由于没有转换异构指令的虚拟化层,因此运行效率高于虚拟机。
缺点:只能实现与宿主机操作系统相同系统的虚拟化。
3)对比
对比项 | 容器技术(Docker为例) | 虚拟机技术 |
快速创建和删除 | 启动应用快速,秒级启动 | 启动Guest OS + 启动应用,启动时间以分钟计算。 |
交付和部署 | 容器镜像 | 虚拟机镜像 |
密度 | 单Node 100~1000 | 单Node 10~100 |
更新管理 | 迭代式更新。对增量内容进行分发、存储、传输。节点启动和回复迅速 | 向虚拟机推送安装、升级应用软件补丁包 |
Windows支持 | 支持(目前Linux下的容器居多) | 支持 |
稳定性 | 每月都进行更新 | KVM,Xen,VMware技术成熟稳定 |
安全性 | Docker具有宿主计算机root权限,安全性较差 | 硬件隔离,Guest OS运行在非root模式。比较安全 |
监控成熟度 | 发展中 | Host,Hypervisor, VM的监控工具成熟 |
高可用性 | 由业务本身的高可用性来保证 | 武器库丰富:快照、克隆、HA 动态迁移、异地容灾、异地双活 |
平台管理成熟度 | 以K8S为代表,处于快速发展中 | 以OpenStack、vCenter为代表,使用多年,技术成熟 |
|
|
|
4) 容器特点
- 敏捷环境:容器技术最大的优点是创建容器实例比创建虚拟机示例快得多,容器轻量级的脚本可以从性能和大小方面减少开销。
- 提高生产力:容器通过移除跨服务依赖和冲突提高了开发者的生产力。每个容器都可以看作是一个不同的微服务,因此可以独立升级,而不用担心同步。
- 版本控制:每一个容器的镜像都有版本控制,这样就可以追踪不同版本的容器,监控版本之间的差异等等。
- 运行环境可移植:容器封装了所有运行应用程序所必需的相关的细节比如应用依赖以及操作系统。这就使得镜像从一个环境移植到另外一个环境更加灵活。比如,同一个镜像可以在 Windows 或 Linux 或者 开发、测试或 stage 环境中运行。
- 标准化: 大多数容器基于开放标准,可以运行在所有主流 Linux 发行版、Microsoft 平台等等。
- 安全:容器之间的进程是相互隔离的,其中的基础设施亦是如此。这样其中一个容器的升级或者变化不会影响其他容器。