Serverless

Serverless

定义:表面上的意思是无须关心服务的计算资源,会按照请求量自动伸缩;

实际上,Serverless,最大价值或愿景是 “just to focus on business logic”,真正落地“面向业务”,降低研发门槛和提升效率。

Serverless 和传统云计算的区别:

  • Decoupling of computation and storage; they scale separately and are priced independently.
  • The abstraction of executing a piece of code instead of allocating resources on which to execute that code.
  • Paying for the code execution instead of paying for resources you have allocated to executing the code.

Serverless技术带来的好处:

  1. 时间效率:devops整体的效率
  2. 成本效率:提高资源使用率,按需付费

云服务提供商的挑战:计算资源,存储等服务按量弹性伸缩及收费


Knative

本篇主要是对Knative的整理,Knative是Google 与 Pivotal、SAP、Red Hat、IBM 等行业领导者携手合作的 Serverless 项目,也是目前主流的Serverless平台。

Google在云原生领域目前有了这三部曲:

  • Kubernetes:云平台底座,解决了应用上云的问题,主要包括:资源调度,服务伸缩
  • Istio:服务网格,和开发语言无关,剥离掉服务运行时要有的通用能力,抽象为kubernete组件并以非侵入的方式提供:服务注册与发现,路由配置,负载均衡,重试,超时,熔断,故障注入,策略控制,遥测收集等。
  • Knative :代码消除到至简,最后只剩业务逻辑。简化分为三部分:构建配置,服务kuber,istio配置,和工程代码。

Knative 构建在Kubernetes,Istio之上,与不同角色之间的关系:

upload successful
Knative组件包括:

  • Build(构建)(deprecated):
    通过灵活的插件化的构建系统将用户源代码构建成容器。目前已经支持多个构建系统,比如 Google 的 Kaniko,它无需运行 Docker daemon 就可以在 Kubernetes 集群上构建容器镜像。随着pipeline功能的演化以及未来定位,将这部分剥离Knative,形成一个标准化云原生Kubernetes CI/CD解决方案—Tekton。
  • Serving(服务):
    基于负载自动伸缩,包括在没有负载时缩减到零。允许你为多个修订版本(revision)应用创建流量策略,从而能够通过 URL 轻松路由到目标应用程序。
  • Event(事件):
    使得生产和消费事件变得容易。抽象出事件源,并允许操作人员使用自己选择的消息传递层。

Build(构建)(deprecated)

从源代码到容器镜像的构建,运行在 Kubernetes CRD上,其组件还包括:

  • BuildTemplate:封装可复用,参数化的构建步骤集合
  • Builder:Build可以包含多个步骤,每个步骤是一个Builder
  • ServiceAccount:私有资源(如 Git 存储库或容器镜像库)进行身份验证

目前,Knative 已经支持多个 Build Template ,包括:

  • Kaniko: 在运行的容器中构建容器镜像,而不依赖于运行 Docker daemon ,需要dockerfile。
  • Jib: 为Java应用程序构建容器镜像。
  • Buildpack: 不需要dockerfile,自动检测应用程序的运行时,建立一个容器镜像使用 Cloud Foundry Buildpack。

Knative Build构建的好处:

  • 在kubernetes之上利用CRD,提供更抽象通用的构建组件
  • 以一致的方式编译和打包代码
  • 不必每次更新代码时都构建或推送容器镜像

目前build-pipeline CI/CD已经剥离出knative,形成一个标准化的原生kubernetesCI/CD解决方案 - Tekton;从而让knative专注于serlverLess

Tekton

Kubernetes原生CI/CD系统,基于Kubernetes CRD,包括:

  • Task:构建任务,Task里可以定义一系列的steps,例如编译、构建镜像、推送镜像等,每个step实际由一个Pod执行。
  • TaskRun:Task只是一个模版,TaskRun代表了一次实际的运行,TaskRun创建出来之后,就会自动触发Task描述的构建任务。
  • Pipeline:一个或多个Task、PipelineResource以及各种定义参数的集合。
  • PipelineRun:pipelineRun也表示某一次实际运行的Pipeline
  • PipelineResource:pipeline input,output资源资源,比如GitHub上的源码,一个容器镜像或者构建生成的jar包等。

Serving(服务)

在Kubernetes 和 Istio 之上,支持部署无服务应用或方法。

Knative Serving项目提供的功能包括:

  • 无服务容器的快速部署
  • 自动伸缩(缩放可到零)
  • ISIO组件之上的路由和网络编程
  • 已部署代码和配置的时间点快照

