云原生在当下技术环境中越来越流行。关于云原生的概念,CNCF 给予了它如下定义:
- 构筑在现代化的动态环境之上,也就是云上环境;
- 基础技术为容器化技术,包含像服务网格、不可变基础设施以及声明式 API 等;
- 主要特性包括弹性伸缩、可管理、可观测、自动化以及频繁变更等;
回归到企业角度,在企业的发展过程中,为什么都在拥抱云原生,云原生对企业而言究竟有什么意义呢?
从技术角度来看,云原生技术成为了一个技术趋势。截止到目前,无论是 K8s、容器化或者是云原生,这些技术的热度都在持续增加。根据 CNCF 2021 年的调查报告显示,Kubernetes 社区中有 62000 多名贡献者,贡献者数量非常庞大。当下的技术趋势下,越来越多的国内外公司都开始将更多的成本投入到云原生当中,提早加入赛道进行积极部署。
从企业角度来看,云原生为企业带来了更多价值。云原生技术是以 Kubernetes 为基石,将 K8s 提供的一些特性进行了全方位呈现。比如通过容器化方式部署,提供了更为简单的弹性伸缩和故障自愈能力。方便按照业务需求在不同负载状态下进行弹性扩缩容,从而节约成本,将每台机器的性能发挥到最大化。
此外在云原生环境中,通过统一的声明式进行基础设施配置时,更方便实现多平台的无缝迁移,尤其是迁移到通过 Kubernetes 一致性认证的平台当中。由于目前的云原生技术大都是一些开源项目,因此也大大避免了项目被厂商锁定的问题。
云原生带来的技术优势
云原生之所以开始流行,在技术层面必然有其优势。目前的云原生技术主要有两个方面,一个是以 Docker 为首的容器化技术,另外一个是以 Kubernetes 为首的容器编排技术。
Docker 为技术世界引入了容器镜像,使容器镜像成为了一个标准化的交付单元。实际上,在 Docker 之前,容器化技术就已经存在,过早的技术我们不提,聊一个比较近的,比如 2008 年的 LXC(Linux Containers)。相比 Docker,LXC 之所以没有流行起来就是因为 Docker 提供了容器镜像,可以更加的进行标准化和迁移。并同时打造了 DockerHub 的公共服务,成为目前全球规模最大的容器镜像仓库。此外,通过容器化技术还可以实现一定程度的资源隔离。不仅实现 CPU、内存等资源隔离,也可以进行网络堆栈的隔离,从而更方便地在同一台机器上部署应用程序的多个副本。
Kubernetes 实际上也是因为 Docker 容器化技术火热之后才逐步流行起来的。
以 Kubernetes 为首的容器编排技术,主要提供了几个重要的能力。比如故障自愈、资源调度和服务编排。Kubernetes 内置了基于 DNS 的服务发现机制,得益于它的调度架构,可以非常方便地进行扩展,实现服务编排。
目前越来越多的公司都在积极拥抱 Kubernetes,并将自己的应用转变为使用 Kubernetes 的方式部署。而作为云原生技术的基石,我们现在所聊的云原生技术,实际上都是以 Kubernetes 为大前提进行的。
容器化优势
- 标准化交付
容器镜像目前已经成为了一个标准化的交付单元。使用容器化技术,用户可以不再需要去交付源代码或者二进制,而是直接通过一个容器镜像的方式完成交付。依靠容器镜像的打包机制,可以在任意一个容器运行时当中,使用相同的镜像去启动一个服务,并产生相同的行为。
- 可移植与轻量级,节约成本
容器化技术通过使用 Linux 内核所提供的能力,可达到一定的隔离性,进而在迁移时更加方便。同时容器化技术是直接运行应用程序,与虚拟化技术相比,在技术实现上更加轻量,无需虚拟机中的 OS,
所有的应用程序都可以共享内核。这样不仅可以节约成本,而且随着应用规模的增大,节约的成本也越多。
- 方便资源管理
在启动容器时,可以去为容器服务设置可以使用的 CPU、内存或者磁盘 IO 等属性。这样通过容器的方式去启动应用实例时,可以更好地进行规划与部署资源。
容器编排优势
- 简化工作流程
在 Kubernetes 中,应用程序的部署相对 Docker 部署方式更容易进行管理。因为 Kubernetes 当中采用了声明式配置方式,比如用户在一个配置文件中,只要去声明这个应用程序它要使用的容器镜像是什么,以及暴露出来的服务端口是哪些就可以了,不需要额外管理这部分内容。只需根据声明式配置来完成相应操作,进而大大简化了工作流程。
- 提升效率,节约成本
此外 Kubernetes 的一个优势功能就是故障转移。当 Kubernetes 中的一个 node 节点挂掉后,Kubernetes 会将这些应用程序自动调度到其他正常的节点上并正常运行起来。 整个恢复过程并不需要人为干预及操作,所以在操作层面不仅提升了运维效率,还节约了时间成本。
通过 Docker 和 Kubernetes 的崛起,你会发现,他们的出现给应用交付带来了巨大的革新与机遇。容器镜像作为标准的交付单元,缩短了交付流程,使其更容易与 CI/CD 系统集成。
考虑到应用交付变得更快,那应用架构又是如何跟进云原生趋势的呢?
应用架构的演进
应用架构演进的起点,依旧是从单体架构说起。单体架构下所有的应用程序都耦合在一起,随着应用规模和需求的增加,单体架构不再满足团队协作开发的需求,便开始逐步引入分布式架构。
在分布式架构中,最流行的就是微服务架构。微服务架构可以将服务拆分为多个模块,模块之间彼此进行通信、完成服务注册发现,实现限流和熔断等通用能力。
此外在微服务架构中,还包含了多种模式。比如每服务数据库模式,它代表着每一个微服务都有一个各自的数据库,这种模式可以避免数据库层面对应用程序造成影响,但可能会引入更多的数据库实例。
还有一种就是 API Gateway 模式。通过一个网关,接收集群或整个微服务架构的入口流量,通过 API 来完成流量分发。这也是目前使用较多的一个模式,像 Spring Cloud Gateway 或 Apache APISIX 这些网关产品都可以应用其中。
而目前流行的架构已经不再是这种微服务架构了,开始逐步向云原生架构进行扩展。那在云原生下的微服务架构,是否可以简单地将原有的微服务构建成容器镜像,直接迁移到 Kubernetes 当中呢?
理论上看起来可以,但在实际操作过程中会有一些挑战。因为在云原生的微服务架构中,这些组件不仅仅需要简单地通过容器方式运行,实际上还包括了服务的注册发现,以及服务配置等其他环节。
同时在迁移的过程中,还会涉及到业务层面的改造与适配,就需要将认证、授权等通用逻辑和可观测性相关能力(日志、监控等)全部迁移到 K8s 中。所以从原先的物理机环境部署迁移至 K8s 平台当中时,情况会比实际复杂的多。
在这种情况下,我们可以通过 Sidecar 模型来完成一个抽象,将上述场景简单化处理。
通常情况下,Sidecar 模型以 Sidecar Proxy 的形式出现。通过将一些通用能力(如认证、授权和安全等)下沉到 Sidecar 中,进而从下图左侧演变为右侧模式。从图中可以看到,这种模式的调整,将原先需要维护多个组件,变成了只需要去维护两个东西(应用程序 +Sidecar)。同时在 Sidecar 模型自身中,包含一些通用组件,所以也不需要业务方自己去维护,因此可以很方便地解决微服务通信之间的问题。
为了避免每个微服务引入一个 Sidecar 时,出现单独配置的复杂场面和重复造轮子的情况,就可以通过引入控制面或者通过控制面注入的方式执行,这逐步形成了现在的服务网格(Service Mesh)。
服务网格通常情况下需要两个组件,即控制面 + 数据面。控制面完成配置的下发和相关逻辑的执行,比如当前最为流行的 Istio;在数据上,你可以选择类似 Apache APISIX 这种 API 网关进行流量的转发与服务通信。得益于 APISIX 的高性能和可扩展,还可以进行一些定制化需求和自定义逻辑。如下展示了以 Istio+APISIX 的服务网格方案架构。
这套方案的优势在于,当你想从原有的微服务架构迁移到云原生架构时,直接使用服务网格方案,可以避免业务侧的大规模变更。
云原生带来的技术挑战
前文提到了目前云原生趋势下,一些技术层面的优势。但万物都有两面性,带来新鲜元素和机遇的同时,也会因为某些技术的加入带来一些挑战。
容器化与 K8s 引入的问题
在文章开头部分,我们提到了容器化技术采用共享内核的方式,共享内核带来轻量级的同时,也造成了隔离性上的不足。如果某一个容器,发生了容器逃逸,就可能出现主机被攻击的情况。因此为了应对这些安全挑战,也应运而生了安全容器等技术。
此外容器镜像虽然提供了一个标准化的交付方式,但同样容器镜像也容易成为被攻击的类型,比如供应链攻击。
同样在引入 K8s 后,也相应带来了组件安全方面的挑战。组件的增多导致了攻击面也增多,同时还额外带来了底层组件和依赖层面相关漏洞等。而在基础架构层面,从传统物理机或虚拟机迁移到 K8s 当中,会涉及到基础设施的改造成本以及更多的人力成本,去执行集群的数据备份、周期性升级以及证书续期等相关问题。
同时在 Kubernetes 架构中,apiserver 作为整个集群的核心组件,需要处理来自内外部的所有流量。因此为了规避边界安全问题,如何保护 apiserver 也成为一个关键问题。比如我们可以使用 Apache APISIX 将其保护起来。
安全层面
使用新技术后,更需要在安全层面进行加倍关注:
- **在网络安全层面,**可以利用 Network Policy 这种方式进行流量的精细化控制。或者使用像 mTLS 这种方式进行连接加密,形成零信任网络。
- **在数据安全层面,**K8s 中提供了** **secret 资源进行机密数据的处理,但实际上它并不安全。因为 secret 资源当中的内容实际上只是进行了 Base64 编码,即你可以通过 Base64 解码去获取其中的具体内容,尤其是将这些内容放到 etcd 中后,如果你有 etcd 的访问权限也是可以直接读取的。
- **在权限安全层面,**还会涉及类似 RBAC 设置不合理的情况,进而导致攻击者可以利用相关 Token 去与 apiserver 进行通信,实现攻击目的。这种权限设置不合理的场景多见于 controller 和 operator。
可观测性相关
云原生场景下,大多会涉及一些可观测性相关的操作,比如日志、监控等。
在 K8s 中如果想要进行多样式的日志收集,就需要通过聚合的方式,在每一个 K8s 的 node 节点上直接进行采集。如果通过这种方式采集日志,就需要将应用程序全都输出到标准输出或者标准错误当中。
但如果业务不进行相关改造,仍然选择将应用日志都写入到容器内的某一个文件中,那就意味着每一个实例当中都需要有一个 Sidecar 进行日志的采集,在部署架构时就会变得异常复杂。
回到架构治理层面,在云原生环境下面,监控方案的选择也带来了一些挑战。因为方案选型一旦出现问题,那后续的使用成本是非常高的,一旦方向走错,带来的损失也是巨大的。
同时在监控层面下,还会涉及一些容量问题。虽然在 K8s 当中部署应用程序时,可以简单通过配置它的限流限速等去限制该应用程序能够使用的资源细节。但是在 K8s 环境中,还是会比较容易出现资源超卖、过度占用资源的情况,以及因为这些情况产生的内存溢出等状况。
此外,K8s 集群中还会存在另外一种情况,当整个集群或者 node 的资源不够了,它就会产生资源驱逐,将已经运行在某一个节点上的资源驱逐到其他节点上。假如说某个集群的资源比较紧张,一旦出现某个节点风暴,就会容易导致整个集群的业务全部挂掉。
应用变革及多集群模式
在应用架构变革层面,最核心的问题是服务发现。
K8s 当中默认提供基于 DNS 的服务发现机制,但如果业务组成中包含云上业务和存量业务共存的状况,采用 DNS 服务发现机制进行处理时,就会比较复杂。
同时企业选择云原生技术后,随着业务规模的扩大,就会逐渐去考虑多节点的处理方向,这时就会涉及到多集群问题。
比如我们想通过多集群去给客户提供一个更高可用性的模式,这个时候就会涉及到服务在多集群之间的编排、多集群负载分配和同步配置,以及集群在多云及混合云场景下,如何处理和部署策略等问题。这些都是会面临的一些挑战。
APISIX 如何赋能数字化转型
Apache APISIX 是 Apache 软件基金会下的云原生 API 网关,它兼具动态、实时、高性能等特点,提供了负载均衡、动态上游、灰度发布(金丝雀发布)、服务熔断、身份认证、可观测性等丰富的流量管理功能。你可以使用 Apache APISIX 来处理传统的南北向流量,也可以处理服务间的东西向流量。
目前在 Apache APISIX 中,基于上文描述的一些架构演进和应用变革,也衍生出了基于 APISIX 的 Ingress controller 和服务网格方案,助力企业更好地进行数字化转型。
APISIX Ingress 方案
Apache APISIX Ingress Controller 是一种 Kubernetes Ingress 控制器实现,它主要用作处理 Kubernetes 南北向流量的流量网关。
APISIX Ingress Controller 架构类似 APISIX,是一种控制面和数据面分离的架构。其中,使用 APISIX 作为数据面,进行实际流量的处理。
目前 APISIX Ingress Controller 支持以下三种配置方式,同时兼容 APISIX 的所有插件,开箱即用:
- 支持 K8s 当中原生的 Ingress 资源。这种方式可以让 APISIX Ingress Controller 具有更高的适配性。目前来说,基本上是所有开源且具有影响力的 Ingress controller 产品中,APISIX Ingress Controller 是支持版本最多的一个产品。
- 支持使用自定义资源。目前 APISIX Ingress Controller 的自定义资源是根据 APISIX 语义进行设计的一套 CRD 规范。使用自定义资源可以很方便地跟 APISIX 进行集成,更加原生。
- 支持 Gateway API。作为下一代的 Ingress 标准,APISIX Ingress Controller 已开始支持 Gateway API(Beta 阶段)。随着 Gateway API 的发展,后续很有可能直接成为 K8s 的内置资源。
相比 Ingress NGINX,APISIX Ingress Controller 存在以下优势:
- 架构分离。在 APISIX Ingress 中,采用了数据面和控制面分离的架构。当流量处理压力较大、想要进行扩容时,就可以简单操作进行数据面的扩容。这样就可以让更多的数据面对外提供服务,而不需要去对控制面进行任何调整。
- 扩展能力强,支持自定义插件。
- 数据面选用 APISIX,高性能全动态功能加持。得益于 APISIX 的全动态特性,在 APISIX Ingress 的使用中也可以尽可能的保护业务流量。
目前 APISIX Ingress Controller 的使用用户网罗了国内外一些家喻户晓的企业。国内用户比如中国移动云开放平台(开放 API 和云 IDE 产品)、又拍云、地平线(车载 AI 系统)等,海外用户如欧洲的哥白尼参考系统(隶属欧盟的地球观测计划)。
APISIX Ingress Controller 目前仍在持续迭代中,后续计划去完善更多功能:
- 进行 Gateway API 的完整支持,去实现更多场景配置;
- 支持 external service 服务代理;
- 原生支持多注册中心,让 APISIX Ingress Controller 更加通用;
- 进行架构更新,打造全新架构模型 ;
- 与 Argo CD/Flux 等 GitOps 工具集成,打造丰富生态。
如果你对 APISIX Ingress 方案感兴趣,也欢迎随时关注社区动态,跟进产品的迭代与社区动向等。
APISIX 服务网格方案
目前,除了 API 网关和 Ingress 方案外,基于 APISIX 的服务网格方案也正在积极迭代中。
基于 APISIX 的服务网格方案主要包含了两个部分,即控制面和数据面。控制面选择了 Istio,因为它行业领先且社区活跃,被多个厂商所支持。数据面则选择了 APISIX 去替换掉 Envoy,让 APISIX 的高性能和扩展性发挥作用。
目前 APISIX 的服务网格网格仍在积极推进中,后续计划进行如下方向的迭代:
- 进行 eBPF 加速,提高整个效能;
- 进行插件能力集成,允许在服务网格体系中更好地使用 APISIX Ingress 能力;
- 打造无缝迁移工具,为用户的迁移过程提供更加便捷的工具,简化流程。
因此总体来看,在云原生时代下,架构和技术的演进为我们带来了机会和挑战。Apache APISIX 作为云原生网关,也一直致力于为云原生趋势进行更多的技术适配与集成。基于 APISIX 的各类解决方案,也开始帮助企业用户进行数字化转型,助力企业更平稳地过渡到云原生赛道。