写点什么

避免不完全的云原生(四):技术和基础设施角度

2021 年 1 月 08 日

避免不完全的云原生(四):技术和基础设施角度

本文最初发布于 The Startup 博客,经原作者授权由 InfoQ 中文站翻译并分享。


注意:这是该系列文章的第 4 部分。你可以点击这里阅读上一部分


虽然我们在前两篇文章中讨论的人员、流程、架构和设计问题都是云原生解决方案的关键推动因素,但云原生解决方案最终要落在技术和基础设施上,这也是我们在本文中要讨论的内容。



云原生要素:技术和基础设施


云基础设施就是将底层硬件抽象出来,使解决方案能够快速地自助配置和扩展。它应该能够使用相同的操作技能管理不同的语言和产品运行时。此外,它应该促进操作自动化,并提供一个可观测性框架。让我们仔细看下,在云原生方法中使用的基础设施有什么关键特征。



云原生的技术和基础设施


弹性、不可知且安全的平台


为了实现云原生,我们必须向部署组件的平台提很多要求。平台应该提供一种通用的机制,不管我们部署什么,它都能提供帮助,让我们不用考虑非功能性问题,同样,还应该“内置”安全性。因此,我们对平台的主要要求有:


  • 弹性资源能力

  • 不可知部署和操作

  • 默认安全设置


如果开发人员要提高他们的生产力,就需要能够专注于编写创造业务价值的代码。这意味着平台应该解决负载平衡、高可用性、可伸缩性、弹性,甚至灾难恢复等问题。在部署时,我们应该能够指定高级的非功能性需求,而由平台完成剩下的工作。在这方面,我们将使用 Kubernetes 容器编排作为一个强大(实际上无处不在)的例子,但是云原生绝对不限于 Kubernetes 平台。


Kubernetes 集群可根据所部署的组件的需求,提供 CPU、内存、存储、网络等资源的自动化、弹性配置。资源池可以分布在许多物理机上,也可以分布在许多独立地区的多个可用区域上。它负责找到你所需要的资源,并将组件部署到这些资源中。你只需要指定需求——需要什么资源,它们应该或不应该扩展,以及它们应该如何扩展和升级。对于基于虚拟机的平台,我们也可以这样说,但正如我们将要看到的,容器带来了更多的东西。


假设我们遵循了上一节的架构原则,在容器中交付应用程序组件,让 Kubernetes 以标准化的方式执行部署和后续操作,而不考虑任何特定容器的内容。如果组件基本上是无状态的、可抛弃的、细粒度的、良好解耦的,那么平台就很容易以通用的方式部署、扩展、监控和升级它们,而不需要了解它们的内部结构。对于每一种软件,现在都有一种逐步抛弃专有安装和拓扑配置的趋势,像 Kubernetes 这样的标准就是其中的一部分。现在,它们都以相同的方式工作,我们可以受益于操作的一致性、学习曲线的降低以及附加功能(如监视和性能管理)更广泛的适用性。


最后,我们希望平台内置了安全,这样,我们从第一天起就可以相信它是安全的应用程序运行环境。我们不应该每次设计一个新组件时都需要重新设计安全内核;相反,我们应该能够从平台继承一个模型。在理想情况下,这应该包括身份管理、基于角色的访问管理、保护外部访问和内部通信。我们注意到,在这个例子中,Kubernetes 本身只是部分解决方案;对于一个完整的安全解决方案,还需要添加一些元素,比如用于内部通信的服务网格,以及用于入站流量的入站控制器。

轻量级运行时


要想实现操作敏捷性,就要保证组件尽可能简单和轻量级。这可以归结为三个主要特性。


  • 快速启动/关闭

  • 基于文件系统的安装和配置

  • 基于文件系统的代码部署


为了实现可用性和可伸缩性,组件必须能够快速创建和销毁。也就是说,容器内的运行时必须可以优雅地启动和关闭。它们还必须能够处理不优雅地关闭。这意味着有许多优化可能可以做:从删除依赖项,减少初始化过程中的内存占用,到在镜像构建中启用编译“左移”。至少,运行时应该能够在几秒内启动,这个期望值会不断降低(如Quarkus)。


如果采用持续集成,我们还希望构建尽可能简单、快速。大多数现代运行时已经不再需要单独安装软件,而只需将文件放到文件系统上。类似地,根据定义,不可变镜像不应该在运行时更改,它们通常从属性文件读取配置,而不是通过自定义运行时命令接收配置。


同样,实际的应用程序代码也可以放在文件系统中,而不是在运行时部署。这些特性组合在一起,使得构建能够通过简单的文件复制快速完成,非常适合容器镜像的分层文件系统。

