云原生多云现状及挑战
根据最新的调查报告显示,超过93%的企业正同时使用多个云厂商的服务。云原生技术和云市场不断成熟,多云、多集群部署已经成为常态,未来将是编程式多云管理服务的时代。而业务部署到多云或多集群,它其实是分几个阶段的:
典型阶段1:多云多地部署,统一管理运维,减少重复劳动
第一个阶段,我们认为是多地部署统一运维管理,可以理解为是多个互操作的孤岛,互操作意味着在不同的环境,不同的云上,所用软件的技术站是一套标准化的,在进行公有云、公有云1、公有云2互相切换时,操作命令所输入的命令请求都是一样的,但其之间没有任何业务相关性或业务相关性非常弱,此时去做统一的应用交付,比如部署运维,要么手动执行重复的命令或者脚本化,或者最简单的用一套CI/CD的系统堆上去即可。因为在这个阶段大部分的业务相对来说比较固定,部署在哪个公有云、哪个数据中心,哪个机房,不需要太多的动态性和变化性。
典型阶段2:多云统一资源池,应对业务压力波动
第二个阶段为统一资源池,则会对资源池的动态性有一定的诉求。一般来说,在此处我们所认为的应用交付并不是一个简单的CI/CD,因为我们希望动态性之后,流量也能够随之迁移。在这种情况下,上面的应用交付就需要具备自动调度的能力,流量可以根据实例数的分布情况自己去获取。当然也会有其他情况,比如用一些简单的脚本化来处理你的流量,也可以认为达到了第二个阶段。当然理想的状态下,我们认为这些应该是全自动化的。
典型阶段3:多云协同,统一应用平台,业务跨云部署
第三个阶段是我们认为当前可预见到的一个多云和多集群的最终形态,也是我们所认为一个理想中的形态。其实不论用集群、Kubernetes或以前的虚拟机,从整个云计算的发展历史来看,其实一直在不断的突破边界,或者说重新去定义边界。比如最早的时候装一些新的应用、部署新的服务,需要一台物理服务器,而边界非常不灵活,当后来有了虚机、容器,颗粒度变小了,但在跨机器跨环境的访问形态下,又产生了很多新的挑战,所以Kubernetes的出现其实在产生了这么多细腻度的容器之后,重新画一个大的集群作为边界。
而多云其实是在这些不断演进的边界基础上,当在发展到一定的阶段受到数据中心或云的限制,可以用多云的技术来突破云的边界,突破集群的边界,真正的做到业务的应用可以自由的在集群、在云之间灵活的部署和迁移。
但其实在云原生话题下,多云仍然存在非常多的挑战,原因有以下几点:
- 集群繁多:繁琐重复的集群配置、云厂商的集群管理差异、碎片化的API访问入口
- 业务分散:应用在各集群的差异化配置、业务跨云访问、集群间的应用同步
- 集群的边界限制:资源调度受限于集群、应用可用性受限于集群、弹性伸缩受限于集群
- 厂商绑定:业务部署的“黏性”、缺少自动的故障迁移、缺少中立的开源多集群编排项目
华为云MCP历程
在Kubernetes里面,多集群的概念出现非常早,华为也是作为最早的发起的单位之一,2015年我们在社区提出了 Federation的概念,Federation的v1版本是在2016年启动开发,在2017年将其独立,作为Kubernetes的独立子项目来研发。2017年中, 我们启动了Federation v2的开发。商业化的话,其实华为是在2018年中启动整个商业化的大平台,并且在年底提供了商用的能力,但我们在长期服务于客户的过程中也发现一些问题,因此在2020年,我们启动了全新的引擎Karmada。
Karmada是基于 Kubernetes Federation v1 和 v2 开发,它可以跨多个 Kubernetes 集群和云运行云原生应用程序,而无需对应用程序进行更改。通过直接使用 Kubernetes 原生 API 并提供高级调度功能,Karmada 可以实现真正的开放式多云 Kubernetes。
Karmada项目
上图为我们认为应该在开源社区所要呈现的多云多集群的技术站视角,图中灰色框也是Karmada要覆盖的所有的能力范围。从数据面、存储以及运维相关的维度来看,我们向上要去解决容器网络的多云多集群,服务发现的多云多集群甚至流量治理,原数据的持久化,这些将会Karmada项目在社区里所要涵盖的范围。
在起步阶段,我们主要会关注几个方面,一是兼容K8s原生API,这个特性其实是原来Federation的v2一个稍微比较大的阻碍,因为大家都习惯去使用k8s的API而不是新的API,所以我们在做全新的Karmada项目时,直接采用原生的API来提供多集群的应用部署的能力。
在集群同步方面,我们会支持多种网络模式,包括控制面在公有云,子集群在私有云或者是反过来,甚至是边缘的场景,也都可以用Karmada这个项目去覆盖,并且我们会内置开箱即用的能力来实现最低成本的适配。
Karmada架构图
Karmada架构图上面有一个统一的控制面,我们其实有一个独立的API-server来出Kubernetes原生API也会出Karmada提供的额外策略API的能力,来做辅助的高级调度的核心功能。在集群同步方面,我们有中心式的 Controller和 Agent两种模式,分别对应于控制面和子集群在公私有云或倒置的情况。
另外一类是大边缘的场景,它在云边的网络环境下,需要管理一个边缘的集群,所以我们会结合KubeEdge在整个网络环境下的优化来提供针对边缘的集群管理能力。
Karmada项目核心价值:
K8s原生API兼容,丰富云原生生态
内嵌策略,开箱即用
丰富的多集群调度支持
集群资源空间隔离
多种模式集群同步,屏蔽地域、网络限制
多集群应用部署
1)零改造 — 使用K8s原生API部署一个多集群应用
示例策略:为所有deployment配置多AZ的HA部署方案
使用标准的K8s API定义部署应用
kubectl create -f nginx-deployment.yaml
2)Propagation Policy: 可重用的应用多集群调度策略
resourceSelector
支持关联多种资源类型
支持使用 name 或 labelSelector 进行对象筛选
placement
clusterAffinity:
定义倾向调度的目标集群
支持通过 names 或 labelselector 筛选
clusterTolerations:
类似单集群中Pod tolerations和 node taints
spreadConstraints:
定义应用分发的HA策略
支持对集群动态分组:按Region、AZ、特性label分组,实现不同层级的HA
3)Override Policy: 跨集群可重用的差异化配置策略
resourceSelector
支持使用 name 或 labelSelector 进行对象筛选
overriders
支持多种override插件类型
plainTextOverrider :基础插件,纯文本操作替换
imageOverrider:针对容器镜像的差异化配置插件
多集群服务治理
多集群服务治理要解决的问题
服务发现
DNS解析
负载均衡、熔断、故障注入,流量切分等高级流量治理
跨云的访问安全性
ServiceMesh的优势
上图是Istio ServiceMesh典型的架构图,Istio是一个完全无侵入式的,通过自动注入Certificate的方式去拦截应用发出来的流量,并通过Certificate管理应用的流量。
Istio的基本功能:
1)流量治理
通过Resilience(熔断、超时、重试、故障注入等),提高整个系统的韧性
灰度发布:方便我们去更快的部署上线新版本
负载均衡、路由匹配,基本上可以取代原来的那种微服务治理的框架
2)安全:数据加密、认证、鉴权
3)可观测:可观测性是更加方便应用运维人员去诊断系统的故障,这里的典型的三个可观测性的指标有Metrics、Traces(调用链)、Access Log(访问日志)。
多集群多云场景下,如何进行服务网格的技术选型?
接下来,将从下面这三个维度来进行技术细节的详细说明:
1)扁平网络 vs 非扁平网络
2)单服务网格 vs 多服务网格
3)单控制面 vs 多控制面
1)多集群服务网格-扁平网络
优势:
东西向服务访问延迟低
缺点:
组网复杂性
安全性:所有的工作负载在同一网络中.
Scalability: pod、service IP地址不冲突
2)多集群服务网格-非扁平网络
优势:
网络隔离,安全性相对更高
组网简单
Scalability: pod/service网络地址可以重叠
缺点:
跨集群服务访问需要通过东西向网关
Gateway工作依赖TLS Auto Passthrough
3)非扁平网络-单控制面
- 单个控制面(可以部署在用户集群或者完全托管)
- 服务发现
- 配置发现
- Split Horizon EDS
- 东西向网关
4)非扁平网络-多控制面
- 控制面部署在每个集群
- 服务发现
- 配置发现
- Sidecar连接本集群内的Istio控制面,与单控制面相比,有更好的性能和可用性
5)非扁平网络-东西向网关
网关地址获取
Split horizon EDS:
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: cross-network-gateway
namespace: istio-system
spec:
selector:
istio: eastwestgateway
servers:
- hosts:
- '*.local'
port:
name: tls
number: 15443
protocol: TLS
tls:
mode: AUTO_PASSTHROUGH
Network filter: "envoy.filters.network.sni_cluster"