云原生架构: 服务网格、混沌工程、用户态网络

Go语言精选

共 5620字,需浏览 12分钟

 ·

2020-08-30 23:57

一、云原生是什么

随着云原生的火爆发展,主流的云厂商陆续加入社区运作,CNCF官方在2018年重新定义什么是云原生。
来自官方的新定义

云原生技术有利于在公有云、私有云和混合云等新型动态环境中,构建可弹性扩展的应用运行环境。

这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。 

结合可靠的自动化手段,工程师能够轻松地对系统作出频繁和可预测的重大变更。

本文将介绍云原生服务化新架构,组合利用几个云原生社区的明星项目实践,助力于服务端生产力解放、提高服务端新一代基础架构认知水平。
  • 服务网格( Service mesh ):处理服务间通信的基础设施层,负责实现请求的可靠传递,通常为轻量级网络代理,与应用部署在一起,但是对应用透明。
  • 混沌工程( Chaos Mesh ):运作在容器内对生产中的软件进行故障注入,模拟各种故障情况可视化识别项目缺陷
  • 容器网络( Container Network ): 容器间通信的基础设施层,负责网络路由、网络策略、负载均衡等

将依次讲述微服务架构的迭代与Envoy数据面板丰富的功能、利用混沌工程故障注入加强健壮性、基于eBPF+XDP实现用户态容器网络用于网络加速。

二、服务网格

微服务的架构迭代

许多企业正在将其应用程序演变为微服务体系结构。在这种模式下,应用程序由通过API进行通信的细粒度服务组成。
微服务有望实现更快的开发、创新、可扩展,更好的基础架构优化以及开发人员愉悦的开发过程。
这就是这种体系结构得到这么多关注的原因。但这并不意味着实施微服务策略很容易, 如果您正处于此过程的中则知道它是很复杂的。

随着技术的发展,一些面向微服务架构的开发框架出现了:Spring Cloud、Dubbo、go-micro、php-hyperf 等。
这些框架实现了分布式系统通信需要的各种通用语义功能:负载均衡、服务发现、断路器等,因此一定程度上屏蔽了这些通信细节,使得开发人员使用较少的框架代码就能开发出健壮的分布式系统。
问题是:
  • 不同语言间的存在巨大差异
  • 不同的语言社区的微服务实现各不相同
这导致难以实现多种语言相互协作的微服务架构,加上各式各样的rpc框架、服务发现、监控实现这让跨语言的微服务架构寸步难行。
Service Mesh的新一代服务架构

Istio是一个提供服务网格的开源项目。它得到了Google,IBM,Red Hat,Lyft,Cisco,  Amazon、阿里等公司的支持,并被多家大型互联网公司用于生产。Istio使用Sidecar注入Envoy容器的方式,两个容器共享网络等资源,通过iptables实现流量劫持,达到控制该容器的所有流量。

ServiceMesh具有如下优点

  • 屏蔽分布式系统通信的复杂性(负载均衡、服务发现、认证授权、监控追踪、流量控制等等),服务只用关注业务逻辑

  • 真正的与语言无关,服务可以用任何语言编写,只需和Service Mesh通信即可

  • 对应用透明,Service Mesh组件可以单独升级

Service Mesh面临的挑战

  • Service Mesh组件以代理模式计算并转发请求,一定程度上会降低通信系统性能,并增加系统资源开销

  • ServiceMesh组件接管了网络流量,因此服务的整体稳定性依赖于Service Mesh

下文我们将讲述利用现代内核新技术eBPF+XDP加速Service Mesh 数据代理面板。

Envoy:数据代理面板

Envoy是专为大型现代SOA(面向服务架构)架构设计的L7代理和通信总线。该项目源于以下理念:

网络对应用程序来说应该是透明的。当网络和应用程序出现问题时,应该很容易确定问题的根源。

两大优点
  • envoy 可以与任何应用程序语言配合使用,面向服务架构使用多个应用程序框架和语言的趋势越来越普遍。
  • envoy 可以透明地在整个基础架构上快速部署和升级。

高级负载均衡算法

  • Weight Round robin:每个健康的上游主机按循环顺序选择, 如果将权重分配给本地的端点,则使用加权round robin调度
  • Weighted least request:使用O(1) 算法选择两个随机健康主机,并选择主动请求较少的主机
  • Google Maglev Hasing:与环形散列算法相比,Maglev 具有快得多的查表编译时间以及主机选择时间
  • Random:  选择一个随机的健康主机。如果没有配置健康检查策略,则随机负载均衡器通常比 round robin 更好