操作自动化


如果我们能够作为发布的一部分,交付在运行时配置解决方案的整个行动方案(包括基础设施和拓扑结构的所有方面),会怎么样呢?如果我们可以将行动方案存储在代码存储库中,并可以像处理应用程序代码那样触发更新,情况会怎样?如果我们让操作人员这个角色聚焦于实现环境自治和自愈,会怎样?这些问题引出了一些关键的方法,我们应该以不同的方式处理基础设施:


  • 基础设施即代码

  • 存储库触发的操作(GitOps)

  • 站点可靠性工程


正如前面所讨论的,基于镜像的部署已经使部署的一致性提高了很多。然而,这只交付了代码及其运行时。我们还需要考虑如何部署、扩展和维护解决方案。在理想情况下,我们希望能够将所有这些都作为“代码”和组件的源代码一起提供,以确保在不同环境中构建时的一致性。


术语“基础设施即代码”最初关注的是编写底层基础设施(比如虚拟机、网络、存储等)的脚本。编写基础设施脚本并不是什么新鲜事,但有越来越多的专用工具,如 Chef、Puppet、Ansible 和 Terraform,大大推动了这方面的发展。这些工具首先假定有可用的硬件,然后在硬件上准备并配置虚拟机。有趣的是,当我们迁移到容器平台时,这个过程会有什么变化。


在理想情况下,我们的应用程序应该可以假设,已经有一个 Kubernetes 集群可用。集群本身可能是使用 Terraform 构建的,但这与我们的应用程序无关;我们只要假设集群是可用的。那么,现在我们需要提供什么样的基础设施即代码元素,来完整地描述我们的应用程序呢?可以认为,就是那些打包在 helm charts 或 Kubernetes Operator 中的各种 Kubernetes 部署定义文件以及相关的客户资源定义(CRD)文件。结果是一样的——将一组文件与我们的不可变镜像一起交付,它们完整地描述了应该如何部署、运行、扩展和维护。


因此,如果我们的基础设施现在成了代码,那么为什么不用与应用程序相同的方式构建和维护基础设施呢?每次我们提交一个基础设施的重大更改时,都可以触发一次“构建”,它会自动地部署到环境中。这种日益流行的方法被称为 GitOps。值得注意的是,这种方法特别偏爱采用“声明式”而非“命令式”方法的基础设施工具。你提供了一个描述“将来”目标状态的属性文件,然后该工具将解决如何让你达到目标状态的问题。上面提到的许多工具都可以在这种方式下工作,这是 Kubernetes 的基本操作方式。


真正的系统是复杂的、不断变化的,所以认为它们永远不会崩溃是不合理的。不管像 Kubernetes 这样的平台在自动化动态扩展和可用性方面有多好,问题还是会出现,至少最初还是需要人工干预来诊断和解决。然而,在实现了细粒度、弹性伸缩组件自动化部署的世界中,反复的人工干预将变得越来越不可能,只要可能,就要实现自动化。为了做到这一点,操作人员需要重新接受培训,成为“站点可靠性工程师”(SRE),编写代码执行必要的操作工作。事实上,一些组织已在明确地招聘,或将开发人员移到运营团队中,以确保工程文化。人们越来越多地保证解决方案是可自愈的,这意味着当系统扩展时,我们不再需要增加相应的操作人员。

可观测性和监控


随着组织向更细粒度的容器化工作负载发展,将监控作为事后加上去的东西是不可持续的。为了在云原生环境中取得成功,这又是一个我们需要“左移”的例子。解决这个问题取决于我们是否能够回答下面三个关于组件的问题:


  • 它是健康的吗?你的应用程序有可以轻松访问的状态吗?

  • 它里面发生了什么?你的应用是否有效地使用了平台无关的日志记录和跟踪?

  • 它是如何与其他组件交互的?你利用了跨组件相关性吗?


可观测性并不是一个新术语,尽管它在 IT 领域,尤其是在云原生解决方案方面得到了新的应用。它的定义来自于非常古老的控制理论。它是一种度量,是指基于从外部看到的内容,可以在多大程度上理解系统内部的状态。如果你希望响应性地控制某个东西,你就需要能够准确地观测它。


有些定义还做了区分,监控是针对已知的未知因素(如组件状态),而可观测性是针对未知的未知因素——为之前没有想过的问题寻找答案。在一个高度分布式的系统中,你两者都需要。


