云原生这个概念已经被Gartner评为2022最受关注的技术术语,因此现在的问题已经不是你要不要学云原生的问题,而是When的问题。云原生本质上是我们构建分布式应用程序的一种设计和架构思路(笔者认为架构本身就是一种设计,而架构的核心就是为了解决复杂度,简单容易理解的东西根本不需要架构设计),并且云原生更多描述的是结果,也就是你构建的应用程序应该具备什么样的”特征“,才能算得上云原生应用程序。
当然理解了这些云原生的特征(比如应用的无状态,可观测性,配置和业务逻辑代码分离,基础设施代码化等),我们还是无从下手,因此业界的各位先驱们把自己一线的实践总结成了云原生的多种模式,来解决助架构师或者系统设计人员在构建系统时How的问题。具体来说,业务目前一共有6种核心的模式,每种模式具体解决了整个分布式应用的不同关注点,他们是:(多个服务之间的信息交换模式)communication, 服务的治理和组合模式(connectivity and composition),数据管理模式(data management), 事件驱动架构模式(event-driven architecture),流处理模式(stream processing),以及API统一管理模式(API management and consumption)。
这些模式的落地实施基本都和微服务相关,虽然说我们微服务架构本质上就是模块化应用的设计,传统的SOA架构其实也算是模块化设计,但是微服务架构对涉及到服务组合和聚合部分拆分的更加彻底,去掉了SOA架构依赖的ESB这一层,因此灵活性和可扩展性就变得更高。但是这也造成了很多理解上的混乱,很多人都听说过原子服务和组合服务,聚合服务的概念,甚至还有领域服务这样的概念,这么概念让很多刚刚入行的架构师束手无策,因为这个服务划分和粒度是没有标准的,那句拆分出粒度合适的服务基本等于没说。不过笔者在这篇文章中不想展开讨论微服务的拆分,而是希望大家能够从业务的维度,服务的并发量未付,服务的变化频率等维度来考虑。一个基本的原则是从大到小要由于一开始分的太细而进行服务合并。
微服务架构下应用的部署有很多种模式,不过如果读者完全不知道微服务应该如何部署,那只需要了解容器化部署方式就行了,这应该是未来几年整个企业级应用部署市场的事实标准。容器化部署当然售前要理解什么是容器了,这也是笔者写这篇文章的目的,饶了一大圈终于说到重点了。容器这个概念绝对是未来几年行业的热门术语,它和云原生是企业级应用程序的两个面,容器这面代表是应用程序物理特征,而云原生代表的是应用特征。
应用程序是当前大部分企业主营业务的血管,数据就如同血液一样在应用程序中流淌,从一个部门流到另外一个部门,从而为企业产生价值。如果应用程序宕机,企业的业务会受损,甚至有的时候会造成生命安全损失,因此随着数字化的深入,应用程序的稳定性和可靠性会变得越来越重要。
过去我们通常将应用程序直接运行在物理机器上,并且大部分情况下一台机器只会运行一个应用程序,而造成这种看似资源浪费的部署方式主要由同一台机器的操作系统提供的隔离程度并不完整,我们没法在同一个操作系统上安全的运行多个应用程序(如果你听过dll hell,那么就非常清楚我再说什么!)。
由于这种局限性的存在,每次我们要开发一个新的业务系统的时候,总是伴随着购买新的服务器,而最大的问题是我们并不知道要买多大规格的服务器来支撑新的业务(我们不希望,也不想由于服务能力不足导致用户的请求没有办法被满足,特别是电商类的应用),而这种不确定性和压力导致IT部门总是按最大的预估量以及增加额外的冗余来购买硬件资源,结果是大量的硬件资源被限制,拒某机构统计,这种模式下平均只有5-10%的硬件资源被真正使用到。特别是当前大环境下大家都在谈碳中和,如何降低IT资源浪费显得尤为重要。
不过在容器化出现之前,VMWare就给行业献上了大礼:(今天的新闻是VMWare从Dell拆分出来了,这是好事情,看好VMware在企业级部署市场继续amazing)虚拟机(也叫Virtual Machine)。虚拟机推出之后,一夜间让全世界的企业都趋之若鹜,我们终于有一种成熟的技术来在一台机器上安全的运行多个应用程序。
坦白讲,虚拟机技术是真的Game Changer(游戏规则改变者),IT部门终于不需要每次为新的应用程序购置服务器,因为虚拟机的存在,我们可以从现有机器中选择有资源空间的机器来创建对应的虚拟机来运行新的应用程序。这种通过VM部署应用程序的方式让企业的资源使用率得到的提升,反过来看就是省钱,何乐而不为呢!
看美剧多的同学应该都听过一句话,任何事情都有but。对于虚拟机这种部署模式来说,虽然说很优秀,但是(but)还远不能称之为完美。关注虚拟化技术的同学应该知道虚拟机本质上就是在宿主机上运行一个完整的guest操作系统,而这也是虚拟机这种部署方式最大的缺点(笔者试图客观的来看这个问题,因为技术发展了,我们才有机会说这是虚拟机部署的缺点)。
由于Guest操作系统需要消耗CPU,内存等资源,因此在一台物理机上运行多台虚拟机的结果是,留给应用程序本身的资源就不多了。另外操作系统需要授权费用,并且操作系统都需要维护,因此运行大量的虚拟机推高了系统运维的成本,这包括时间上和金钱上两个维度。虚拟机这种部署方式除了资源消耗的问题外,还包括启动慢,迁移困难等问题,比如我们在多个平台之间或者云下和云上之间迁移应用程序会非常繁琐,你可以考虑一下拷贝几个G的VM虚拟机是个什么感觉,更为糟糕的是,会有多个G级别的虚拟机文件需要拷贝。
虚拟机部署的问题不光让中小企业的倍感煎熬,同时也让像谷歌这样的大厂奋发图强,积极的探索新的技术来解决虚拟机的短板。而容器技术在Docker出现之前,就已经在谷歌内部实践十多年了。容器经常被用来类比为轻量级的虚拟机,虽然我们都知道(看过笔者容器本质系列文章的同学)这种类比非常不准确,因为容器技术是不需要独享的操作系统内核,并且实时上,运行在同一台物理机上多个容器和操作系统共享操作系统内核。而这种机制的好处显而易见,释放了大量的CPU,内存等资源给应用程序使用。同时由于不需要额外的操作系统,因此授权费用和运维的费用也得到的缩减,整体上来看,企业省钱了。
除了节省资源省钱之外,容器技术由于不需要独享的操作系统,我们在对应用进行扩容的时候,启动时间就基本和在操作系统上启动进程相同,速度非常快;容器的跨平台特性要优秀很多,无论是自己的笔记本,还是云平台,都可以无缝的衔接,开发人员终于不用为“在我电脑上运行的好好的”这样的问题绞尽脑汁了。
容器技术当然不是突然出现,任何新事物都会经历演进的过程,而容器技术不例外,是很多杰出的企业和计算机专家长期共同努力的结果。这里举个小小的例子,谷歌为Linux操作系统内核贡献了很多容器相关的技术,也是容器三个支柱:Namespace,Cgroup和Chroot发展的重要来源,可以毫无夸张的说,如果没有谷歌等公司和个人的杰出工作和无私的奉献,就没有我们今天的容器化平台Docker,容器编排平台Kubernetes等。
除了刚才提到的容器技术三个支柱之外,促成容器化部署大发展还包括了联合文件系统(union filesystems),Docker技术等。虽然Docker公司最近几年从事业的巅峰下滑的有点快,但是我们不能否认这只小鲸鱼为企业级部署市场做出的贡献。原因很简单,虽然说容器技术的支柱在Linux操作系统中已经存在很多年了,正是由于Docker公司的远见和聪明才智,让容器技术走进了寻常企业“家”,可以毫不夸张的说,如果没有Docker公司,我们离全民容器化部署要晚上好多年。
注:在Docker出现之前,虚拟化技术已经有了长足的发展,有些甚至可以追溯到IBM的System/360操作系统。BSD jails以及Solaris Zone都是在Unix操作系统上赫赫有名的容器化技术,不过笔者不打算讨论这些古老的技术,原因很简单,我们应该不会再使用这些技术了。
Docker对容器技术的贡献很那用几句话说清楚,不过大家只要记住关键一句就行:Docker让容器技术使用边的简单,笔者更喜欢用自己编的这句话:Docker,释放你服务器的潜力(Docker,free your server‘s possibility)。咱们会在后边的文章中详细介绍Docker的运行机制,今天先来解答一下最近经常在项目上遇到的关于容器化的问题。
笔者最近在帮出版行业的客户构建数字化平台,然而不幸的是,我发现这个行业完全没有被互联网大潮所裹挟,技术还处于10-20年前的技术和架构。举个例子,图书行业进销存基本上需要ERP系统的而支持,而市场上做这个细分领域的供应商要么还用的是Delphi+数据库的CS模式,要么就是在Windows机器上做的windows服务+客户端可执行文件exe的架构。当笔者在评估这些系统如何和云原生,阿里云结合在一起的时候,很多人也在问我,Windows操作系统是否可以虚拟化,或者说容器化部署?
云原生基金会CNCF是促进Kubernetes,容器化部署的社区组织,了解这个组织结构的同学应该知道张磊的大名,阿里云的张磊是唯一一位来自中国的现任TOC技术委员会委员,他是阿里巴巴负责云原生和容器化的领军人物。在加入阿里之前,张磊在微软做过多年容器化的工作,因此也可以看出微软其实一直在努力的将Docker引入Windows平台。在笔者写这些文字的时间点上,Windows容器在多个版本的Windows操作系统上已经被支持,这也是微软和社区以及Docker公司多年努力工作的成果。
Windows容器(Windows Containers)这个概念可以看成是一种特殊的用来支持容器化的Windows内核技术,我们可以用Docker来运行Windows容器,就类似于在Docker上运行Linux容器一样。Windows容器的发展终于拉齐了两大服务器端操作系统阵营在Docker平台上的界面,开发人员终于可以使用类似的工具来同时运维Linux和Windows容器。
从原理上来讲,Windows容器运行起来之后,需要和宿主机共享操作系统内核,因此容器化的Windows应用是没有办法运行在Linux操作上的,反之亦然(Linux容器无法运行在Windows宿主机上)。为了运行容器化的Windows应用程序,我们就必须准备安装了支持容器化版本操作系统的机器,但是由于虚拟化技术的飞速发展,在Windows机器上运行Linux容器实例也不是不可能。
运行在Windows操作系统上的Docker Desktop有两种模式:Windows容器和Linux容器。在特定版本下,我们可以在Windows操作系统上通过轻量级的Hyper-v虚拟机,或者Windows Subsystem for Linux(WSL)来运行Linux容器实例。特别是WSL,这是Windows上非常新的内核技术,也是微软的战略性技术选项,相比Hyper-v技术,WSL的性能和兼容性要好很多,感兴趣的读者可以关注一下。那么我们是不是就可以在生产环境中使用Windows容器呢?笔者的建议是如无必要,请勿这么干。
对于Mac用户来说,特别是在Mac操作系统上安装了Docker Desktop的用户,我们在机器上运行Linux容器本质上是安装的时候在Mac上创建了一台VM虚拟机,这让大量的Mac用户可以很容易在本地开发和测试容器化应用程序。
说到Docker和容器就不能不提Kubernetes,由于容器技术的飞速发展,以及很多企业对容器化应用PASS平台的渴求,谷歌联合一帮科技行业的小伙伴推出了Kubernetes,这个平台已经演变成企业级容器编排平台的事实标准。有一句不太技术的话来总结Kubernetes就是:Kuberntes平台是一个简单易用(相对的)的部署和管理容器化应用程序的应用程序。
最后我们通过解释什么是容器化应用收尾。容器化应用的字面意思就是运行在容器中的应用程序,在Kubernetes平台上部署应用程序,我们需要使用像Docker这样的容器化运行时来实现:拉取镜像,启动容器,停止容器等工作。由于Kubernetes社区的杰出工作,关于容器运行时这部分已经被彻底标准化了,具体的什么意思呢?Kuberntes定义了CRI(容器运行时接口),所有实现了这个接口的容器运行时都可以被Kubernetes调度。
CRI标准化可以说对Docker非常不利,因为从最新版本Kubernetes中,Docker已经不会默认的容器运行时,最新Kubernetes已经使用containerd为默认的容器运行时,笔者会在后续的文章中详细介绍containerd,读者现在可以简单的把containerd理解为负责启动和停止容器实例的组件。Kubernetes相对来说很复杂,不过K8S要解决的问题其实很简单,在容器之上来解决容器的编排,调度,运维和管理的问题。当然Kubernetes本身的复杂度已经超过了很多非科技类型企业的运维能力,因此大部分企业都如果希望落地K8S,还是需要使用阿里巴巴的EDAS+ACK的组合,特别是EDAS在K8S之上构建了一套易用的,白屏操作的管理系统,让企业落地K8S如丝般顺滑。
好了,今天这篇科普性质的文章就这么多了,下篇文章咱们来详细介绍推动容器化技术普及的技术:Docker,敬请期待!
网友评论