Knative Serving 基础

发布时间 2023-10-07 14:42:22作者: 小吉猫

Knative Serving 概述

Knative Serving 将一组对象定义为 Kubernetes 自定义资源定义 (CRD)。这些资源用于定义和控制Serverless工作负载在集群上的行为方式。

Knative Serving CRD资源

Knative Serving 将一组对象定义为 Kubernetes 自定义资源定义 (CRD)。这些资源用于定义和控制serverless工作负载在集群上的行为方式。

Service

1. Service资源API在service.serving.knative.dev群组。
2. 对自动编排Serverless类型应用的功能的抽象,负责自动管理工作负载的整个生命周期。
3. 控制其他对象的创建,以确保您的应用程序具有Route、Configuration和每次服务更新的新Revision。可以将服务定义为始终将流量路由到最新版本或固定版本。

Route

1. Route资源API在route.serving.knative.dev群组。
2. 将请求流量路由到目标Revision。
3. 支持将流量按比例切分并路由到多个Revision。

Configuration

1. Configuration资源API在configuration.serving.knative.dev群组。
2. 反映了Service当前期望状态(Spec)的配置。
3. 它提供了代码和配置之间的清晰分离,并遵循十二要素应用程序方法。
4. Service对象的更新,也将导致Configuration的更新。

Revision

1. Revision资源API在revision.serving.knative.dev群组。
2. Service的每次代码或配置变更都会生成一个Revision。
3. Revision是不可变的对象,只要有用就可以保留。
4. Knative Serving Revisions 可以根据传入流量自动扩大和缩小。

Knative Serving 架构

 

Networking Layer and Ingress

在这种情况下,Ingress 并不指 Kubernetes Ingress 资源。它指的是公开对集群上资源的外部访问的概念。
Knative Serving 依赖于满足Knative Networking 规范的Networking Layer。为此,Knative Serving定义了一个内部KIngress资源,它充当不同的多个可插拔网络层的抽象。目前,社区提供并支持三个网络层:net-kourier、net-contour、net-istio。

流量和 DNS

每个网络层都有一个控制器,负责监视KIngress资源并进行相应的配置Ingress Gateway。它还将status通过该资源报告回信息。
Ingress Gateway 用于将请求路由到activator或直接路由到 Knative Service Pod,具体取决于采用的模式(proxy/serve)。Ingress Gateway 用来处理来自集群内部和集群外部的请求。
为了使 Ingress Gateway 能够在集群外部访问,必须使用类型为 LoadBalancer 或类型为 NodePort 的 Kubernetes 服务来公开它。然后将 DNS 配置为指向 Ingress 网关的 IP 或名称。

Knative Serving 子组件

Activator

Revision中的Pod数量收缩至0时,activator负责接收并缓存相关的请求,同时报告指标数据给Autoscaler,并在Autoscaler在Revision上扩展出必要的Pod后,再将请求路由至相应的Revision。

Autoscaler

Knative通过注入一个称为queue-proxy容器的sidecar代理来了解它部署的Pod上的请求,而Autoscaler会为每个服务使用“每秒请求数”来自动缩放其Revision上的Pod。

Controller

负责监视Serving CRD(KService、Configuration、Route和Revision)相关的API对象并管理它们的生命周期,是Serving声明式API的关键保障。

Webhooks

为Kubernetes提供的外置Admission Controller,兼具Validation和Mutation的功能,主要作用于Serving专有的几个API资源类型之上,以及相关的ConfigMap资源上。负责验证和改变 Knative 资源。

DomainMapping

将指定的域名映射至Service、KService,甚至是Knative Route之上,从而使用自定义域名访问特定的服务。

Queue-Proxy

Queue-Proxy 是 Knative Service Pod 中的一个 sidecar 容器。它负责收集指标并在将请求转发到用户容器时强制执行所需的并发性。如果需要的话,它也可以充当队列,类似于activator 。

Knative Serving 工作模式

Knative Serving HTTP 请求流程

HTTP 请求流程

下图显示了 Knative Serving 的不同请求流和控制平面。请注意,某些组件(例如autoscaler和 apiserver)不会根据每个请求进行更新,而是定期测量系统(这称为控制平面)。

HTTP router、activator和autoscaler 都是共享的集群级资源;这将新 Knative 服务的开销减少到仅在服务未使用时使用元数据,并允许更有效地管理和升级这些共享组件。
路由决策在 HTTP 路由器(ingress层)的每个请求级别上做出一次,并记录在请求的内部标头中。一旦请求被分配给Revision,后续路由取决于测量的流量;在低流量或零流量时,传入请求将路由到activator,而在高流量级别(备用容量大于target-burst-capacity)时,流量将直接路由到应用程序 Pod。

低流量请求流程