基于终端的服务发现

终端发现服务(EDS)在 Envoy 中用来获取集群成员,集群成员在 Envoy 的术语中被称为“终端”,对于每个集群Envoy 都会通过发现服务来获取成员的终端。
由于以下几个原因,EDS是首选的服务发现机制:
  • Envoy 对每个上游主机都有明确的了解(与通过 DNS 解析的负载均衡进行路由相比而言),并可以做出更智能的负载均衡决策。
  • 在每个主机的发现 API 响应中携带的额外属性通知 Envoy 负载均衡权重、金丝雀状态、区域等。这些附加属性在负载均衡、统计信息收集等过程中会被 Envoy 网格全局使用。
许多现有的 RPC 系统将服务发现视为完全一致的过程。使用完全一致的领导选举算法,如 Zookeeper、etcd (raft)、Consul  (raft+gossip)等,其实大规模使用这些是很痛苦的。Envoy从一开始就设计服务发现不需要完全一致性。相反的Envoy假定主机以最终一致的方式来回穿过网格。

断路器

Envoy网格的主要优点之一就是在网络级别强制实现断路,而不必为每个应用程序单独配置或编程。
Envoy支持各种类型的完全分布式(非协调的)断路:
  • 集群最大连接数:Envoy将为上游集群中的所有主机建立的最大连接数。
  • 集群最大挂起请求数:在等待就绪连接池连接时将排队的最大请求数。
  • 集群最大请求数:在任何给定时间内,集群中所有主机可以处理的最大请求数。
  • 集群最大活动重试次数:在任何给定时间内,集群中所有主机可以执行的最大重试次数。

断路可以根据每个上游集群和优先级进行配置和跟踪。这使得分布式系统的不同组件可以独立调整并具有不同的限制。

三、混沌工程

为什么需要Chaos Mesh

Netflix 创建并开源了 Chaos 的混沌工程项目,起初将它部署到了 AWS 云上,目的是向基础设施以及业务系统中注入各类故障类型。
Chaos Mesh 诞生于 PingCAP ,在PingCAP早期的时候就开始探索混沌工程。结合k8s与chaos 实现容器的各种故障注入,并逐渐在其公司内部实践落地,为其公司核心产品tidb在容器上运行提供很好的稳定性保障。

Chaos Mesh能做些什么?

Chaos Mesh故障注入能力
  • pod-kill:模拟 Kubernetes Pod 被 kill。
  • pod-failure:模拟 Kubernetes Pod 持续不可用,可以用来模拟节点宕机不可用场景。
  • network-delay:模拟网络延迟。
  • network-loss:模拟网络丢包。
  • network-duplication: 模拟网络包重复。
  • network-corrupt: 模拟网络包损坏。
  • network-partition:模拟网络分区。
  • I/O delay : 模拟文件系统 I/O 延迟。
  • I/O errno:模拟文件系统 I/O 错误 。

Chaos Mesh如何实现的


组件工作流原理
  • Controller-manager:目前 controller-manager 可以分为两部分,一部分 controllers 用于调度和管理 CRD 对象实例,另一部分为 admission-webhooks 动态的给 Pod 注入 sidecar 容器。
  • Chaos-daemon:Chaos-daemon 以 daemonset 的方式运行,并具有 Privileged 权限,Chaos-daemon 可以操作具体 Node 节点上网络设备以及 Cgroup 等。
  • Sidecar contianer:是一类特殊的容器,由 admission-webhooks 动态的注入到目标 Pod 中,目前在 Chaos Mesh 中实现了 chaosfs sidecar 容器,chaosfs 容器内会运行 fuse-daemon,用来劫持应用容器的 I/O 操作。
整体工作流如下:
  1. 用户通过 YAML 文件或是 Kubernetes 客户端往 Kubernetes API Server 创建或更新 Chaos 对象。
  2. Chaos-mesh 通过 watch API Server 中的 Chaos 对象创建更新或删除事件,维护具体 Chaos 实验的运行以及生命周期,在这个过程中 controller-manager、chaos-daemon 以及 sidecar 容器协同工作,共同提供错误注入的能力。
  3. Admission-webhooks 是用来接收准入请求的 HTTP 回调服务,当收到 Pod 创建请求,会动态修改待创建的 Pod 对象,例如注入 sidecar 容器到 Pod 中。第3步也可以发生在第2 步之前,在应用创建的时候运行。

