Docker和K8S已经是当下运维的必备技能,无论是行业技能要求还是前沿技术领域,现在还不能很好掌握这两门技术的技术人员,在新一轮的技术迭代中将最终被抛弃。
AA6FB025-6CB8-4A96-B91D-702CD632331B
Docker其实是一门容器化技术,也是虚拟化技术的一种,只是相对传统的kvm,xen,vmware虚拟化技术而言,是基于进程级别的虚拟化技术,更为轻量,因而性能损耗更小。
虚拟化技术并不是一门新技术,最小可以追溯到LXC技术!
LXC为linux Container的简写。可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。相当于C++中的NameSpace。容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求。与传统虚拟化技术相比,它的优势在于:
总结:Linux Container是一种轻量级的虚拟化的手段,提供了在单一可控主机节点上支持多个相互隔离的server container同时执行的机制。Linux Container有点像chroot,提供了一个拥有自己进程和网络空间的虚拟环境,但又有别于虚拟机,因为LXC是一种操作系统层次上的资源的虚拟化
这里衍生出来另外一个问题?LXC技术最早可以追溯到20世纪70年代,计算机系统刚诞生的时代,即LXC和系统是强关联,为什么一直到2010年左右才开始在历史舞台大紫大红呢?
这里其实要讲到进程和隔离了。
进程与隔离
没有电的电脑只是一堆废铁,通了电的电脑只是一堆带电的废铁!! 这句话充分诠释了操作系统的重要性。
由于计算机只认识二进制 0 和 1,所以无论哪种语言的实现,最后都需要通过某种方式编译为二进制文件,才能在计算机操作系统中运行起来。
而为了能够让这些代码正常运行,我们还需要数据、代码运行平台即操作系统。比如我们这个加法程序所需要的输入文件。这些数据加上代码本身的二进制文件,放在磁盘上,就是我们平常所说的一个“程序”,也叫代码的可执行镜像(executable image)。
然后,我们就可以在计算机上运行这个程序了。
而 CPU 与内存协作进行加法计算,又会使用寄存器存放数值、内存堆栈保存执行的命令和变量。同时,计算机里还有被打开的文件,以及各种各样的 I/O 设备在不断地调用中修改自己的状态。
就这样,一旦 程序 被执行起来,它就从磁盘上的二进制文件,变成了计算机内存中的数据、寄存器里的值、堆栈中的指令、被打开的文件,以及各种设备的状态信息的一个集合。像这样一个程序运行起来后的计算机执行环境的总和,就是我们今天的主角:进程。
从上面可以看到,操作系统也是进程,只是其无比复杂,复杂到可以把自己“虚拟成平台”并承载其它进程运行的程序,而操作系统在这个过程中起到两个非常重要的角色是:资源分配和资源隔离。
资源分配
众所周知,Linux多用户操作系统,即意味着可以多个同时使用操作系统,但操作系统只有一个大脑(无论是几个物理核心,其实真正都在同一时间只有一个核心工作,虽然现代多核心技术在多核心协作上做了非常精巧的设计)。
那么操作系统究竟该如何分配资源呢?如图是top命令的返回,第一列是进程ID,大家可能已经想到了,就是进程ID. 进程ID越小,优先级越高。进程ID是系统判断资源分配的重要依据 。
当然,现代操作系统都是并行性操作系统,想像这么一个场景:如果有多个进程都在申请同一块内存,而另外一个进程一直在占用这块内存不肯释放,此时操作系统该怎么办呢?这种情形称为“死琐”,早在2.6版本以前的内核,在资源分配和资源隔离做的并不理想。尤其是资源隔离
资源隔离
程序的正常运行最少需要如下这些资源:
容器化
其次还有非常重要的文件系统资源,和传统虚拟化不同。传统虚拟化是在磁盘上划分出来一块空间,在此空间上虚拟一个完整的操作系统,所有的资源与真实主机隔离。隔离安全性有保障,但性能损失不容忽视。
而Docker容器化不同的地方是Docker并不是一个操作系统,而只是真实物理机操作系统中的一个进程,通过该进程来调用内核资源,使用rootfs文件系统技术和cgroup隔离动技术,实现资源隔离。
性能几乎无损耗,但隔离技术门槛较高,且3.10之前的内核版本不支持。时至今日,Docker在虚拟化隔离也不能做到安全性100%。
介绍这么多,大家千万不要误解是因为Docker性能损耗少所以大红大紫,真正促使Docker如日中天的原因其实是PAAS的发展
docker
从本世纪初开始,云计算的呼声不断,到2009年王坚博士“骗”了马云10个亿创建阿里云,到现在阿里3年2000亿、腾讯5年5000亿在新基建的大力投入,不过短短20年时间。从早期的AWS,azure外资独大,到现在阿里、腾讯、华为云独占云市场鳌头,如日中天的AWS和盛极一时的OpenStack,带动整个IT产品迈向PAAS时代.
但事情的发展总不以人的意识为导向。在家名为 dotCloud的公司在PAAS的浪潮中坚持不下去,无奈开源他们容器化项目:Docker。
令dotCloud公司自己都没想到的是,这竟然会让他们站在浪潮之巅并有机会和RedHat和google一战雌雄,甚至逼的Google不得不和RedHat合作,并拿出自家核秘密武器Brog却只为求得生存。
“容器”这个概念从来就不是什么新鲜的东西,也不是 dotCloud 公司发明的。所以dotCloud 开源的决定在当时根本没人在乎。
PaaS 项目被大家接纳的一个主要原因,就是它提供了一种名叫“应用托管”的能力。在当时,虚拟机和云计算已经是比较普遍的技术和服务了,用户主流用法,就是租一批 AWS 或者 OpenStack 的虚拟机,然后像以前管理物理服务器那样,用脚本或者手工的方式在这些机器上部署应用。
当然,这个部署过程难免会碰到云端虚拟机和本地环境不一致的问题,所以当时的云计算服务,比的就是谁能更好地模拟本地服务器环境,能带来更好的“上云”体验。而 PaaS 开源项目的出现,就是当时解决这个问题的一个最佳方案。
Cloud Foundry是当时 PAAS 的平台龙头。在Docker开源时,其产品经理 james Bayer在社区做过详细对比,并告诉大家 Docker 实际上只是一个同样使用了 cgroup 和Namespace 的"沙盒"工具而已,并不需要特别关注。
但仅在短短几个月后,Docker就迅速崛起,速度之快连包括 Cloud Foudry 在内的所有 PAAS 公司没来得及反应就out了.
而引导这一现象的原因却仅仅是**Docker的镜像功能**。
恐怕连 Docker 项目的作者 Solomon Hykes 自己当时都没想到,这个小小的创新,在短短几年内就如此迅速地改变了整个云计算领域的发展历程。
PaaS 之所以能够帮助用户大规模部署应用到集群里,是因为它提供了一套应用打包的功能。可偏偏就是这个打包功能,却成了 PaaS日后不断遭到用户诟病的一个“软肋”。
用户一旦使用了 PaaS,就必须为每种语言、每种框架,甚至每个版本的应用维护一个打好的包。这个打包过程,没有任何章法可循,更麻烦的是,明明在本地运行得好好的应用,却需要做很多修改和配置工作才能在 PaaS 里运行起来。而这些修改和配置,并没有什么经验可以借鉴,基本上得靠不断试错,直到你摸清楚了本地应用和远端 PaaS 匹配的“脾气”才能够搞定。
而 Docker 镜像解决的,恰恰就是打包这个根本性的问题
就这样,容器化的时代开始了!
k8s
那Docker和k8s又有什么关系呢?
前面介绍,Docker 项目一日千里的发展势头,但用户们最终要部署的,还是他们的网站、服务、数据库,甚至是云计算业务。
这就意味着,只有那些能够为用户提供平台层能力的工具,才会真正成为开发者们关心和愿意付费的产品。而 Docker 项目这样一个只能用来创建和启停容器的小工具,最终只能充当这些平台项目的“幕后英雄”。
即要想Docker能大面积普及,还需要解决大量Docker的协作编排问题。
谈到Docker容器编排问题,就不得不说说 Docker 公司的老朋友和老对手 CoreOS 了。CoreOS 是一个基础设施领域创业公司。它的核心产品是一个定制化的操作系统,用户可以按照分布式集群的方式,管理所有安装了这个操作系统的节点。从而,用户在集群里部署和管理应用就像使用单机一样方便了.
Docker 项目发布后,CoreOS 公司很快就认识到可以把“容器”的概念无缝集成到自己的这套方案中,从而为用户提供更高层次的 PaaS 能力。所以,CoreOS 很早就成了 Docker 项目的贡献者,并在短时间内成为了 Docker 项目中第二重要的力量。
然而,这段短暂的蜜月期到 2014 年底就草草结束了。CoreOS 公司以强烈的措辞宣布与 Docker 公司停止合作,并直接推出了自己研制的 Rocket(后来叫 rkt)容器。
这次决裂的根本原因,正是源于 Docker 公司对 Docker项目定位的不满足。Docker 公司解决这种不满足的方法就是,让 Docker 项目提供更多的平台层能力,即向 PaaS 项目进化。而这,显然与 CoreOS 公司的核心产品和战略发生了严重冲突。
大红大紫不差钱的 Docker 开始大私收购来完善自己的生态和平台能力。最出名的莫过于 Fig项目,即现在的 Compose,除此外,还有 SocketPlane, Flocker, Tutum等项目。
Docker的异常繁荣终于引起了行业巨头的关注。
作为 Docker 项目早期的重要贡献者,RedHat 也是因为对 Docker 公司平台化战略不满而愤愤退出。但此时,它竟只剩下 OpenShift 这个跟 Cloud Foundry 同时代的经典 PaaS 一张牌可以打,跟 Docker Swarm 和转型后的 Mesos完全不在同一个“竞技水平”之上。
2014年6月,基础设施领域的翘楚 Google 公司突然发力,正式宣告了一个名叫 Kubernetes项目的诞生。而这个项目,不仅挽救了当时的 CoreOS 和 RedHat,还如同当年 Docker项目的横空出世一样,再一次改变了整个容器市场的格局。
2015年6月22日,由 Docker 公司牵头,CoreOS、Google、RedHat 等公司共同宣布,Docker公司将 Libcontainer 捐出,并改名为 RunC 项目,交由一个完全中立的基金会管理,然后以 RunC 为依据,大家共同制定一套容器和镜像的标准和规范。
但由于 OCI 的成立更多的是这些容器玩家出于自身利益进行干涉的一个妥协结果。所以OCI的组织效率一直很低下。
Docker 公司之所以不担心 OCI 的威胁,原因就在于它的 Docker 项目是容器生态的事实标准,而它所维护的 Docker 社区也足够庞大。可是,一旦这场斗争被转移到容器之上的平台层,或者说 PaaS 层,Docker 公司的竞争优势便立刻捉襟见肘了。
Google、RedHat 等开源基础设施领域玩家们,为了牵制Docker,共同牵头发起了一个名为 CNCF(Cloud Native Computing Foundation)的基金会。这个基金会的目的其实很容易理解:它希望,以 Kubernetes 项目为基础,建立一个由开源基础设施领域厂商主导的、按照独立基金会方式运营的平台级社区,来对抗以 Docker 公司为核心的容器商业生态。
k8s早先在社区一直被认为太过前卫先进,但随着时间的发展,GOOGLE的工程能力也逐步得到社区的认可。而没有大规模验证的 swarm 逐步淡出人们视野。
2016 年,Docker 公司宣布了一个震惊所有人的计划:放弃现有的 Swarm 项目,将容器编排和集群管理功能全部内置到 Docker 项目当中。
到此,容器编排之争落下帷幕。