当特定Revision的流量较低或为零时,HTTP 路由器会将流量发送到activator,其中包括指示所选Revision的标头。activator充当传入请求的缓冲区或队列 - 如果请求路由到当前没有可用pod数量的Revision,则activator会延迟该请求并向autoscaler发出需要额外pod数量的信号。
当autoscaler检测到Revision的可用Pod数量低于请求的数量时,它会从 Kubernetes 请求增加 Pod 的数量。
当这些新的 Pod 准备就绪或现有的 Pod 有容量时,activator会将延迟的请求转发到就绪的 Pod。如果需要启动一个新的 Pod 来处理请求,这称为冷启动。

高流量请求流程

当Revision具有大量流量(备用容量大于target-burst-capacity)时,直接使用Revision的 pod 地址对ingress路由器进行编程,并将activator从流量中删除。当不需要activator的额外缓冲时,这可以减少延迟并提高效率。在所有情况下,队列代理都会保留在请求路径中。
如果流量低于突发容量阈值(计算方式为:current_demand + target-burst-capacity > (pods * concurrency-target)),则ingress路由器将被重新编程以将流量发送到activator Pods。
通过将activator 端点的子集写入Revision服务的端点来完成ingress 和activator 之间的路由流量。与 Revision 对应的 Kubernetes Service 是 selectorless服务,并且可能包含 Revision 的 pod 端点或activator端点。使用selectorless服务的原因如下:
1. 某些ingress实现不允许跨namespace服务引用。activator在knative-serving 命称空间中运行。
2. 某些ingress实现无法无缝处理路由端点的支持 Kubernetes 服务的更改。
3. 通过在每个Revision的基础上使用子集化,传入的请求被集中到少量的activator,这些activator可以更有效地做出就绪/未就绪的容量决策。每个Revision的有效activator数量较少并不是一个扩展问题,因为当Revision扩大以接收更多流量时,activator将从请求路径中删除。

Queue-Proxy

Knative Serving会为每个Pod注入一个称为Queue Proxy的容器
1. 为业务代码提供代理功能
  1. Ingress GW接收到请求后,将其发往目标Pod实例上由Queue Proxy监听的8012端口
  2. 而后,Queue Proxy再将请求转发给业务代码容器监听的端口
3. 报告实例上的多个有关客户端请求的关键指标为给Autoscaler
4. Pod健康状态检测(Kubernetes探针,每秒最多探测一次)
5. 为超出实例最大并发量的请求提供缓冲队列
Queue Proxy预留使用了如下几个端口
1. 8012:HTTP协议的代理端口
2. 8013:HTTP/2端口,用于代理gRPC
3. 8022:管理端口,如健康状态检测等
4. 9090:暴露给Autoscaler进行指标采集的端口
5. 9091:暴露给Prometheus进行监控指标采集的端口

Knative Serving Revision

Revision 介绍

Revision是 Knative Serving 资源,其中包含对 Knative 服务所做的每个更改的应用程序代码和配置的时间点快照。

您不能直接创建Revision或更新Revision规范。Knative Service上的spec.template的每次变动,都会自动生成一个新的Revision。但是,您可以强制删除Revision,以处理泄漏的资源以及删除已知的错误Revision,以避免将来在管理 Knative 服务时出现错误。

Revision通常是不可变的,除非它们可能引用可变的 Kubernetes 核心资源,例如 ConfigMap 和 Secret。Revision也可以通过Revision默认值的更改而发生变化。对默认值的更改通常是语法上的,而不是语义上的。

Revision 管理员配置

如果您拥有 Knative 安装的集群管理员权限,则可以修改 ConfigMap 以更改集群上 Knative 服务Revision的全局默认配置选项。

Revision 垃圾收集配置

当 Knative 服务的Revision处于非活动状态时,它们会在设定的时间段后自动清理并回收集群资源。这称为垃圾收集。
retain-since-create-time 自创建Revision以来在考虑对Revision进行垃圾回收之前必须经过的时间。
retain-since-last-active-time 自Revision最后一次处于活动状态以来在Revision被考虑进行垃圾回收之前必须经过的时间。
min-non-active-revisions 要保留的非活动Revision的最小数量。
max-non-active-revisions 要保留的非活动Revision的最大数量。
如果修订属于以下任一类别,则始终保留:

> 该Revision处于活动状态并且正在被Route引用。
> Revision是在设置指定retain-since-create-time的时间内创建的。
> 在最后设置指定retain-since-last-active-time的时间内Route引用了Revision 。
> 现有Revision的数量少于设置指定min-non-active-revisions的数量。

Revision 示例

立即清理任何不活动的Revision
apiVersion: v1
kind: ConfigMap
metadata:
  name: config-gc
  namespace: knative-serving
data:
  min-non-active-revisions: "0"
  max-non-active-revisions: "0"
  retain-since-create-time: "disabled"
  retain-since-last-active-time: "disabled"
...
保留最后十个非活动Revision
apiVersion: v1
kind: ConfigMap
metadata:
  name: config-gc
  namespace: knative-serving
