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技术带来的好处:
- 时间效率:devops整体的效率
- 成本效率:提高资源使用率,按需付费
云服务提供商的挑战:计算资源,存储等服务按量弹性伸缩及收费
Knative
本篇主要是对Knative的整理,Knative是Google 与 Pivotal、SAP、Red Hat、IBM 等行业领导者携手合作的 Serverless 项目,也是目前主流的Serverless平台。
Google在云原生领域目前有了这三部曲:
- Kubernetes:云平台底座,解决了应用上云的问题,主要包括:资源调度,服务伸缩
- Istio:服务网格,和开发语言无关,剥离掉服务运行时要有的通用能力,抽象为kubernete组件并以非侵入的方式提供:服务注册与发现,路由配置,负载均衡,重试,超时,熔断,故障注入,策略控制,遥测收集等。
- Knative :代码消除到至简,最后只剩业务逻辑。简化分为三部分:构建配置,服务kuber,istio配置,和工程代码。
Knative 构建在Kubernetes,Istio之上,与不同角色之间的关系:
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资源. 这些对象用于定义和控制您的无服务器工作负载在集群上的行为。包括如下:
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各组件之间的关系:
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。
事件发送分为直接发送,和使用通道,订阅发送到多个端点
实际的消息转发如下图:
事件还包括一些组件,目前这块功能还在快速演化。
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