Serving

Knative Serving 定义了一些CRD资源. 这些对象用于定义和控制您的无服务器工作负载在集群上的行为。包括如下:

upload successful

Service

service.serving.knative.dev资源自动管理工作负载的整个生命周期。它控制其他对象的创建,以确保您的应用程序对服务的每次更新都有一个Route、一个Configuration和一个新的Revision。Service可以定义为始终将流量路由到最新版本或固定版本。

Route

route.serving.knative.dev资源将网络端点映射到一个或多个Revision。您可以通过多种方式管理流量,对应了 istio 的流量管理。

Configuration

configuration.serving.knative.dev资源保持部署所需的状态。最小化 Configuration 至少包括一个配置名称和一个要部署容器镜像的引用。修改配置将创建新的修订。

Revision

revision.serving.knative.dev资源是对工作负荷所做的每个修改的代码和配置的时间点快照。

如下是一个简单的Service配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
name: helloworld-java
namespace: default
spec:
runLatest:
configuration:
revisionTemplate:
spec:
container:
image: docker.io/{username}/helloworld-java
env:
- name: TARGET
value: "Spring Boot Sample v1"

# Build the container on your local machine
docker build -t {username}/helloworld-java .

# Push the container to docker registry
docker push {username}/helloworld-java

kubectl apply --filename service.yaml
kubectl delete --filename service.yam

上面的例子没有配置build,所以需要依赖构建好的镜像,更多例子可以参考:https://www.knative.dev/docs/serving/samples/

Knative Service 的好处:

提供了更高的抽象,封装简化了 kubernetes 和 istio 的配置实现细节,包括 deployment、ingress、service discovery、auto scaling等。

下面这张图介绍了 knative serving 与kuber,istio各组件之间的关系:

upload successful

Autoscaler (自动伸缩器)

Pod自动汇报 metrics 数据到 Autoscaler,Autoscaler 根据请求量和资源情况调整 deployment 的 replicas 数量,实现自动扩缩容,包括缩容到0。伸缩算法针对两个独立的时间间隔计算所有数据点的平均值:

  • Stable Mode(稳定模式):使用 60 秒时间窗平均值决定如何伸缩部署

  • Panic Mode (恐慌模式): 6 秒窗口的平均并发量两次到达期望目标,Autoscaler 转换为 Panic Mode 并使用 6 秒时间窗

Activator (激活器)

缩容至零时所有流量均路由至 Activator,当接收到某一请求时,由Activator去激活Revision,并代理请求至Pods。

Event(事件)

设计概述

  • 事件和服务之间是解耦的,相互独立。(函数不关心谁调用了它,而事件源触发也不关心谁会处理它)
  • 生产者和事件源也是独立的,生产和订阅没有部署上的先后顺序依赖。
  • 订阅者可以选择过滤事件的内容。

概念&组件

event producers/consumers

事件的产生者,和消费者

event source

定义事件在何处生成以及如何将事件传递给关注对象的方式,producers就可以生产这些定义好的事件,并接入到Knative 体系中

channel
  • 渠道是消息传递的抽象,后端可以使用 kafka、RabbitMQ等具体的实现。channel name 类似于消息集群中的 topic,可以用来解耦事件源和函数。
  • channel 有一个 status.address.hostname 字段,这个字段确定了事件怎么到达channel。
Subscriptions

订阅是通道和服务之间的纽带,是channel 和后端函数的绑定信息,一个 channel 可以绑定到多个knative service。

事件发送分为直接发送,和使用通道,订阅发送到多个端点

upload successful

实际的消息转发如下图:

upload successful

事件还包括一些组件,目前这块功能还在快速演化。

Knative event的好处

  • 当某件事发生时,就可以触发某个的函数
  • 对事件消息的抽象,简化了编程难度

事件的很多概念也来自Spring cloud Stream,Reactive Streams ;
因为Spring Cloud就是Pivotal 的出品,Pivotal也是 Knative 主要贡献者之一;
另外,过去Spring的成功就是凭借统一的抽象,提供脚手架集成来简化应用开发的代码,接下来,Knative会更抽象,更简化,最终达到应用代码最小化到只和业务相关。

参考:

https://www.knative.dev/docs/
https://rise.cs.berkeley.edu/blog/a-berkeley-view-on-serverless-computing/
https://cloud.tencent.com/developer/article/1538063