Serverless Kubernetes 的思考与征程
作者:牛秋霖、张维、李传云、易立
本文将针对 Serverless Container 技术的特殊性,分享其对 Kubernetes 的架构影响,以及阿里云在 Serverless Kubernetes 方面架构选择。
一、Serverless Container 缘起
在 2018 年,容器团队与弹性计算团队启动了 Serverless Container 与 Kubernetes 的研发,其目标是融合容器技术和云基础设施能力,最大化利用云的弹性和自动化运维能力。为此,我们为 Serverless Container 定义了其几个关键架构原则:
单一职责 Single Responsibility —— 在传统的容器编排中,需要预先分配的工作节点上调度容器应用执行,一个工作节点上可以运行多个容器应用,同节点内部应用共享 OS 内核,存在资源和安全干扰;而在 Serverless Container 中,每个应用运行在独立的安全沙箱中,独享 OS 内核,应用之间不存在相互的资源干扰,有明确的安全作用域。单一职责使得从资源弹性供给到应用调度的全链路可以一体优化,极大优化了弹性效率。
不可变性 Immutability —— 在 Serverless Container 实例在创建后,作为一个不可变的基础设施只支持部分配置变更,比如 ConfigMap 配置,镜像版本,资源配额等。如果变更引发应用拓扑或者资源的变化,比如一个新版本的 AI 应用从之前只依赖 CPU 到依赖 GPU 设备,需要重建而非原地更新。不可变性极大简化了运维复杂性。
位置无关 Location independency —— 用户可以通过一些部署策略,比如可用区、失效域等,控制 Serverless Container 的部署位置,但是用户无法指定 Serverless Container 所在的具体的物理节点。Serverless Container 是临时性的(ephemeral),所有持久化应用状态要保存在外部存储中(比如 EBS,NAS,OSS 等)或数据服务中,而不能依赖宿主机文件系统。重建 Serverless Container 实例不能保障 IP 地址不变。位置无关使得容器可以在整个弹性资源池上进行供给和动态迁移
通过这几个基本原则,用 Serverless Container 和 Serverless Kubernetes 重新定位了云平台与开发者之间的边界,尽可能让开发者聚焦于应用,而将资源调度、基础设施运维、高可用、系统优化等复杂性交给到基础设施完成。实现将复杂留给自己,将简单留给用户的技术初心。
1.1 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 包含了两种不同的实现架构,具备不同的优势和特点,可以由控制面按需调度满足用户资源供给需求。
并池架构:阿里云在神龙架构上实现了 ECI 实例、ECS 实例、裸金属实例的统一供给,这样可以充分利用阿里云整体弹性计算资源池保障弹性资源供给;并且可以利用现有 ECS 规格实现丰富的资源类型,比如 GPU 实例、AMD、倚天实例等,以及地域覆盖;同时可以利用弹性计算资源池中的碎片资源,提升整体利用率。但是并池架构也存在一些挑战,比如,对每个 ECI 实例都会包含完整 ECI Agent、Container Runtime 等组件,会占用较多的系统资源。此外,在支持 ECS 与 ECI 混布的场景下,复用了虚拟机的存储网络编配流程,容器的启动速度和并发度受限于整体链路效率。
专属池架构: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 的抽象架构如图:
其中重要的组成部分包括:
ACK Scheduler - 是 ACK 增强的 K8s 调度器实现,除了增强批量任务、GPU 调度等能力之外,支持根据资源策略自动选择在 ECS 节点池或者 ECI 上进行调度和重调度。
Virtual Node Addon - 作为 ECI 与 Kubernetes 架构之间的适配器,实现 ECI Pod 的生命周期管理,以适配部分 Node 相关的实现,比如 Metrics Server,Prometheus 的集成。Virtual Node 是集群中的一个逻辑概念而不是一个物理实体,不支持 NodePort,DaemonSet 等 Node 级别概念。
在应用弹性层,ACK/ASK 也支持了众多的增强可以更好地帮助应用充分利用云的弹性能力,支持 ECI 这样的弹性新算力,比如 AHPA 可以根据 AI 算法预测弹性趋势,降低弹性的滞后性,阿里云也针对云的特性,扩展 Knative/KEDA 等应用弹性实现,比如更好地支持 Spot 类型弹性资源等,细节将在下篇中进行介绍。
在应用框架层,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 的一些限制与应对之道。
3.1 不支持节点网络模型
由于 Serverless Container 中不再对外暴露 Node 的概念,Serverless K8s 不再支持节点网络模型,比如 NodePort 类型的 Service、HostPort 或者 HostNetwork,需要用户调整使用 Load Balancer 类型服务或者 Ingress 为容器应用对外提供服务。
3.2 容器安全模型的改变
经典 Kubernetes 和 Serverless K8s 在数据面安全模型有很多不同。我们可以快速对比一下二者在数据面架构的差异。
3.2.1 Pod 实例强安全隔离
Serverless Container 运行在基于 MicroVM 的安全沙箱之中。不同实例之间不共享操作系统内核,减小了安全攻击面。因此 Serverless Container 实例之间不能通过宿主机资源,比如本地文件系统和进程间通讯机制(共享内存,管道等)进行相互访问,只能通过远程文件存储和网络进行数据交换。
ECI 的资源交付单位是 Pod。如果容器间需要通过本地 OS 进行共享文件或者进程间通讯,我们需要将其组合运行在相同 ECI 实例(Pod)之中。
3.2.2 受限的运行权限
在 Serverless 容器沙箱中同时运行着用户应用以及平台的系统组件。为了防止用户应用对云平台的安全攻击,Serverless Container 限制了用户应用进程的运行权限。
不支持特权模式 (privileged mode):一些系统级应用,比如 systemd,Docker In Docker,GPU 监控等需要运行在特权模式应用是无法运行在 ECI 之中的。
受限的 Linux capabilities:Linux Capabilities 可以精细化控制一个进程所需的权限。为了避免安全渗透,Serverless Container 中的应用进程只支持受限的 capabilities 集合。在 Docker 容器的默认 capabilities 集合之外,通过 Guest OS 内核加固,ECI 扩展了部分 capabilities 支持,比如 SYS_PTRACE 支持 Sysdig Falco 等使用 ptrace 的应用,NET_ADMIN 支持 Istio 等服务网格应用。更多细节请参见配置 Security Context 。然而由于一些 Capabilities 具备更大的安全攻击面风险,比如使用 eBPF 应用,是无法直接运行在 Serverless 容器之中的。
不支持宿主机访问:在 Serverless Container 中已经没有 host 的概念,自然用户无法访问宿主机的资源,这引入了一些限制。比如过去用户需要登录工作节点并执行 coredump 、抓包等操作来定位应用问题,但是这在 Serverless Container 场景下是不支持的。为此,ECI 提供了内建的 coredump 以及 tcpdump 抓包 分析工具来实现。
注:在 GKE Autopilot 中,虽然它依然采用了传统的 Node 模式,但是 Node 的资源归属属于云平台,对用户不可见。因此它也采用了类似的受限容器权限模型,来防止安全攻击和滥用。为了解决众多监控、安全、日志等软件对更高系统权限的要求,Google 提供了一个 Autopilot partner workloads 项目,对认证过的应用镜像进行白名单处理。
3.2.3 容器粒度云资源授权模型
容器技术成为了用户使用云的新界面。其中一个重要原因是 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 功能,开发者可以为应用所使用的服务账户(Service Account)创建一个 RAM 角色,并对其进行授权。容器应用在运行时可以通过 SA 获取扮演这个 RAM 角色的临时凭证实现对云服务的访问,这种方案实现了应用 RAM 权限最小化以及 Pod 对云资源访问的细粒度隔离需求。
3.2.4 融合的容器网络与虚拟化网络安全
ECI 复用了阿里云虚拟化基础设施,每个 ECI 实例具备独立的弹性网卡。ECI 在网络模型上保持了与 ECS Worker Node 的容器网络的高度兼容,支持 ECI 实例与 Worker Node 上 Pod 的互联互通,支持 ECI 实例访问 VPC 资源,支持各种类型 K8s 服务发现与访问,比如 ClusterIP、Loadbalancer、DNS、Ingress 等等。
ASK/ACK on ECI 支持基于安全组的网络隔离控制。也可以利用现有的 VPC Flow, SLB 流量安全等云服务发现潜在的网络安全风险。
下一步 ASK 和 ACK on ECI 会提供兼容 Kubernetes network policy 的网络安全策略管理,可以更加细粒度、一致性地管理 Pod 的网络连通性。
3.2.5 运行时安全与风险修复流程调整
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 实例。
3.3 不支持 DaemonSet
在经典的 Kubernetes 架构中, 的工作节点中一般会运行用户的基础设施 agent (如日志、安全、监控、运维) 等。他们通常采用 DaemonSet 部署,以 Pod 为单位部署在节点中,管理整个节点上的所有容器应用。基础设施 agent 可以通过 OS 能力(如文件系统,进程间通讯等)和容器引擎,对相同节点中的容器应用进行监控指标、日志采集、安全防御、资产管理等操作。基础设施 Pod 与应用 Pod 生命周期解耦,可以独立更新,不对应用 Pod 的造成影响也不受应用 Pod 影响。
在弹性容器实例中,每个容器应用运行在一个独立的沙箱中。面向节点运维的基础设施 agent,要针对 Serverless Container 的特殊性进行转化与改造才能继续运行。下面,我们将介绍 Sidecar 和 Hidecar 两种不同的架构模式。
3.3.1 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 的部署和运维体验。
3.3.2 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 受限于资源分配,就有可能出现日志上传的堆积。
3.4 对整体架构可伸缩性的挑战
容器应用通常被应用于微服务架构和大数据、AI 等计算任务。他们和传统的应用相比,其生命周期更短,数量更多。根据 Sysdig《2023 云原生安全与使用情况调查报告》,近 90%的容器应用的生命周期<1 天,其中 72%的容器生命周期小于 5 分钟。Serverless 容器将对整体的架构带来众多的可伸缩性挑战。
3.4.1 对云基础设施管控的 scalability 挑战
Serverless 容器应用与传统虚拟机应用相比,生命周期小 1~2 个数量级。ECI 目前每天有数百万的容器实例被创建和释放,而且随着 AI、大数据等数据任务类应用的拓展,整体数量在持续快速增长中。Serverless Container 应用对底层基础设施管控链路带来的压力是远超于虚拟机。这里面需要在基础设施层和 Kubernetes 层相结合来解决。
在基础设施层,一方面需要计算、存储、网络等云资源提升管控容量,一方面要针对不同容器应的特殊性优化底层资源生产供给。比如针对计算任务优化的 ECI Job 优化型实例,它不需要独立的 ENI,可以通过阿里云网络 Mesh(ANSM)技术大大提升网络建联效率,从而实现更好的可伸缩性和更优的弹性。
在 Kubernetes 层,ASK/ACK 针对 ECI 架构的特殊性进行了改造和优化。首先要避免通过 ECI OpenAPI 进行频繁的数据交换,降低对 ECI 管控链路的压力。比如,在 Serverless Kubernetes 中,对 Pod 的健康检查、Exec、日志、监控等场景,通过 ECI 沙箱中的 agent 与 API Server 之间的直接通信旁路了 ECI 管控,可以有效提升整体架构的可伸缩性。此外在 API Server 中对 ECI 容器创建、删除等场景做了更细粒度的限流、降级机制实现,避免突发流量引发雪崩。未来也会增加优先级队列等方式,在底层资源发生流控的同时,优先保障高优先级任务的处理。
3.4.2 对 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 的实现,我们可以由不同的架构选择:
一个是 one pod per node 架构。AWS EKS on Fargate 只是将部分节点级别组件运行在沙箱内部,不修改 K8s 整体架构。这种方式对 K8s 架构侵入性较小,但会引入较大的伸缩性问题。比如目前 AWS EKS 只支持单集群 1000 Fargate 实例。
另一种则是针对 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 类型,在 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%以上的连接数。
3.5 Worker Node 与 Serverless Container 混合调度挑战
越来越多的 ACK 用户在使用 ECS 作为 Worker Nodes 的同时,也在在弹性、计算类任务等场景应用 ECI。客户可以自由组合不同类型的弹性计算资源满足业务对资源确定性、成本等多方面需求。比如在 ACK 集群中,客户可以用包年包月的 ECS 节点池承载常态业务流量,用按量付费 ECS 节点池承载大促等可预期的业务波动,利用虚拟节点/ECI 支持突发的业务流量。
ACK 针对 K8s 调度器进行了扩展,支持客户自定义资源策略 ResourcePolicy 在不同类型的资源类型间实现优先级调度。比如为了优化弹性成本,可以指定当应用扩容时优先在 ECS 的空闲资源上调度应用,如果容量不足再调度到 ECI 之上;同时在应用缩容时优先删除 ECI 上的 Pod,再删除 ECS 节点上的 Pod。ResourcePolicy 为用户在云上不同弹性资源供给之间提供了一致、透明的调度策略,也可以帮助客户将适合的业务逐渐切换到 Serverless Container 之上。
3.6 目前尚不支持资源超售
在 Kubernetes 架构中,开发者可以通过定义 Pod 资源(CPU,Memory 等)的 requests 和 limits 控制应用调度与资源使用。Kubernetes 会根据资源 requests 值调度 Pod,容器运行时会根据 limits 值使用 cgroup 限制容器最大资源用量。比如当容器进程内存消耗超过 limits 时,会被杀死。当容器进程 CPU 消耗超过 limits 时会被限流。
Kubernetes 中 Pod 具备不同 QoS 类型。Kubernetes 会根据 QoS 类别通过 cgroup 为设置 Pod 优先级。当系统整体内存资源不足时,优先杀死低优先级 Pod。其优先级从高到低依次为:
Guaranteed —— Pod 中的所有容器的设置了 CPU/内存资源的 requests 与 limits 值,且 requests 等于 limits。Guaranteed Pod 优先级最高,有确定性资源保障,适于对稳定性要求高的生产应用。
Burstable —— Pod 中有任一容器的 CPU/内存资源设置了 requests 与 limits 值,但是 requests 不等于 limits。
Best-Effort —— Pod 中的所有容器均未设置 requests 与 limits。Best-Effort 类型的应用只能使用节点上的空闲资源,优先级最低。
由于一个节点可以运行多个 Pod,用户可以利用应用间资源用量的峰谷变化和 QoS,控制节点资源超售比例。在 Serverless Container 场景下,每个沙箱中只运行一个应用,目前 ECI、Fargate 都只支持 Guaranteed QoS 的 Pod,不支持资源超售。GKE Autopilot 虽然在底层 Node 节点上可以运行多个 Pod,但是资源超售会让技术实现过于复杂,导致产品与用户的责任边界也不清,目前只支持 Guaranteed QoS 的 Pod,不支持资源超售。
3.7 对网络通讯模式效率的影响
在 Cloud Programming Simplified: A Berkeley View on Serverless Computing 一文中,提到在机器学习、大数据等分布式系统中常见的通信模型,比如 Broadcast, Aggregation 和 Shuffle 等,在 Serverless 计算场景下复杂度剧增。
Cloud Programming Simplified: A Berkeley View on Serverless Computing
https://rise.cs.berkeley.edu/blog/a-berkeley-view-on-serverless-computing/
在基于 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 的一些最新进展和发展方向。
版权声明: 本文为 InfoQ 作者【阿里技术】的原创文章。
原文链接:【http://xie.infoq.cn/article/0536b81f9521017d311ee718d】。文章转载请联系作者。
评论