Knative核心概念与原理、应用场景与思考
Knative是什么?
knative 是 Google 的开源无服务器架构解决方案。它旨在提供简单易用的 Serverless 解决方案并标准化 Serverless。目前参与的公司主要有Google、Pivotal、IBM和Red Hat。 2018年7月24日刚刚发布,目前仍处于快速开发阶段。
这是 Knative 宣布的 Google Cloud Platform 简介:
Knative 与 Pivotal、IBM、Red Hat 和 SAP 密切合作开发,通过提供构建块来推动基于 Kubernetes 的计算向前发展。需要构建和部署现代化的、基于容器的无服务器应用。
可以看出,Knative 解决了以容器为核心的构建、部署和运行无服务器应用的问题。
无服务器的概念已经存在很长时间了。要理解Serverless,我们可以从应用程序开发人员的角度来看待它。使用Serverless框架后,应用开发者的整个操作流程变成:
~ # 编写 code 和 configuration 文件
~ # faascli build
~ # faascli deploy
~ # curl http://myapp.com/hello
hello, world from Awesome FaaS App!复制代码可以看到用户只需要在配置文件中编写代码(或函数)(关于如何构建、运行、访问等的声明性信息) ,然后Build and Deploy自动将应用部署到集群(可以是公有云,也可以是私有集群)。
其他事情由无服务器平台自动处理(例如这里的 Knative)。这些内容包括:
- 自动完成构建容器的代码
- 将应用程序(或函数)绑定到特定事件:当事件发生时,自动触发应用程序(或函数)
- 网络路由和流程控制
- 自动应用程序扩展
与标准化 FaaS 不同,knative 期望运行所有工作负载:传统应用程序、函数、容器。
knativ 构建于 kubernetes 和 istio 平台之上,利用了 kubernetes 提供的容器管理能力(deployment、replicaset、pods 等),以及 kubernetes 的网络管理功能(ingress、LB、动态路由等)伊斯蒂奥
Knative 核心概念和原理
为了实现 Serverless 应用的管理,knative 将整个系统分为三个部分:
- Build:构建系统,构建用户自定义函数和应用以及容器镜像
- Utility :服务系统,用于配置应用路由、升级策略、自动扩缩容等功能,自动将用户代码构建成容器镜像。乍一听起来很奇怪。有了Docker,不就可以用Dockerfile构建一个容器了吗?为什么我们需要一个新的建筑系统?
Knative 的特殊之处有两点:第一,它的构建是在 kubernetes 中完成的,与整个 kubernetes 生态结合得更加紧密;此外,应该有一个通用的标准化建筑组件,用作更大系统的另一部分。
正如官方文档所说,更多的是定义一个标准化的、可移植的、可重用的、性能高效的构建方法:
Knative Build 的目标是提供一个标准的、可移植的、可重用的、性能优化的方法定义并运行集群上容器镜像构建。
Knative 提供
BuildCRD 对象,允许用户通过 yaml 文件定义构建过程。一个典型的Build配置文件如下:apiVersion: build.knative.dev/v1alpha1 kind: Build metadata: name: example-build spec: serviceAccountName: build-auth-example source: git: url: https://github.com/example/build-example.git revision: master steps: - name: ubuntu-example image: ubuntu args: ["ubuntu-build-example", "SECRETS-example.md"] steps: - image: gcr.io/example-builders/build-example args: ['echo', 'hello-example', 'build'] 复制代码其中,
serviceAccountName是连接构建所需的密码和认证过程信息,在打印镜像中的用户名和密码为注册表等);Source是代码信息,比如这里的Git地址和分支;steps是实际运行过程中的不同步骤。本示例中的步骤只是作为一个演示,实际的构建过程一般包括绘制代码、构建镜像以及将镜像推送到注册表等逻辑。由于大多数构建过程都是一致的,所以knative还提供了
构建模板的概念。构建模板封装了预定义的构建流程(即封装了上面的step流程),并提供了非常简单的配置参数来使用。使用构建模板构建容器镜像更加容易。您只需要指定代码的地址和图像的名称。例如,下面是使用 Google Kaniko 模板构建 Github 源码的 Yaml 文件(代码根目录下必须存在 Dockerfile):
apiVersion: build.knative.dev/v1alpha1 kind: Build metadata: name: kaniko-build spec: serviceAccountName: build-bot source: git: url: https://github.com/my-user/my-repo revision: master template: name: kaniko arguments: - name: IMAGE value: us.gcr.io/my-project/my-app复制代码Serving:服务系统
服务的核心功能是使应用程序能够运行并提供服务。虽然听起来很简单,但它包含了很多东西:
- 自动启动和销毁容器
- 根据名称生成网络访问相关的服务、入口等对象
- 监控应用程序请求并自动扩容和缩容
- 支持蓝绿发布和回滚功能,方便应用方法流程
原生服务功能基于kubernetes和istio开发。它使用 kubernetes 来管理容器(Deployment、Pod),使用 istio 来管理网络路由(VirtualService、DestinationRule)。
由于kubernetes和istio本身有很多难以理解和管理的概念,Knativ在上面提供了更高层次的抽象(这个对应关系是基于kubernetes的CRD实现的)。这些抽象概念之间的对应关系如下:
- 配置:应用程序的最终配置,也就是应用程序当前期望的状态,对应kubernetes的容器管理(部署)。每次更新应用程序时都会更新配置,knative 还会保留历史版本的记录(图中的修订版)。结合流量管理,knative 可以允许多个版本一起提供服务,方便蓝绿发布和滚动升级。‘Istio 的流量管理(VirtualService)
- Service:注意这不是 kubernetes 中提供服务发现的服务,但是knative的自定义CRD。他的全名目前是
services.serving.knative.dev。服务的所有功能都可以通过自己控制路由和配置来实现,但是knative推荐使用service进行管理,因为它会自动帮你管理路由和配置
服务配置是一个hello world,如下:
apiVersion: serving.knative.dev/v1alpha1 kind: Service metadata: name: helloworld-go namespace: default spec: runLatest: configuration: revisionTemplate: spec: container: image: docker.io/{username}/helloworld-go env: - name: TARGET value: "Go Sample v1" 复制代码看起来和kubernetes的pod定义非常相似,但是它可以帮助你部署、入口、服务发现、自动伸缩……为你提供帮助。实施细节。
下图表示了 knative 服务各组件之间的关系:
- 可以看到,每个版本对应一组部署管理的 pod
- pod 会自动向 autoscaler 上报指标数据, Autoscaler会根据请求量和资源使用情况改变部署的副本数量,实现自动扩缩容。 Serverless 的一个重要特性是它可以缩放到 0,也就是说,如果应用程序没有流量访问,它会自动销毁所有 pod
- activator 比较有趣,它似乎可以处理缩放到 0。如果 pod 在修订后缩小到 0,则路径流量将定向到激活器。激活器收到请求后,自动拉起 pod 并将流量发送到其中
- 路由对象对应 istio 的 DestinationRoute 和 VirtualService,决定如何将流量路由到应用程序
事件:事件系统
Utility实用系统的功能是使应用程序/功能能够自动运行和扩展。什么时候会调用应用程序?除了我们熟悉的正常的应用程序调用之外,Serverless 最重要的是基于事件的触发机制,这意味着当某些事情发生时,会触发特定的功能。
事件概念的出现使得函数能够与特定的调用者解耦。当一个函数被调用时,谁调用它并不重要,当一个事件源被触发时,谁处理它并不重要。
注:目前有很多 Serverless 产品和平台,每个位置支持的事件源和事件定义都不同(例如 AWS Lambda 支持很多来自自己产品的事件源)。 Knative 当然会定义自己的事件类型。此外,knative 还与 CNCF 合作,对事件进行标准化。当前输出是 CloudEvents 项目。
为了让整个事件系统更具可扩展性和通用性,knative 定义了很多与事件相关的概念。先介绍一下:
- EventSource:事件源,可以生成事件的外部系统
- Feed:将某种类型的EventType和EventSource绑定到对应的通道
- Channel:实现消息的抽象层,后端可以使用Kafka、RabbitMQ、Google PubSub作为具体实现。通道名称与消息集群中的主题类似,可用于解耦事件源和功能。事件发生后下沉到一个通道,然后通道中的数据被后端函数消费
- 订阅:将通道和后端函数绑定在一起。一个通道可以绑定多个knative服务
它们之间的关系流程图如下:
Bus是Knative中的事件存储层。用户可以选择他们感兴趣的实现。目前支持的方法有:Stub(在内存中实现的简单消息系统)、Kafka、Google PubSub。如果您希望事件正常工作,则必须在 knative 集群中安装总线实现之一。
通过总线我们可以监控外部事件。目前支持三种事件源:github(如合并事件、推送事件等)、kubernetes(事件)、Google PubSub(消息系统)。稍后将添加更多事件源。
如果你想监听合适的事件源,你需要在Knative中部署一个源适配器Pod,它负责从外部系统读取事件。
读取事件后,根据用户配置的feed对象(其中包含事件源与通道的对应关系)找到对应的通道,然后将消息发送到这个通道(the Channel)消息最终在存储的后端总线系统中)。
然后knative根据订阅配置不断从通道中读取事件,然后以事件为参数调用相应的函数,从而完成整个事件流程。
Knative 目前的状态
knative 在 2018 年 7 月才对公众开放,虽然已经内部开发了一段时间,但仍处于非常早期的阶段(从支持的事件源和总线可以看出) )。目前代码不稳定,许多实现都是硬编码的。
knativ同样来自Google和CNCF,所以整个社区的运营方式和目标与之前的kubernetes和istio非常相似。社区根据组件分为不同的工作组。每个小组独立负责自己的职能。所有开源活动(文档、视频、代码)都是开放的。此外,CloudEvents作为knative所依赖的标准,也旨在提供与CRI、CNI、CSI类似的标准。
knative 社区目前非常活跃。
github.com/knative/serving项目就是一个例子。它一个月内有 600+ 颗星,目前有 60+ 员工,900+ 次提交,介绍性文档和教程非常全面。Knative应用场景与思考
knative是一个基于kubernetes和istio的无服务器开源实现。目标是提供更高层次的抽象,使开发人员不必关注基础设施(虚拟机或容器、网络配置、容量规划)而只需关注业务代码。 ?大多数互联网应用具有高竞争性和高性能要求。整个Serverless网络连接很长,启动和停止容器需要额外的时间,无法满足互联网应用的要求。
从这一点来看,很多Serverless框架也不断进行改进,比如不断精简容器的启动时间、容器启动后进行缓存等。例如,nuclio 声称其平台比 AWS Lambda 快 10 倍以上。
相信随着Serverless的不断演进,性能问题会不断得到优化。至于是否符合互联网应用的要求,还需要时间给我们答案。
2。 istio层有必要吗?
基于kubernetes的Serverless组件有很多,比如kubeless。但同时基于istio,knative目前是第一个做到这一点的。
有人的疑问是,Knativ 真的有必要基于 istio 吗?我对这个话题的个人看法是必要的。
虽然istio刚刚发布了1.0版本,但它作为集群基础设施通用网络层的地位已经开始显现。相信在未来的发展中它的接受度会越来越高,地位也会逐渐得到巩固。虽然现阶段很多人对istio还不是很熟悉,但从长远来看这将是Knativ的一个优势。
此外,基于istio构建自己的Serverless服务也符合当前软件行业,不重新发明轮子的工作。 istio在集群网络管理(智能路由、负载均衡、蓝绿发布等)方面表现出色。 knative基于istio,可以直接使用istio提供的常用网络功能,无需重复工作。
3。系统复杂度
这与上面类似。 knative 下已经有两个非常复杂的平台:kubernetes 和 istio。理解、构建、操作和维护这两个平台本质上是复杂的。现在整个原生平台都已经加上去了,需要理解的概念有几十个,更不用说实现过程中遇到的各种问题了。
对于公有云来说,kubernetes、istio等底层平台可以由云提供商(如Google Function)来维护,但对于内部建设来说,这无疑提高了整个技术门槛,这对于系统管理人员来说是非常困难的。要求更高。
如何安装部署整个集群?如何升级集群?如何调试和跟踪问题?如何更好的与内部系统对接?这些系统的最佳实践是什么?如何优化性能?这些问题都需要集群管理者思考并落实。 4。功能的运行和维护?
与编写微服务相比,单个功能的复杂度已经很低,但当大量功能需要协同工作时,如何管理这些功能就成了需要解决的问题。
- 查找函数的速度有多快?
- 如何知道函数的作用?接受哪些参数?
- 如何保证功能升级不破坏原有功能?升级后如何回滚?如何记录函数的历史版本并恢复?
- 如果有多个功能必须同时工作,如何定义它们之间的关系?
- 功能出现问题如何调试?
在功能运维方面,常见的Serverless平台(包括Knativ)提供日志、指标、追踪三大功能。默认情况下,knative 使用 EFK(Elasticsearch、Fluent、Kibana)来收集、查找和分析日志;使用Prometheus + Grafana收集、索引和展示指标数据;并使用jaeger进行调用关系追踪。
Serverless衍生出来的运维工具和平台还不够多,线上问题如何调试也没有很好的解决方案。
5。 Knative成熟度
最后一点是关于Knative的成熟度。正如前面提到的,Knative 最近出现了。虽然整个框架和设计已经建立,但很多实现还比较初级。以下是一些要点:
- 为了实现自动缩放,knative 向每个 pod 添加一个名为 Queue Proxy 的代理,该代理会自动将请求的指标发送到自动缩放器组件作为参考。这样整个网络连接就多了一层,肯定会对整个性能产生影响。未来的计划是直接使用 Envoy Sidecar 来替代 Queue Proxy
- 支持的事件源和消息系统。外部事件仅支持 github、kubernetes 和 Google PubSub。这个问题可以慢慢扩大。 Knative 本身将实现非常通用的事件类型。用户可以自行实现自定义事件源
- 目前没有函数的管道管理(类似于AWS Lambda Step Functions)。不同职能如何协作和合并?自己没处理好。虽然我没有在官方文档中看到这个路线图,但是以后肯定会有这个功能(无论是Knative本身做的,还是社区作为工具补充实现的)
这个问题并不大。随着knative版本的迭代,很快就会得到解决。
作者:金融级分布式架构
来源:掘金
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网