四、用户态容器网络

什么是 CNI?

  • Container Network Interface,容器网络的 API 接口
  • Kubelet 通过这个标准的 API 调用不同的网络插件配实现置网络
  • CNI 插件:一系列实现了 CNI API 接口的网络插件
用户态网络的几种方案
  • OVS CNI:基于Open vSwitch
  • SR-IOV CNI +DPDK: SR-IOV技术是一种基于硬件的虚拟化解决方案, 允许在虚拟机之间高效共享PCIe设备,可以获得能够与本机性能媲美的 I/O性能。
  • Cilium CNI:  使用最新Linux内核技术创新,基于eBPF+XDP的新技术

Cilium基于eBPF实现

Cilium 是一个用于容器网络领域的开源项目,主要是面向容器而使用,用于提供并透明地保护应用程序工作负载之间的网络连接和负载均衡。
Cilium的基础是一项称为eBPF的新Linux内核技术,它支持在网络IO,应用程序套接字和跟踪点等各种集成点将eBPF字节码动态插入Linux内核,以实现安全性,网络和可见性逻辑,高效且灵活。

什么是eBPF和XDP?

eBPF

BPF(Berkeley Packet Filter)是一种Linux内核字节码解释器,用于过滤网络数据包,例如用于tcpdump和socket过滤器。
BPF程序可以在内核中的各个Hook点运行,例如传入数据包、传出数据包、系统调用、kprobes、uprobes、tracepoint等
BPF 的两大核心功能:
  • 过滤(Filter): 根据外界输入的规则过滤报文;
  • 复制(Copy):将符合条件的报文由内核空间复制到用户空间
在3.17版本内核时全新设计了BPF,最终被命名为extended BPF(eBPF),它允许通过LLVM编译字节码而非之前的汇编。

Cilium利用eBPF来执行核心数据路径过滤、处理、监视和重定向,并且需要4.14.x 版本Linux内核(稳定的版本)

XDP

XDP(eXpress Data Path),它能够在网络包进入用户态直接对网络包进行过滤或者处理,XDP依赖eBPF技术。

XDP可以从网络驱动程序直接访问包的DMA缓冲区来运行特定风格的BPF程序。根据定义这是栈中最早的一个点,在这里附加程序以便在Linux内核网络数据路径中使用可编程的、高性能的数据包处理器。
由于eBPF的灵活性和实用性,Hook的数量正在激增。将重点放在数据路径较低端的那些位置,此处的主要区别在于eBPF在驱动程序空间中增加了一个额外的Hook。这使用户可以在数据包中添加skb(套接字缓冲区)元数据结构之前丢弃,反射或重定向数据包。这导致性能提高约4-5倍。

用户态加速Envoy Proxy

Istio的服务网格体系结构要求将参与服务网格的所有Pod的传入和传出请求的所有网络流量都重定向到Sidecar代理。
问题是:
由于必须多次遍历整个TCP/IP堆栈,因此当使用基于iptables来实现重定向时,这种重定向的成本可能很高。

利用BPF在sidecar代理和Istio控制平面之间提供高效的数据路径,通过使用socket感知BPF程序在Linux socket级别执行流量重定向,Cilium可以加速流量重定向到sidecar代理。这允许绕过很费事的TCP/IP堆栈遍历而且对应用程序或sidecar代码没有侵入性。

Envoy性能大幅度提升

至此解决了Serive Mesh数据代理过程带来的通信性能问题。

附录:

【1】 Service Mesh 模式起源:https://zhuanlan.zhihu.com/p/40951244
【2】envoy中文文档:https://www.servicemesher.com/envoy/about_docs.html
【3】 eBPF简史: https://www.ibm.com/developerworks/cn/linux/l-lo-eBPF-history/index.html



推荐阅读



学习交流 Go 语言,扫码回复「进群」即可


站长 polarisxu

自己的原创文章

不限于 Go 技术

职场和创业经验


Go语言中文网

每天为你

分享 Go 知识

Go爱好者值得关注


浏览 144
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报