前言

这是一个人们对上云已经有了共识,但是对怎么样上好云还在深入讨论和探索的新阶段。

在上云之后,我们会遇到一些典型的问题,比如怎么样使用云服务器的问题。如果我们把多个业务混合部署在云服务器上,这些业务可能会因为使用了不同版本的库文件出现兼容性问题;而如果我们让每个业务实例独享一个云服务器,又会有明显的资源碎片问题。

包括了容器、编排调度、服务网格、持续集成交付(CICD)等在内的云原生技术,是“上好云”这个新阶段的核心技术,也是解决“上好云”这个问题的最佳实践策略和方法论。

作为本书的开篇,我们希望在序章部分交代清楚几件事情:

(1)多角度下的云原生“操作系统”——Kubernetes的基本理论;(2)学习和研究Kubernetes的方法;(3)本书的成书背景。

什么是Kubernetes

我们来看一下什么是Kubernetes。在这一部分,我们会从四个角度和大家分享我们的看法。

第一个角度,未来是什么样的

图0-1是一张未来企业的IT基础设施架构图。简单来说,未来基本上所有的企业都会把IT基础设施部署在云上,用户会基于Kubernetes把底层云资源分割成具体的集群单元,给不同的业务使用。

图0-1 未来企业的IT基础设施架构

之后,随着业务微服务化的落地,服务治理会越来越重要。像服务网格这类把服务治理逻辑下沉到基础设施层的思路,势必成为下一个趋势。

目前,阿里巴巴几乎所有的业务都“跑”在云上,其中一大半业务已经迁移到了内部定制版的Kubernetes集群上,而且这个比例还在迅速增加中。

对于服务网格技术来说,一些企业(比如蚂蚁集团)其实已经有线上业务在使用了。大家可以通过蚂蚁集团一些技术专家的公开分享来了解他们的实践过程。

虽然这张图里的观点可能有一些绝对,但是目前这个趋势是非常明显的。未来几年,Kubernetes肯定会像Linux一样,作为集群的操作系统无处不在。

第二个角度,Kubernetes与操作系统

图0-2是传统操作系统(单机操作系统)和云原生操作系统(集群操作系统)的比较图。大家知道,像Linux或者Windows这些传统的操作系统,它们扮演的角色是底层硬件的抽象层。它们向下管理计算机硬件,如内存和CPU,然后把底层硬件抽象成易用的接口,向上对应用层提供支持。

而Kubernetes技术,我们也可以理解为一个操作系统。这个操作系统也是一个抽象层。它向下管理的硬件,不是内存或者CPU这种硬件,而是多台计算机组成的集群。这些计算机本身就是普通的单机系统,有自己的操作系统和硬件。Kubernetes把这些计算机当成一个资源池统一管理,向上对应用层提供支撑。

图0-2 传统操作系统与云原生操作系统

Kubernetes上的应用的特别之处在于,它们都是容器化应用。对容器不太了解的读者,可以简单地把它们理解成安装包。安装包里包括了所有的依赖库,如libc函数库等,使得这些应用不必依赖底层操作系统库文件就可以直接运行。

第三个角度,Kubernetes与Google运维解密

图0-3的左边是Kubernetes集群示意图,右边是一本非常有名的书《SRE Google运维解密》。相信很多人都看过这本书,而且有很多公司正在实践这本书里的方法,如故障管理、运维排班等。

图0-3 Kubernetes集群与《SRE Google运维解密》

Kubernetes和这本书的关系,可以比作剑法和气功的关系。读者看过金庸的《笑傲江湖》的话,可能会记得,《笑傲江湖》里的华山派分为两个派别,剑宗和气宗。

剑宗强调剑法的精妙,而气宗更注重气功修炼。实际上剑宗和气宗的“分家”,是因为华山派两个弟子偷学了同一本《葵花宝典》,但是两个人各记了一部分内容,最终因为观点分歧分成了两派。

Kubernetes实际上源自Google的集群自动化管理和调度系统Borg,也就是这本书里讲的运维方法所管理的对象。Borg系统和书里讲的方法论,可以被看作一件事情的两个方面。如果一个公司只学习他们的运维方法(比如设了很多SRE职位)而不懂这套方法所管理的对象,其实就是学习《葵花宝典》,但是只学了一部分。

Borg因为是Google内部的系统,所以一般人是看不到的,而Kubernetes基本上继承了Borg在集群自动化管理方面非常核心的一些理念。所以大家如果看了这本书,觉得非常有参考价值,或者已经在实践这本书里的方法,就一定要深入理解Kubernetes。

