作者:冬岛、贤维、幻云、微垣
在本系列第一篇 《没有银弹,只有取舍 - Serverless Kubernetes 的思考与征程(一)》 中介绍了 Kubernetes 的复杂性以及现有Serverless Kubernetes云产品的解决之道。本文将针对 Serverless Container 技术的特殊性,分享其对 Kubernetes 的架构影响,以及阿里云在Serverless Kubernetes方面架构选择。
Serverless Container缘起
在2018年,容器团队与弹性计算团队启动了Serverless Container与Kubernetes的研发,其目标是融合容器技术和云基础设施能力,最大化利用云的弹性和自动化运维能力。为此,我们为Serverless Container定义了其几个关键架构原则:
1、单一职责 Single Responsibility - 在传统的容器编排中,需要预先分配的工作节点上调度容器应用执行,一个工作节点上可以运行多个容器应用,同节点内部应用共享OS内核,存在资源和安全干扰;而在Serverless Container中,每个应用运行在独立的安全沙箱中,独享OS内核,应用之间不存在相互的资源干扰,有明确的安全作用域。单一职责使得从资源弹性供给到应用调度的全链路可以一体优化,极大优化了弹性效率。
2、不可变性 Immutability - 在Serverless Container实例在创建后,作为一个不可变的基础设施只支持部分配置变更,比如ConfigMap配置,镜像版本,资源配额等。如果变更引发应用拓扑或者资源的变化,比如一个新版本的AI应用从之前只依赖CPU到依赖GPU设备,需要重建而非原地更新。不可变性极大简化了运维复杂性。
3、位置无关 Location independency - 用户可以通过一些部署策略,比如可用区、失效域等,控制 Serverless Container 的部署位置,但是用户无法指定Serverless Container所在的具体的物理节点。Serverless Container是临时性的(ephemeral),所有持久化应用状态要保存在外部存储中(比如EBS,NAS,OSS等)或数据服务中,而不能依赖宿主机文件系统。重建Serverless Container实例不能保障IP地址不变。位置无关使得容器可以在整个弹性资源池上进行供给和动态迁移。
通过这几个基本原则,用Serverless Container和Serverless Kubernetes重新定位了云平台与开发者之间的边界,尽可能让开发者聚焦于应用,而将资源调度、基础设施运维、高可用、系统优化等复杂性交给到基础设施完成。实现将复杂留给自己,将简单留给用户的技术初心。
ECI弹性容器实例技术概览
Serverless Container 的安全沙箱技术虽然脱胎于虚拟化技术,为了提供与OS容器相近的使用体验,我们要解决几个重要的技术挑战:
1、更快的启动速度 - 将沙箱容器启动速度从VM的分钟级下降到秒级。
2、更低的性能损耗 - 减少由于引入虚拟化技术,带来的额外性能损耗,尤其是存储与网络的性能。
3、更低的资源开销 - 尽可能降由于引入沙箱技术额外增加的资源损耗,尤其是沙箱内部独占的Guest OS内核,系统管控组件等。
4、有保障的库存供给 - 与OS容器在预分配集群资源进行调度不同,所有Serverless Container依靠云基础设施保障资源的按需供给,一旦库存不足或者创建失败,将影响业务发布与扩容。
阿里云 ECI (Elastic Container Instance)是阿里云上Serverless Container的实现。每一个ECI 实例 运行在一个独立的安全沙箱之中,有清晰的安全边界,只对外暴露标准化接口。系统可以通过API实现Pod生命周期管理, Liveness/Readiness/Startup 探针,日志/监控Metrics采集。在数据面,ECI包含了两种不同的实现架构,具备不同的优势和特点,可以由控制面按需调度满足用户资源供给需求。
1、并池架构:阿里云在神龙架构上实现了ECI实例、ECS实例、裸金属实例的统一供给,这样可以充分利用阿里云整体弹性计算资源池保障弹性资源供给;并且可以利用现有ECS规格实现丰富的资源类型,比如GPU实例、AMD、倚天实例等,以及地域覆盖;同时可以利用弹性计算资源池中的碎片资源,提升整体利用率。但是并池架构也存在一些挑战,比如,对每个ECI实例都会包含完整 ECI Agent、Container Runtime等组件,会占用较多的系统资源。此外,在支持ECS与ECI混布的场景下,复用了虚拟机的存储网络编配流程,容器的启动速度和并发度受限于整体链路效率。
2、专属池架构:ECI团队基于阿里云袋鼠沙箱容器实现一个面向容器场景的技术创新架构。架构特点是将ECI Agent中的Container Runtime等部分下沉到宿主机,只保留了必要的部分在ECI沙箱内部,降低了整体资源占用。同时可以利用容器镜像的特性优化容器启动效率,此外在管控链路和资源生产上也针对容器场景进行了优化。
在Serverless Container架构中,将并池和专属池相结合的方式可以最大化,弹性资源供给的规模、效率、成本与规格丰富度。得益于阿里云在虚拟化层,操作系统层和容器层的软硬一体协同优化,其中ECI启动速度P50为5s;性能与在VM中运行的OS container基本持平,优于KataContainer等开源实现 20%。
Serverless Container的优势来源于技术取舍的结果,其特殊性也对Kubernetes架构以及用户应用产生影响,下文我们将介绍相关的改变与应对之道。
阿里云Serverless Kubernetes架构概览
在阿里云上容器服务提供了对ECI的全面支持和优化。其中 ACK (Kubernetes Service)同时支持 ECS 节点和ECI实例,在保障兼容性的同时优化运维和弹性体验;而 ASK (Serverless Kubernetes)是ACK集群的一个特殊类型,只支持Serverless Container,并默认提供了基于云服务、托管的 K8s Addons (PrivateZone based DNS,ALB based Ingress Controller等等),为客户提供更多的便捷性。ACK/ASK 支持ECI的Serverless Container的抽象架构如图:
其中重要的组成部分包括:
1、ACK Scheduler - 是ACK增强的K8s调度器实现,除了增强批量任务、GPU调度等能力之外,支持根据资源策略自动选择在ECS节点池或者ECI上进行调度和重调度。
2、Virtual Node Addon - 作为ECI与Kubernetes架构之间的适配器,实现ECI Pod的生命周期管理,以适配部分 Node 相关的实现,比如Metrics Server,Prometheus的集成。Virtual Node是集群中的一个逻辑概念而不是一个物理实体,不支持NodePort,DaemonSet等Node级别概念。
3、在应用弹性层,ACK/ASK也支持了众多的增强可以更好地帮助应用充分利用云的弹性能力,支持ECI这样的弹性新算力,比如AHPA可以根据AI算法预测弹性趋势,降低弹性的滞后性,阿里云也针对云的特性,扩展Knative/KEDA等应用弹性实现,比如更好地支持Spot类型弹性资源等,细节将在下篇中进行介绍。
4、在应用框架层,ACK/ASK团队也针对一些对弹性工作负载有更高需求的应用框架进行了优化,比如Argo Workflow,Spark等。也通过Fluid框架实现了对Serveless计算任务的弹性数据访问加速。
阿里云容器服务在兼容K8s能力的基础上,针对Serverless Container进行了全面支持与优化:
1、提供一致的使用体验:提升了对K8s兼容性,可以让现有容器应用平滑迁移到Serverless容器环境。提供了对日志、监控、告警等日常运维能力全面的支持。
2、具备完备的企业能力:让Serverless容器与经典容器架构一样,具备企业客户对可观测性、安全合规、成本治理等多方面要求。
3、最大化差异化云价值:在基础设施层、容器编排和应用框架层对Serverless Container的弹性能力进行了全面的优化。与开源K8s实现相比,在阿里云上可以得到更好的弹性体验、扩容效率与计算规模,以及更低的计算成本。
Serverless Kubernetes 中的限制与应对之道
由于Serverless Container在实现上的特殊性,对Kubernetes的架构也产生了影响。下面我们将介绍Serverless Kubernetes 的一些限制与应对之道。
不支持节点网络模型
由于Serverless Container中不再对外暴露Node的概念,Serverless K8s不再支持节点网络模型,比如NodePort类型的Service,HostPort或者HostNetwork,需要用户调整使用 Load Balancer类型服务或者 Ingress为容器应用对外提供服务。
容器安全模型的改变
经典Kubernetes和Serverless K8s在数据面安全模型有很多不同。我们可以快速对比一下二者在数据面架构的差异。
Pod实例强安全隔离
Serverless Container运行在基于MicroVM的安全沙箱之中。不同实例之间不共享操作系统内核,减小了安全攻击面。因此Serverless Container实例之间不能通过宿主机资源,比如本地文件系统和进程间通讯机制(共享内存,管道等)进行相互访问,只能通过远程文件存储和网络进行数据交换。
ECI 的资源交付单位是Pod。如果容器间需要通过本地OS进行共享文件或者进程间通讯,我们需要将其组合运行在相同ECI实例(Pod)之中。
受限的运行权限
在Serverless容器沙箱中同时运行着用户应用以及平台的系统组件。为了防止用户应用对云平台的安全攻击,Serverless Container限制了用户应用进程的运行权限。
1、不支持特权模式 (privileged mode):一些系统级应用,比如systemd,Docker In Docker,GPU监控等需要运行在特权模式应用是无法运行在ECI之中的。
2、受限的 Linux capabilities: Linux Capabilities[1] 可以精细化控制一个进程所需的权限。为了避免安全渗透,Serverless Container中的应用进程只支持受限的capabilities集合。在Docker容器的默认capabilities集合[2]之外,通过Guest OS 内核加固,ECI扩展了部分capabilities支持,比如SYS_PTRACE支持Sysdig Falco等使用ptrace的应用,NET_ADMIN支持Istio等服务网格应用。更多细节请参见配置Security Context [3]。然而由于一些Capabilities具备更大的安全攻击面风险,比如使用eBPF应用,是无法直接运行在Serverless容器之中的。
3、不支持宿主机访问:在Serverless Container中已经没有host的概念,自然用户无法访问宿主机的资源,这引入了一些限制。比如过去用户需要登录工作节点并执行 coredump 、抓包等操作来定位应用问题,但是这在Serverless Container场景下是不支持的。为此,ECI 提供了内建的 coredump [4]以及 tcpdump抓包 [5]分析工具来实现。
注:在GKE Autopilot中,虽然它依然采用了传统的Node模式,但是Node的资源归属属于云平台,对用户不可见。因此它也采用了类似的受限容器权限模型[6],来防止安全攻击和滥用。为了解决众多监控、安全、日志等软件对更高系统权限的要求,Google提供了一个 Autopilot partner workloads [7]项目,对认证过的应用镜像进行白名单处理。
容器粒度云资源授权模型
容器技术成为了用户使用云的新界面。其中一个重要原因是Kubernetes标准化了容器应用与编排,并提供了平台无关的技术抽象,可以让开发者以应用为中心的方式高效、自动化地调度应用和组装计算、网络、存储等云资源,并访问AI、大数据等云服务。这些自动化能力是通过对云资源的授权来完成的。比如 Cloud Controller Manager 在授权后,可以根据K8s应用对 Service/Ingress定义来自动化创建和管理SLB/ALB实例等等。
在ECS实例上运行的应用在访问云服务时(比如OSS,RDS等),如果把AccessKey固化在应用或配置中,会导致权限泄露信息和难以维护等问题。为此阿里云支持ECS实例RAM角色,让ECS实例扮演具有某些权限的角色,从而赋予ECS实例一定的访问权限。然后部署在ECS实例中的应用通过ECS元信息服务获取STS临时凭证来访问阿里云的云服务。这种安全模型无法满足Serverless容器场景下安全访问云资源的需求。因此,阿里云容器服务ACK联合RAM访问控制服务推出了RAM Roles for Service Accounts (RRSA)功能,可以让容器应用以K8s原生的方式使用STS临时凭证访问阿里云服务,
基于RRSA[8]功能,开发者可以为应用所使用的服务账户(Service Account)创建一个RAM角色,并对其进行授权。容器应用在运行时可以通过SA获取扮演这个RAM角色的临时凭证实现对云服务的访问,这种方案实现了应用RAM权限最小化以及Pod对云资源访问的细粒度隔离需求。
融合的容器网络与虚拟化网络安全
ECI复用了阿里云虚拟化基础设施,每个ECI实例具备独立的弹性网卡。ECI 在网络模型上保持了与ECS Worker Node的容器网络的高度兼容,支持 ECI实例与Worker Node上Pod的互联互通,支持 ECI 实例访问VPC资源,支持各种类型 K8s 服务发现与访问,比如ClusterIP,Loadbalancer, DNS,Ingress等等。
ASK/ACK on ECI 支持基于安全组的网络隔离控制[9]。也可以利用现有的VPC Flow, SLB 流量安全等云服务发现潜在的网络安全风险。
下一步ASK 和 ACK on ECI 会提供兼容Kubernetes network policy的网络安全策略管理,可以更加细粒度、一致性地管理 Pod 的网络连通性。
运行时安全与风险修复流程调整
Serverless Container的安全防护也是采用责任共担方式。用户需要对沙箱内部容器应用的内容和使用负责,而云平台会负责安全沙箱等基础设施的安全性。
与ECS不同,目前ECI实例中没有运行云安全中心的安全代理。而且由于受限的运行权限,大量的现有基于代理的安全解决方案无法运行在Serverless容器之中。既然无法利用 agent-based 的方案来保障沙箱内部应用的运行时安全,我们需要采用 agent-less的方式,实现安全事件的防护、发现与阻断能力。比如,我们可以通过ACR的镜像扫描机制,发现容器镜像中存在的安全漏洞,并通过ACK/ASK提供的安全策略在发布时进行阻断。在应用或者通过Webhook等机制,实现自动化的重构建和重发布等能力。
在Serverless Container中,安全沙箱,agent和Guest OS等基础设施的安全风险是由系统平台负责修复的。ECI的Guest OS是针对容器应用加固和优化的阿里云Linux操作系统,如果其存在安全风险且无法通过热升级无感修复。阿里云平台会基于新的Guest OS和原有的容器配置重建相关的ECI实例。
不支持DaemonSet
在经典的 Kubernetes架构中, 的工作节点中一般会运行用户的基础设施 agent (如日志、安全、监控、运维) 等。他们通常采用 DaemonSet 部署,以 Pod 为单位部署在节点中,管理整个节点上的所有容器应用。基础设施 agent 可以通过OS能力(如文件系统,进程间通讯等)和容器引擎,对相同节点中的容器应用进行监控指标、日志采集、安全防御、资产管理等操作。基础设施Pod与应用Pod生命周期解耦,可以独立更新,不对应用Pod的造成影响也不受应用Pod影响。
在弹性容器实例中,每个容器应用运行在一个独立的沙箱中。面向节点运维的基础设施agent,要针对 Serverless Container 的特殊性进行转化与改造才能继续运行。下面,我们将介绍Sidecar和Hidecar两种不同的架构模式。
Sidecar Pattern
Sidecar 是在Kubernetes应用中广泛使用的架构模式,我们可以在每个容器应用的旁边部署一个伴生容器,来解决不同应用的共性问题 (Cross-cutting concern)。比如,Istio服务网格通过Sidecar实现应用网络流量拦截与转发,监控代理通过Sidecar实现对业务应用的数据采集等等。
我们可以将过去部署在每个节点上的基础设施agent Pod,部署到每个应用Pod内部,以Sidecar容器方式运行。从过去一对多的管理模式,变成一对一的管理模式。这种架构方式如下图所示:
基于这个架构模式,用户可以根据自己的业务需求,改造自己的基础设施agent来满足在Serverless Container中运行的需求。然而,这个模式也有一定的架构挑战。
1、Sidecar 容器与应用容器一样只支持受限运行权限。如果基础设施类agent需要更高权限,无法直接运行在Serverless容器之中。
2、Sidecar 容器会增加沙箱资源占用。与过去节点级别agent与应用一对多的部署模型不同,Sidecar与业务应用是一对一的关系。每个应用Pod都要部署一个独立的Sidecar,这将大大增加整体资源开销。为了解决这个挑战,我们需要尽可能降低Sidecar的资源占用。比如对于监控agent,我们可以将其拆解成两部分,运行在容器沙箱内部的agent仅保留必要的数据采集探针,而将数据分析、处理交由一个外部的共享服务来进行实现。
3、基础设施Sidecar与业务应用生命周期耦合。Sidecar容器只支持受限更新(比如变更镜像),对其他情况需要重新创建Pod,这可能对业务应用执行产生一定的干扰。此外,通常而言基础设施Sidecar要早于业务应用启动,晚于业务应用停止。但是目前Kubernetes中Sidecar容器与业务应用的启停顺序还未有标准化的定义,在时序上存在一定的不确定性。
4、一个应用的多个副本可能混合部署在基于ECS的Worker Node或者ECI实例之中。开发者需要对以DaemonSet和Sidecar部署的基础设施agent进行统一管理。为了解决这个挑战,我们计划通过OpenKruise的SidecarSet来对DaemonSet进行扩展和增强,简化基础设施agent的部署和运维体验。
Hidecar Pattern
在阿里云ECI和AWS Fargate中,对高权限容器的支持是通过Hidecar来实现的。Hidecar是一种隐式的Sidecar,运行在Serverless Container实例之中。它由云平台提供,对用户不可见,可以具备更高的运行权限。在ECI之中,比如日志采集、GPU监控等基础设施能力是作为hidecar实现的。
以日志采集场景为例,在经典的K8s架构中,Logtail agent通过一个DaemonSet部署到每个Work Node上。Logtail通过特权权限访问宿主机的 /run/containerd/containerd.sock 文件来与Containerd通信,来获得节点上 Pod 中容器应用的stdout/stderr以及日志文件。在ECI中,Logtail agent作为一个hidecar部署,通过底层容器运行时和文件系统采集应用相关日志数据。
Hidecar pattern 解决了Sidecar方式不支持特权容器的问题,阿里云也为ECI客户提供了基于云产品丰富的、开放的可观测性能力,比如支持Prometheus,Metrics API,Kafka日志投递等等。但是Hidecar实现只能通过云平台提供,不支持用户扩展。此外,Hidecar 虽然对用户不可见,但是其相关资源消耗会计入整体沙箱的资源用量。ECI 会预留 256M 内存用于Guest OS和Hidecar进程运行。用户对但是Hidecar消耗资源不可控,比如当用户应用日志量较大时,由于logtail hidecar受限于资源分配,就有可能出现日志上传的堆积。
对整体架构可伸缩性的挑战
容器应用通常被应用于微服务架构和大数据、AI等计算任务。他们和传统的应用相比,其生命周期更短,数量更多。根据Sysdig 《2023云原生安全与使用情况调查报告》,近 90% 的容器应用的生命周期 < 1天,其中 72% 的容器生命周期小于5分钟。Serverless 容器将对整体的架构带来众多的可伸缩性挑战。
对云基础设施管控的scalability挑战
Serverless容器应用与传统虚拟机应用相比,生命周期小1~2个数量级。ECI目前每天有数百万的容器实例被创建和释放,而且随着AI、大数据等数据任务类应用的拓展,整体数量在持续快速增长中。Serverless Container 应用对底层基础设施管控链路带来的压力是远超于虚拟机。这里面需要在基础设施层和Kubernetes层相结合来解决。
在基础设施层,一方面需要计算、存储、网络等云资源提升管控容量,一方面要针对不同容器应的特殊性优化底层资源生产供给。比如针对计算任务优化的ECI Job优化型实例[10],它不需要独立的ENI,可以通过阿里云网络Mesh(ANSM)技术大大提升网络建联效率,从而实现更好的可伸缩性和更优的弹性。
在Kubernetes层,ASK/ACK针对ECI架构的特殊性进行了改造和优化。首先要避免通过 ECI OpenAPI 进行频繁的数据交换,降低对ECI管控链路的压力。比如,在Serverless Kubernetes中,对Pod的健康检查,Exec,日志,监控等场景,通过 ECI 沙箱中的 agent 与 API Server 之间的直接通信旁路了ECI管控,可以有效提升整体架构的可伸缩性。此外在API Server中对ECI容器创建、删除等场景做了更细粒度的限流、降级机制实现,避免突发流量引发雪崩。未来也会增加优先级队列等方式,在底层资源发生流控的同时,优先保障高优先级任务的处理。
对 Kubernetes 控制面 scalability 的挑战
在经典的Kubernetes架构中,容器应用运行在工作节点上,Kubelet/Kube-Proxy/CSI/CNI等节点级别组件与API Server通过List-Watch机制进行状态同步,从而实现节点上所有Pod的生命周期管理,配置变更,网络服务发现,存储卷挂载等。Serverless Container作为一个自包含实体,在运行时要通过K8s的List-Watch机制来侦听应用依赖资源的变化,比如ConfigMap配置,应用Service的端点变化等等。在传统VM架构中,VM上K8s组件与API Server通信复杂度为O(N),其中N是VM实例的数量。如果使用Serverless Container,复杂度将会提升到O(N * K),K为一个节点上容器数量。
对于Serverless Container 的实现,我们可以由不同的架构选择:
1、一个是one pod per node 架构。AWS EKS on Fargate只是将部分节点级别组件运行在沙箱内部,不修改K8s整体架构。这种方式对K8s架构侵入性较小,但会引入较大的伸缩性问题。比如目前AWS EKS只支持单集群 1000 Fargate实例。
2、另一种则是针对 nodeless 的特殊性,对 K8s 控制面和 Serverless Container 进行整体架构优化,提升可伸缩性。目前,ACK/ASK选择了这个路径,目前可以支持单集群2万ECI实例。
下面是一些通用的优化策略
利用不可变性(Immutability)最小化对 API Server 访问
不可变性是Serverless Container的重要特征,根据Pod的模版定义,etc-agent就可以判断是否需要在运行时访问API Server获取资源变更。比如,Pod的Volume定义在运行时不会改变,ECI agent自然不需要调用API Server对此类资源进行watch。对于ConfigMap和Secrets,如果Pod没有对其进行引用,或者声明了其是 Immutable [11]类型,在ECI运行时也无需对此类资源进行watch。这样大大减少了ECI agent对API Server 访问请求。
降低单个Serverless Container 对 API Server 资源消耗
在开源K8s API Server中,为了优化Kubelet的watch访问,使用NodeName构建Cache索引。ACK中针对Serverless Container Watch访问的特殊性,支持Pod Name作为cache index,当某个Pod资源发生变化时,只通知对应ECI实例进行处理,大大降低了API Server资源用量。
此外,与经典K8s节点Kubelet/Kube-Proxy利用多个独立进程访问K8s API不同,ECI agent通过TCP连接合并降低了 50% 以上的连接数。
Worker Node与Serverless Container 混合调度挑战
越来越多的ACK用户在使用ECS 作为Worker Nodes的同时,也在在弹性、计算类任务等场景应用 ECI。客户可以自由组合不同类型的弹性计算资源满足业务对资源确定性、成本等多方面需求。比如在ACK集群中,客户可以用包年包月的ECS节点池承载常态业务流量,用按量付费ECS节点池承载大促等可预期的业务波动,利用虚拟节点/ECI支持突发的业务流量。
ACK针对K8s调度器进行了扩展,支持客户自定义资源策略 ResourcePolicy [12]在不同类型的资源类型间实现优先级调度。比如为了优化弹性成本,可以指定当应用扩容时优先在ECS的空闲资源上调度应用,如果容量不足再调度到ECI之上;同时在应用缩容时优先删除ECI上的Pod,再删除ECS节点上的Pod。ResourcePolicy为用户在云上不同弹性资源供给之间提供了一致、透明的调度策略,也可以帮助客户将适合的业务逐渐切换到Serverless Container之上。
目前尚不支持资源超售
在Kubernetes架构中,开发者可以通过定义Pod资源(CPU,Memory等)的requests和limits控制应用调度与资源使用。Kubernetes会根据资源 requests 值调度Pod,容器运行时会根据limits值使用cgroup限制容器最大资源用量。比如当容器进程内存消耗超过limits时,会被杀死。当容器进程CPU消耗超过limits时会被限流。Kubernetes中Pod具备不同QoS类型。Kubernetes会根据QoS类别通过cgroup为设置Pod优先级。当系统整体内存资源不足时,优先杀死低优先级Pod。其优先级从高到低依次为:
1、Guaranteed - Pod中的所有容器的设置了CPU/内存资源的requests与limits值,且requests等于limits。Guaranteed Pod优先级最高,有确定性资源保障,适于对稳定性要求高的生产应用。
2、Burstable - Pod中有任一容器的CPU/内存资源设置了requests与limits值,但是requests不等于limits。
3、Best-Effort - Pod中的所有容器均未设置requests与limits。Best-Effort类型的应用只能使用节点上的空闲资源,优先级最低。
由于一个节点可以运行多个Pod,用户可以利用应用间资源用量的峰谷变化和QoS,控制节点资源超售比例。在Serverless Container场景下,每个沙箱中只运行一个应用,目前ECI、Fargate都只支持Guaranteed QoS的Pod,不支持资源超售。GKE Autopilot虽然在底层Node节点上可以运行多个Pod,但是资源超售会让技术实现过于复杂,导致产品与用户的责任边界也不清,目前也只支持Guaranteed QoS的Pod,不支持资源超售。
对网络通讯模式效率的影响
在 Cloud Programming Simplified: A Berkeley View on Serverless Computing [13]一文中,提到在机器学习、大数据等分布式系统中常见的通信模型,比如Broadcast, Aggregation 和 Shuffle等,在Serverless计算场景下复杂度剧增。
在基于VM方式方案中,运行在同一台实例上的所有任务可以通过本地共享数据或者网络的方式来实现高效的广播(Broadcast) 与聚合 (Aggregation) 。其通信复杂度是O(N),其中N是VM实例的数量。如果使用Cloud Functions,由于无法执行本地聚合,这个复杂度将会提升到O(N * K),其中K是每台VM上运行的函数实例的数量。在Shuffle操作上这个差异会更加明显,其Serverless场景的消息数量会比基于VM的方案高出2个数量级以上。
这样的挑战在Serverless Container场景下同样存在。与传统的Kubernetes部署方式不同,Serverless Container之间无法通过宿主机节点进行数据共享与本地网络通讯,开发者也无法精细控制实例的节点亲和性。这样的架构设计对于Web应用、微服务、中间件、数据库等工作负载是适合的。但是对于大数据和分布式训练等应用场景,我们需要针对性地优化应用架构。
比如,在阿里云EMR on ACK的产品之中,可以将网络与I/O密集型的数据Shuffle任务卸载到独立的Remote Shuffle Service中执行。极大提升了云原生Spark场景下Shuffle的性能与稳定性。
Serverless Kubernetes的采用路径
Serverless Container和Serverless Kubernetes是复用容器生态的基础上,针对云架构进行了架构取舍和重新设计。Serverless Container 非常适于弹性的工作负载,比如Web应用或微服务,或者批量计算任务。也非常适合有强隔离诉求的一些业务场景,比如在一个集群上允许来自第三方的应用或者提供租户间的安全隔离。但是其架构特殊性,也对客户容器应用的部署、运维产生一定的影响,这也是阿里云容器服务提供不同集群形态的原因。在K8s集群模式选择上:
如果客户更加关注运维成本,可以使用阿里云可观测产品技术栈满足运维管理需求,并可以针对Serverless Kubernetes的约束进行应用改造和适配,ASK(Serverless Kubernetes集群)是最优选择。阿里云容器服务会对Kubernetes控制面,系统的Addon(比如 Ingress,DNS等)进行全面的自动化的运维管理。用户无需进行容量管理,只需为应用使用的资源付费。
如果你需要更高的灵活性、可控制性,比如需要在节点上运行特权容器,或者希望通过调度配置优化资源效率等。你可以选择ACK的托管集群,并开启虚拟节点。将合适的应用负载运行在Serverless Container中。ACK 可以统一管理和调度ECS 节点池和 ECI 容器实例,帮助客户平滑迁移到Serverless时代。
总结
在Serverless Kubernetes作为云计算发展中的一个新物种,将Kubernetes技术与云架构深度融合。在其发展过程中,也带来了一些新的挑战,我们需要系统化思考其发展路径,对基础设施层与Kubernetes层进行整体设计,在更多的业务场景中为客户最大化云价值。
非常感谢与弹性计算、基础软件等团队的并肩作战,一起打造和完善 Serverless Container和Serverless Kubernetes的产品和技术,为云上客户提供极简的使用体验和极致的弹性能力。也有很多能力应用在集团和阿里云产品场景之中。下一篇,会介绍下一步Serverless Kubernetes的一些最新进展和发展方向。
参考链接:
[1]:https://man7.org/linux/man-pages/man7/capabilities.7.html
[2]:https://dockerlabs.collabnix.com/advanced/security/capabilities/
[3]:https://help.aliyun.com/document_detail/163023.html
[4]:https://help.aliyun.com/document_detail/167801.html
[5]:https://help.aliyun.com/document_detail/429749.html
[6]:https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-security
[7]:https://cloud.google.com/kubernetes-engine/docs/resources/autopilot-partners
[8]:https://help.aliyun.com/document_detail/429717.html
[9]:https://help.aliyun.com/document_detail/189276.html
[10]:https://help.aliyun.com/document_detail/451263.html
[11]:https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/1412-immutable-secrets-and-configmaps/README.md
[12]:https://help.aliyun.com/document_detail/398680.html
[13]:https://rise.cs.berkeley.edu/blog/a-berkeley-view-on-serverless-computing/
作者 | 冬岛、贤维、幻云、微垣
来源 | 阿里云开发者公众号