平台必须能够轻松、迅速地评估已部署组件的运行状况,以便快速做出生命周期决策。例如,Kubernetes 要求组件实现简单的探测,以报告容器是否已启动、是否已准备好工作以及是否运行良好。


此外,组件应该基于其活动,以标准的形式提供易于访问的日志记录和跟踪结果,用于监控和诊断。通常,在容器中,我们只简单地记录到标准输出。然后,平台可以分类整理和聚合这些日志,并提供查看和分析服务。


对于细粒度组件,涉及多个组件的交互可能会增加。为了能够理解这些交互并诊断问题,我们需要能够可视化跨组件请求。OpenTracing是一个非常适合容器世界的、越来越流行的现代化分布式跟踪框架。

回顾


下图是前面提到的让云原生采用取得成功的所有关键要素:




云原生的要素


通常,它们是相互联系,而且相互加强的。你需要全部都做吗?这样的问题表述方式可能是错误的,就好像是说上面的任何一项都是简单的二元问题,“是的,你需要”或“不,你不需要”。问题应该是你要做的多深入。无疑,你需要考虑每一个方面的现状,并评估是否需要更进一步。在下一篇文章中,我们将回到“为什么”人们被云原生所吸引,并看看这是否可以帮我们理清,我们如何、何时以及在多大程度上采纳上述要素。


查看英文原文:

The “How” of Cloud-Native: Technology and Infrastructure Perspective


延伸阅读:

避免不完全的云原生(三):架构和设计角度

避免不完全的云原生(二):人员和流程要素

避免不完全的云原生(一):云原生到底意味着什么?

避免不完全的云原生


2021 年 1 月 08 日 12:001258

评论

发布
暂无评论
发现更多内容

【有奖调研】大数据与人工智能从业者有奖需求用研

Apache Flink

大数据 flink 流计算 实时计算 大数据处理

职场“潜”规则(二)

俊毅

职场 感悟 个人提升 人才

那个业务大拿死在了这个地方

小眼睛聊技术

Java 学习 高效工作 程序员 个人成长

k8s上运行我们的springboot服务之——上传服务到docker私服

柠檬

Docker springboot

职场提问的“唐太宗”原则

大伟

系统服务构建-BFF 助力前后端分离

图南日晟

php 微服务 BFF

工厂模式——这一篇真够了

海星

Java 架构 面试 设计模式 工厂模式

你不知道的JSON.stringify(上)

前端黑板报

Java json

露营之美,在乎山水之间也

李冬梅

系统化服务构建-调用链管理

图南日晟

微服务 全链路监控 链路追踪

招联金融助力经济复苏 致力成为“智慧生活的消费金融专家”

极客编

1分钱秒杀!疫情季,如何为孩子的升学保驾护航?

极客编

DDD 实践手册(番外篇: 事件风暴-实践)

Joshua

领域驱动设计 DDD 事件风暴 事件驱动 Event Storming

北大学子手写实现《统计学习方法》书中全部算法!

GitHubDaily

人工智能 GitHub 学习 程序员

JVM源码分析之堆内存的初始化

猿灯塔

奈学教育分享:Hadoop分布式系统HDFS工作原理

奈学教育

hadoop hdfs 分布式

unittest框架

Flychen

Python 自动化测试 unittest

真香!谷歌终与美国国防部合作,签署百万美金云服务合同

神经星星

云计算 互联网巨头 互联网 谷歌Google

Neo4j执行计划

脚动两轮男之漂流小王子

游戏夜读 | 数据整理的难题?

game1night

Jenkins 插件开发之旅:两天内从 idea 到发布(上篇)

donghui

DevOps jenkins jenkins-plugin

聊一聊采访外籍人员时需要注意的几点事项

李冬梅

态度 体验 感悟

H2 的全文检索功能

Page

全文检索 lucene H2 内存数据库

k8s上运行我们的springboot服务之——k8s 1.16.0安装

柠檬

k8s

k8s上运行我们的springboot服务之——在linux安装docker并搭建docker私服

柠檬

Docker k8s

Java 简介

编号94530

Java jdk java简介 jdk8

Jenkins 插件开发之旅:两天内从 idea 到发布(下篇)

donghui

DevOps jenkins jenkins-plugin

如何参与开源项目

郭旭东

GitHub 开源

一文搞懂RSA算法

somenzz

投机者

Neco.W

投机 口罩 头盔 投机者

2020年4月云主机性能评测报告

博睿数据

云计算 百度云 ucloud 性能测试 公有云

亚马逊云科技 Webinar 电商专场

亚马逊云科技 Webinar 电商专场

避免不完全的云原生(四):技术和基础设施角度-InfoQ