第四个角度,技术演进史

在早期,我们做一个网站后端,可能只需要把所有的模块放在一个可执行文件里,就如同图0-4中第一个架构图一样。网站后端包括界面、数据和业务三个模块,这三个模块被编译成一个可执行文件,“跑”在一台服务器上。

但是随着业务的大幅增长,我们没有办法通过升级服务器配置的方式来使后端扩容,这时候我们就必须做微服务了。

微服务会把单体应用拆分成低耦合的小应用。这些应用各自负责一块相对独立的业务,每个小应用实例独占一台服务器,它们之间通过网络互相调用。这就是图0-4中第二个架构图的模式。

图0-4 网站后端技术演进史

这里最关键的是,我们可以通过增加实例个数,来对小应用做横向扩容。这就解决了单台服务器无法扩容的问题。

微服务之后会出现一个问题,就是一个实例独占一台服务器的问题,这种部署方式的资源浪费其实是比较严重的。这时我们自然会想到,把这些实例混合部署到底层服务器上。

但是混合部署会引出两个新问题。一个是依赖库兼容性问题,这些应用依赖的库文件版本可能完全不一样,安装到一个操作系统里,就会有兼容性问题;另一个问题是应用调度和集群资源管理的问题,比如一个新的应用被创建出来,我们需要考虑这个应用被调度到哪台服务器,以及调度之后资源够不够用的问题。

依赖库兼容性问题,实际上是靠容器化来解决的,也就是每个应用自带依赖库,只跟其他应用共享内核,而调度和资源管理问题就是Kubernetes所要解决的问题。

所以整个架构最终会演变成图0-4中第三个架构图的模式。

如何学习Kubernetes

我们会从三个方面总结我们的经验:一是为什么Kubernetes学习起来比较难,二是一些方法和建议,三是一个实际例子。

如图0-5所示,总体来说,之所以Kubernetes门槛比较高,学习起来比较困难,一个原因是它的技术栈非常深,包括内核和系统,以及虚拟化、容器技术、网络、存储、安全,甚至可信计算等,绝对可以称得上全栈技术。

图0-5 Kubernetes学习难度

同时,Kubernetes在云环境中的实现,肯定会涉及非常多的云产品,比如在阿里云上,Kubernetes集群的实现用到了云服务器、虚拟网络、负载均衡、安全组、日志服务、云监控、ahas和arms等中间件产品、服务网格、弹性伸缩等。

最后,因为Kubernetes是一个通用的计算平台,所以它会被用到各种业务场景中去,比如数据库、边缘计算、机器学习、流计算等。

基于我们的经验,学习Kubernetes需要从了解、动手、思考三个方面去把握,如图0-6所示。

图0-6 学习Kubernetes的三个步骤

首先,了解其实很重要,特别是了解技术的演进史,以及技术的全景图。

一方面,我们需要知道各种技术的演进历史,比如容器技术是怎么从chroot这个命令发展而来的,以及技术演进背后要解决的问题是什么,只有知道技术的演进史和发展的动力,我们才能对未来技术方向有自己的判断。

另一方面,我们需要了解技术全景图。对Kubernetes来说,我们需要了解整个云原生技术栈,包括容器、CICD、微服务、服务网格等,知道Kubernetes在整个技术栈里所处的位置。

其次,除了这些基本的背景知识以外,学习Kubernetes技术,动手实践是非常关键的。

从我们和大量工程师一起解决问题的经验来说,很多人其实不会去深入研究技术细节。我们经常开玩笑说工程师有两种,一种是search engineer,就是搜索工程师,一种是research engineer,就是研究工程师。很多工程师遇到问题,就用搜索引擎搜索一下,如果找不到答案,就直接请别人帮忙了。这样是很难深入理解一个技术的。

最后,就是怎么去思考,怎么去总结了。我们需要在理解技术细节之后,不断地问自己,细节的背后有没有什么更本质的东西。也就是我们要把复杂的细节看简单,然后找出普遍的模式来。

下面用一个例子来具体解释上面的方法。

这个例子是关于集群控制器的,如图0-7所示。我们在学习Kubernetes的时候会听到几个概念,像声明式API、Operator、面向终态设计等。这些概念本质上都是在讲一件事情,就是控制器模式。