data:
  retain-since-create-time: "disabled"
  retain-since-last-active-time: "disabled"
  max-non-active-revisions: "10"
...
禁用集群上的gc
apiVersion: v1
kind: ConfigMap
metadata:
  name: config-gc
  namespace: knative-serving
data:
  retain-since-create-time: "disabled"
  retain-since-last-active-time: "disabled"
  max-non-active-revisions: "disabled"
...

Revision 开发者配置

虽然在不修改 Knative 服务配置的情况下无法手动创建修订版,但您可以修改现有修订版的规范来更改其行为。

禁用Revision的gc

apiVersion: serving.knative.dev/v1
kind: Revision
metadata:
  annotations:
    serving.knative.dev/no-gc: "true"
...

Knative Serving API

API 群组

# kubectl api-versions |grep knative
autoscaling.internal.knative.dev/v1alpha1
caching.internal.knative.dev/v1alpha1
networking.internal.knative.dev/v1alpha1
serving.knative.dev/v1
serving.knative.dev/v1alpha1
serving.knative.dev/v1beta1

serving.knative.dev 群组

# kubectl api-resources --api-group=serving.knative.dev
NAME             SHORTNAMES      APIVERSION                    NAMESPACED   KIND
configurations   config,cfg      serving.knative.dev/v1        true         Configuration
domainmappings   dm              serving.knative.dev/v1beta1   true         DomainMapping
revisions        rev             serving.knative.dev/v1        true         Revision
routes           rt              serving.knative.dev/v1        true         Route
services         kservice,ksvc   serving.knative.dev/v1        true         Service

autoscaling.internal.knative.dev 群组

# kubectl api-resources --api-group=autoscaling.internal.knative.dev
NAME             SHORTNAMES   APIVERSION                                  NAMESPACED   KIND
metrics                       autoscaling.internal.knative.dev/v1alpha1   true         Metric
podautoscalers   kpa,pa       autoscaling.internal.knative.dev/v1alpha1   true         PodAutoscaler

networking.internal.knative.dev 群组

# kubectl api-resources --api-group=networking.internal.knative.dev
NAME                  SHORTNAMES      APIVERSION                                 NAMESPACED   KIND
certificates          kcert           networking.internal.knative.dev/v1alpha1   true         Certificate
clusterdomainclaims   cdc             networking.internal.knative.dev/v1alpha1   false        ClusterDomainClaim
ingresses             kingress,king   networking.internal.knative.dev/v1alpha1   true         Ingress
serverlessservices    sks             networking.internal.knative.dev/v1alpha1   true         ServerlessService

caching.internal.knative.dev 群组

# kubectl api-resources --api-group=caching.internal.knative.dev
NAME     SHORTNAMES   APIVERSION                              NAMESPACED   KIND
images                caching.internal.knative.dev/v1alpha1   true         Image

Knative Serving 运行应用说明 

在Serving上,可通过创建Knative Service对象来运行应用;该Service资源会自动创建一个Configuration对象和一个Route对象。
一个Configuration对象,它会创建一个Revision,并由该Revision自动创建一个Deployment对象和一个PodAutoscaler对象
一个Route对象,它会创建一个Kubernetes Service对象和一组Istio VirtualService对象 {kservice-name}-ingress {kservice-name}-mesh

Knative Service 资源规范

Knative Service资源(简称kservice或ksvc)的资源规范主要有两个字段
  template:用于创建或更新Configuration,任何更新,都将创建新的Revision对象
  traffic:用于创建或更新Route对象

查看 ksvc 资源规范

# kubectl explain ksvc
KIND:     Service
VERSION:  serving.knative.dev/v1

DESCRIPTION:
     Service acts as a top-level container that manages a Route and
     Configuration which implement a network service. Service exists to provide
     a singular abstraction which can be access controlled, reasoned about, and
     which encapsulates software lifecycle decisions such as rollout policy and
     team resource ownership. Service acts only as an orchestrator of the
     underlying Routes and Configurations (much as a kubernetes Deployment
     orchestrates ReplicaSets), and its usage is optional but recommended. The
     Service's controller will track the statuses of its owned Configuration and
     Route, reflecting their statuses and conditions as its own. See also:
     https://github.com/knative/serving/blob/main/docs/spec/overview.md#service

FIELDS:
   apiVersion	<string>
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

   kind	<string>
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

   metadata	<Object>
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

   spec	<Object>
     ServiceSpec represents the configuration for the Service object. A
     Service's specification is the union of the specifications for a Route and
     Configuration. The Service restricts what can be expressed in these fields,
     e.g. the Route must reference the provided Configuration; however, these
     limitations also enable friendlier defaulting, e.g. Route never needs a
     Configuration name, and may be defaulted to the appropriate "run latest"
     spec.

   status	<Object>
     ServiceStatus represents the Status stanza of the Service resource.

参考文档

https://knative.dev/docs/serving/