我们怎么来理解Kubernetes的控制器呢?请大家先看一下第一张图。这张图是一个经典的Kubernetes架构图,这张图里有集群Master(管控)节点和Worker(工作)节点,Master节点上有中心数据库(Database)、集群接口(API Server)、调度器(Scheduler)以及各类控制器(Controller)。

图0-7 深入理解集群控制器原理

中心数据库是集群的核心存储系统,API Server是集群的管控入口,调度器负责把应用调度到资源充沛的节点上,而控制器是我们这里要说的重点。

控制器的作用,我们用一句话概括,就是“让梦想照进现实”。从这个意义上来讲,我自己(罗建龙)也经常扮演控制器的角色,我女儿如果说,“爸爸,我要吃冰激凌”,那我女儿就是集群的用户,我就是负责把她这个愿望实现的人,也就是控制器。

除了Master节点以外,Kubernetes集群有很多Worker节点,这些节点都部署了Kubelet和Proxy这两个代理。Kubelet负责管理Worker节点,包括应用在节点上启动和停止之类的工作。Proxy负责把服务的定义落实成具体的iptables或者ipvs规则。其实这里服务的概念,简单来说就是利用iptables或者ipvs来实现负载均衡。

如果从控制器的角度来看第一张图的话,我们就会得到第二张图。也就是说,集群实际上就包括一个数据库、一个集群入口,以及很多个控制器。这些组件,包括调度器、Kubelet和Proxy在内,实际上都是在不断地观察集群里各种资源的定义,然后把这些定义落实成具体的配置,比如容器启动或iptables配置。

从控制器的角度观察Kubernetes,我们其实得到了Kubernetes最根本的一条原理,就是Kubernetes是按照控制器模式运行的。

控制器模式在我们的生活中无处不在,这里我拿冰箱举个例子。我们在控制冰箱的时候,并不会直接去控制冰箱里的制冷系统或者照明系统。我们打开冰箱的时候,里边的灯会打开,在我们设置了想要的温度之后,就算我们不在家,制冷系统也会一直保持这个温度。这背后就是因为有控制器模式在起作用。

关于本书

本书是阿里云容器服务Kubernetes(Alibaba Cloud Container Service for Kubernetes,缩写为ACK)云上实践的技术结晶,主要包括两部分内容。一部分是以技术进阶为主题的理论篇,另一部分是以案例分析为主题的实践篇。

本书总结起来有三个特点:第一个是创新性地阐述了Kubernetes的一些核心原理,第二个是有阿里云线上真实案例诊断集锦,第三个是首创了一些Kubernetes诊断方法和调试方法。

首先,我们的一项重要工作是技术服务,我们需要用创新的方式,把一些生涩难懂的技术解释给用户听。这本书中对技术的解释是比较形象也比较易懂的。

其次,我们每天都在处理疑难、复杂的问题。部分问题因为复现概率极小,可能需要几个月才出现一次。这样的问题也只有在阿里云这样的大平台上才有机会复现和诊断出结果。这本书就包括了一些这样的案例。

最后,这本书里的案例分析,肯定会涉及多个Kubernetes组件,以及针对这些组件问题的调试方法,读者一般不能在其他地方看到这些方法。

致谢

首先,感谢阿里云数字新基建系列丛书的编委会,包括李津、刘湘雯、沈乘黄、刘松、孟晋宇、张小亮、万谊平、宋欢欢、周裕峰、郭雪梅、宿宸、刘明、李娅莉、王佩杰、朱智敏、李若冰、解国红、江冉、王超、张雯。同时感谢所有在本书撰写、编辑和出版过程中给予过帮助的同事,包括阿里云全球技术服务部的冯明星、杨岳林、盛梦晓,基础产品事业部的易立、汤志敏、王炳燊、谢瑶瑶、阚俊宝、王夕宁、谢于宁、匡大虎、孟小兵、陈全照、萧元、张良、王蓉、姜曦,蚂蚁集团的王旭。没有你们的输入和智慧,书中的内容不可能被整理成册。

其次,感谢阿里巴巴技术委员会的导师们,你们的技术视野和技术领导力,是促进本书成册的主要力量。

最后,感谢电子工业出版社的张彦红编辑和高丽阳编辑,没有你们专业的指导和持续的推进,这本书中的内容也不会以图书的形式与读者见面。

特别感谢本丛书设计师李玲,她把“上云”与“迁徙”联系在一起,才有了本丛书以“迁徙”为主题的设计方案。