天天看點

開源 serverless 産品原理剖析(一) - Kubeless背景Kubeless 簡介原理剖析總結

背景

Serverless 架構的出現讓開發者不用過多地考慮傳統的伺服器采購、硬體運維、網絡拓撲、資源擴容等問題,可以将更多的精力放在業務的拓展和創新上。

随着 serverless 概念的深入人心,各大雲計算廠商紛紛推出了各自的 serverless 産品,其中比較有代表性的有

AWS lambda

Azure Function Google Cloud Functions 阿裡雲函數計算

等。

另外,CNCF 也于 2016 年創立了

Serverless Working Group

,它緻力于 cloud native 和 serverless 技術的結合。下圖是 CNCF serverless 全景圖,它将這些産品分成了工具型、安全型、架構型和平台型等類别。

開源 serverless 産品原理剖析(一) - Kubeless背景Kubeless 簡介原理剖析總結

同時,容器以及容器編排工具的出現,大大降低了 serverless 産品的開發成本,促進了一大批優秀開源 serverless 産品的誕生,它們大多建構于

kubernetes

之上,如下圖所示。

開源 serverless 産品原理剖析(一) - Kubeless背景Kubeless 簡介原理剖析總結

Kubeless 簡介

本文将要介紹的 kubeless 便是這些開源 serverless 産品的典型代表。根據官方的定義,kubeless 是 kubernetes native 的無服務計算架構,它可以讓使用者在 kubernetes 之上使用 FaaS 建構進階應用程式。從 CNCF 視角,kubeless 屬于平台型産品。

Kubless 有三個核心概念:

  1. Functions - 代表需要被執行的使用者代碼,同時包含運作時依賴、建構指令等資訊;
  2. Triggers - 代表和函數關聯的事件源。如果把事件源比作生産者,函數比作執行者,那麼觸發器就是聯系兩者的橋梁;
  3. Runtime - 代表函數運作時所依賴的環境。

原理剖析

本章節将以 kubeless 為例介紹 serverless 産品需要具備的基本能力,以及 kubeless 是如何利用 K8s 現有功能來實作它們的。這些基本能力包括:

  1. 靈活建構 - 能夠基于使用者送出的源碼迅速建構可執行的函數,簡化部署流程;
  2. 靈活觸發 - 能夠友善地基于各類事件觸發函數的執行,并能友善快捷地內建新的事件源;
  3. 自動伸縮 - 能夠根據業務需求,自動完成擴容縮容,無須人工幹預。

本文所作的調研基于

kubeless v1.0.0

k8s 1.13

靈活建構

CNCF 對函數生命周期的定義如下圖所示。使用者隻需提供源碼和函數說明,建構部署等工作通常由 serverless 平台完成。 是以,基于使用者送出的源碼迅速建構可執行函數是 serverless 産品必須具備的基礎能力。

開源 serverless 産品原理剖析(一) - Kubeless背景Kubeless 簡介原理剖析總結

在 kubeless 裡,建立函數非常簡單:

kubeless function deploy hello --runtime python2.7 \
                                --from-file test.py \
                                --handler test.hello           

該指令各參數含義如下:

  1. hello

    :将要部署的函數名稱;
  2. --runtime python2.7

    : 指定使用 python 2.7 作為運作環境。Kubeless 可供選擇的運作環境請參考連結 runtimes
  3. --from-file test.py

    :指定函數源碼檔案(支援 zip 格式)。
  4. --handler test.hello

    :指定使用 test.py 中的 hello 方法處理請求。

函數資源與 K8s Operator

Kubeless 函數是一個自定義 K8s 對象,本質上是

k8s operator

。k8s operator 原理如下圖所示:

開源 serverless 産品原理剖析(一) - Kubeless背景Kubeless 簡介原理剖析總結

下面以 kubeless 函數為例,描述 K8s operator 的一般工作流程:

  1. 使用 k8s 的 CustomResourceDefinition(CRD) 定義資源,這裡建立了一個名為

    functions.kubeless.io

    的 CRD 來代表 kubeless 函數;
  2. 建立一個 controller 監聽自定義資源的 ADD、UPDATE、DELETE 事件并綁定 hander。這裡建立了一個名為

    function-controller

    的 CRD controller,該 controller 會監聽針對 function 的 ADD、UPDATE、DELETE 事件,并綁定 handler(參閱 AddEventHandler );
  3. 使用者執行建立、更新、删除自定義資源的指令;
  4. Controller 根據監聽到的事件調用相應的 handler。

除了函數外,下文将要介紹的 trigger 也是一個 k8s operator。

函數構成

Kubeless 的

function-controller

監聽到針對 function 的 ADD 事件後,會觸發相應 handler 建立函數。一個函數由若幹 K8s 對象組成,包括 ConfigMap、Service、Deployment、Pod 等,其結構如下圖所示:

開源 serverless 産品原理剖析(一) - Kubeless背景Kubeless 簡介原理剖析總結

ConfigMap

函數中的 ConfigMap 用于描述函數源碼和依賴。

apiVersion: v1
data:
  handler: test.hello
  # 函數依賴的第三方 python 庫
  requirements.txt: |
    kubernetes==2.0.0
  # 函數源碼
  test.py: |
    def hello(event, context):
      print event
      return event['data']
kind: ConfigMap
metadata:
  labels:
    created-by: kubeless
    function: hello
  # 該 ConfigMap 名稱
  name: hello
  namespace: default
...           

Service

函數中的 Service 用于描述該函數的通路方式。該 Service 會與執行 function 邏輯的 Pods 相關聯,類型是 ClusterIP。

apiVersion: v1
kind: Service
metadata:
  labels:
    created-by: kubeless
    function: hello
  # 該 Service 名稱
  name: hello
  namespace: default
  ...
spec:
  clusterIP: 10.109.2.217
  ports:
  - name: http-function-port
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    created-by: kubeless
    function: hello
  # Service 類型
  type: ClusterIP
...           

Deployment

函數中的 Deployment 用于編排執行函數邏輯的 Pods,通過它可以描述函數期望的個數。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    created-by: kubeless
    function: hello
  name: hello
  namespace: default
  ...
spec:
  # 指定函數期望的個數
  replicas: 1
...           

Pod

函數中的 Pod 包含真正執行函數邏輯的容器。

Volumes

Pod 中的 volumes 段指定了該函數的 ConfigMap。這會将 ConfigMap 中的源碼和依賴添加到 volumeMounts.mountPath 指定的目錄裡面。從容器視角來看,檔案路徑為

/src/test.py

/src/requirements

...
  volumeMounts:
  - mountPath: /kubeless
    name: hello
  - mountPath: /src
    name: hello-deps
volumes:
- emptyDir: {}
  name: hello
- configMap:
    defaultMode: 420
    name: hello
...           
Init Container

Pod 中的 Init Container 主要作用如下:

  1. 将源碼和依賴檔案拷貝到指定目錄;
  2. 安裝第三方依賴。
Func Container

Pod 中的 Func Container 會加載 Init Container 準備好的源碼和依賴并執行函數。不同 runtime 加載代碼的方式大同小異,可參考

kubeless.py

Handler.java

小結

  1. Kubeless 通過綜合運用 K8s 中的多種元件以及利用各語言的動态加載能力實作了從使用者源碼到可執行的函數的建構邏輯;
  2. 考慮了函數運作的安全性,通過 Security Context 機制限制容器中的程序以非 root 身份運作。

靈活觸發

一款成熟的 serverless 産品需要具備靈活觸發能力,以滿足事件源的多樣性需求,同時需要能夠友善快捷地接入新事件源。CNCF 将函數的觸發方式分成了如下圖所示的幾種類别,關于它們的詳細介紹可參考連結

Function Invocation Types
開源 serverless 産品原理剖析(一) - Kubeless背景Kubeless 簡介原理剖析總結

對于 kubeless 的函數,最簡單的觸發方式是使用 kubeless CLI,另外還支援通過各種觸發器。下表展示了 kubeless 函數目前支援的觸發方式以及它們所屬的類别。

觸發方式 類别
kubeless CLI Synchronous Req/Rep
Http Trigger
Cronjob Trigger Job (Master/Worker)
Kafka Trigger Async Message Queue
Nats Trigger
Kinesis Trigger Message Stream

下圖展示了 kubeless 函數部分觸發方式的原理:

開源 serverless 産品原理剖析(一) - Kubeless背景Kubeless 簡介原理剖析總結

HTTP trigger

如果希望通過發送 HTTP 請求觸發函數執行,需要為函數建立 HTTP 觸發器。 Kubeless 利用

K8s ingress

機制實作了 http trigger。Kubeless 建立了一個名為

httptriggers.kubeless.io

的 CRD 來代表 http trigger 對象。同時,kubeless 包含一個名為

http-trigger-controller

的 CRD controller,它會持續監聽針對 http trigger 和 function 的 ADD、UPDATE、DELETE 事件,并執行對應的操作。

以下指令将為函數 hello 建立一個名為

http-hello

的 http trigger,并指定選用 nginx 作為 gateway。

kubeless trigger http create http-hello --function-name hello --gateway nginx --path echo --hostname example.com           

該指令會建立如下 ingress 對象,可以參考

CreateIngress

深入了解 ingress 的建立邏輯。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  # 該 Ingress 的名字,即建立 http trigger 時指定的 name
  name: http-hello
  ...
spec:
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          # 指向 kubeless 為函數 hello 建立的 ClusterIP 類型的 Service
          serviceName: hello
          servicePort: 8080
        path: /echo           

Ingress 隻是用于描述路由規則,要讓規則生效、實作請求轉發,叢集中需要有一個正在運作的 ingress controller。可供選擇的 ingress controller 有

Contour F5 BIG-IP Controller for Kubernetes Kong Ingress Controllerfor Kubernetes NGINX Ingress Controller for Kubernetes Traefik

等。這種路由規則描述和路由功能實作相分離的思想很好地提現了 K8s 始終堅持的需求和供給分離的設計理念。

上文中的指令在建立 trigger 時指定了 nginx 作為 gateway,是以需要部署一個

nginx-ingress-controller

。該 controller 的基本工作原理如下:

  1. 以 pod 的形式運作在獨立的命名空間中;
  2. 以 hostPort 的形式暴露出來供外界通路;
  3. 内部運作着一個 nginx 執行個體;
  4. 監聽和 ingress、service 等資源相關的事件。如果發現這些事件最終會影響到路由規則,ingress controller 會采用向 Lua hander 發送新的 endpoints 清單或者直接修改 nginx.conf 并 reload nginx 等手段達到更新路由規則的目的。

想要更深入地了解 nginx-ingress-controller 的工作原理可參考文章

how-it-works

完成上述工作後,我們便可以通過發送 HTTP 請求觸發函數 hello 的執行:

  1. HTTP 請求首先會由 nginx-ingress-controller 中的 nginx 處理;
  2. Nginx 根據 nginx.conf 中的路由規則将請求轉發給函數對應的 service;
  3. 最後,請求會轉發至挂載在 service 後的某個函數進行處理。

樣例如下:

curl --data '{"Another": "Echo"}' \
  --header "Host: example.com" \
  --header "Content-Type:application/json" \
  example.com/echo

# 函數傳回
{"Another": "Echo"}           

Cronjob trigger

如果希望定期觸發函數執行,需要為函數建立 cronjob 觸發器。K8s 支援通過

CronJob

定期運作任務,kubeless 利用這個特性實作了 cronjob trigger。Kubeless 建立了一個名為

cronjobtriggers.kubeless.io

的 CRD 來代表 cronjob trigger 對象。同時,kubeless 包含一個名為

cronjob-trigger-controller

的 CRD controller,它會持續監聽針對 cronjob trigger 和 function 的 ADD、UPDATE、DELETE 事件,并執行對應的操作。

scheduled-invoke-hello

的 cronjob trigger,該觸發器每分鐘會觸發函數 hello 執行一次。

kubeless trigger cronjob create scheduled-invoke-hello --function=hello --schedule="*/1 * * * *"           

該指令會建立如下 CronJob 對象,可以參考

EnsureCronJob

深入了解 CronJob 的建立邏輯。

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  # 該 CronJob 的名字,即建立 cronjob trigger 時指定的 name
  name: scheduled-invoke-hello
  ...
spec:
  # 該 CronJob 的執行計劃,即建立 cronjob trigger 時指定的 schedule
  schedule: */1 * * * *
  ...
  jobTemplate:
    spec:
      activeDeadlineSeconds: 180
      template:
        spec:
          containers:
          - args:
            - curl
            - -Lv
            # HTTP headers,包含 event-id、event-time、event-type、event-namespace 等資訊
            - ' -H "event-id: xxx" -H "event-time: yyy" -H "event-type: application/json" -H "event-namespace: cronjobtrigger.kubeless.io"'
            # kubeless 會為 function 建立一個 ClusterIP 類型的 Service
            # 可以根據 service 的 name、namespace 拼出 endpoint
            - http://hello.default.svc.cluster.local:8080
            image: kubeless/unzip
            name: trigger
          restartPolicy: Never
  ...           

自定義 trigger

如果發現 kubeless 預設提供的觸發器無法滿足業務需求,可以自定義新的觸發器。新觸發器的建構流程如下:

  1. 為新的事件源建立一個 CRD 來描述事件源觸發器;
  2. 在自定義資源對象的 spec 裡描述該事件源的屬性,例如 KafkaTriggerSpec HTTPTriggerSpec
  3. 為該 CRD 建立一個 CRD controller。
    1. 該 controller 需要持續監聽針對事件源觸發器和 function 的 CRUD 操作并作出正确的處理。例如,controller 監聽到 function 的删除事件,需要把和該 function 關聯的觸發器一并删掉;
    2. 當事件發生時,觸發關聯函數的執行。

我們可以看到,自定義 trigger 的流程遵循了

K8s Operator

設計模式。

  1. Kubeless 提供了一些基本常用的觸發器,如果有其他事件源也可以通過自定義觸發器接入;
  2. 不同僚件源的接入方式不同,但最終都是通過通路函數 ClusterIP 類型的 service 觸發函數執行。

自動伸縮

K8s 通過

Horizontal Pod Autoscaler

實作 pod 的自動水準伸縮。Kubeless 的 function 通過 K8s deployment 部署運作,是以天然可以利用 HPA 實作自動伸縮。

度量資料擷取

自動伸縮的第一步是要讓 HPA 能夠擷取度量資料。目前,kubeless 中的函數支援基于 cpu 和 qps 這兩種名額進行自動伸縮。下圖展示了 HPA 擷取這兩種度量資料的途徑。

開源 serverless 産品原理剖析(一) - Kubeless背景Kubeless 簡介原理剖析總結

内置度量名額 cpu

CPU 使用率屬于内置度量名額,對于這類名額 HPA 可以通過 metrics API 從

Metrics Server

中擷取資料。Metrics Server 是

Heapster

的繼承者,它可以通過

kubernetes.summary_api

從 Kubelet、cAdvisor 中擷取度量資料。

自定義度量名額 qps

QPS 屬于自定義度量名額,想要擷取這類名額的度量資料需要完成下列步驟。

  1. 部署用于存儲度量資料的系統,這裡選擇已經被納入 CNCF 的 Prometheus 。Prometheus 是一套開源監控&告警&時序資料解決方案,并且被 DigitalOcean、Red Hat、SUSE 和 Weaveworks 這些 cloud native 上司者廣泛使用;
  2. 采集度量資料,并寫入部署好的 Prometheus 中。Kubeless 提供的函數架構會在函數每次被調用時,将下列度量資料 function_duration_seconds、function_calls_total、function_failures_total 寫入 Prometheus(可參考 python 樣例 )。
  3. 部署實作了 custom metrics API 的 custom API server。這裡,因為度量資料被存入了 Prometheus,是以選擇部署 k8s-prometheus-adapter ,它可以從 Prometheus 中擷取度量資料。

完成上述步驟後,HPA 就可以通過 custom metrics API 從 Prometheus Adapter 中擷取 qps 度量資料。詳細配置步驟可參考文章

kubeless-autoscaling

K8s 度量名額簡介

有時基于 cpu 和 qps 這兩種度量名額對函數進行自動伸縮還遠遠不夠。如果希望基于其它度量名額,需要了解 K8s 定義的度量名額類型及其擷取方式。

目前,K8s 1.13 版本支援的度量名額類型如下:

類型 簡介 擷取方式
Object 代表 k8s 對象的度量名額,例如上文提到的 Service 對象的 function_calls 名額。 custom.metrics.k8s.io 度量資料采集後,需要通過已有擴充卡或自己實作擴充卡擷取資料。目前已有的擴充卡包括 azure-k8s-metrics-adapter k8s-stackdriver
代表伸縮目标中每個 pod 的自定義度量名額,例如 pod 每秒處理的事務數。在與目标值比較前需要除以 pod 個數。 同上
Resource 代表伸縮目标中每個 pod 的 K8s 内置資源名額(如 CPU、Memory)。在與目标值比較前需要除以 pod 個數。 metrics.k8s.io 從 Metrics Server 或 Heapster 中擷取度量資料。
External External 是一個全局度量名額,它與任何 K8s 對象無關。它允許伸縮目标基于來自 cluster 外部的資訊進行伸縮(如外部負載均衡器的 QPS,雲消息服務中的隊列長度)。 external.metrics.k8s.io 度量資料采集後,需要雲平台廠商提供擴充卡或自己實作。目前已有的擴充卡包括

準備好相應的度量資料和擷取資料的元件,HPA 就能基于它們對函數進行自動伸縮。更多關于 K8s 度量名額的介紹可參考文章

hpa-external-metrics

度量資料使用

知道了 HPA 擷取度量資料的途徑後,下面描述 HPA 如何基于這些資料對函數進行自動伸縮。

基于 cpu 使用率

假設已經存在一個名為 hello 的函數,以下指令将為該函數建立一個基于 cpu 使用率的 HPA,它将運作該函數的 pod 數量控制在 1 到 3 之間,并通過增加或減少 pod 個數使得所有 pod 的平均 cpu 使用率維持在 70%。

kubeless autoscale create hello --metric=cpu --min=1 --max=3 --value=70           

Kubeless 使用的是

autoscaling/v2alpha1

版本的 HPA API,該指令将要建立的 HPA 如下:

kind: HorizontalPodAutoscaler
apiVersion: autoscaling/v2alpha1
metadata:
  name: hello
  namespace: default
  labels:
    created-by: kubeless
    function: hello
spec:
  scaleTargetRef:
    kind: Deployment
    name: hello
  minReplicas: 1
  maxReplicas: 3
  metrics:
  - type: Resource
    resource:
      name: cpu
      targetAverageUtilization: 70           

該 HPA 計算目标 pod 數量的公式如下:

TargetNumOfPods = ceil(sum(CurrentPodsCPUUtilization) / Target)           

基于 qps

以下指令将為函數 hello 建立一個基于 qps 的 HPA,它将運作該函數的 pod 數量控制在 1 到 5 之間,并通過增加或減少 pod 個數確定所有挂在服務 hello 後的 pod 每秒能處理的請求次數之和達到 2000。

kubeless autoscale create hello --metric=qps --min=1 --max=5 --value=2k           

該指令将要建立的 HPA 如下:

kind: HorizontalPodAutoscaler
apiVersion: autoscaling/v2alpha1
metadata:
  name: hello
  namespace: default
  labels:
    created-by: kubeless
    function: hello
spec:
  scaleTargetRef:
    kind: Deployment
    name: hello
  minReplicas: 1
  maxReplicas: 5
  metrics:
  - type: Object
    object:
      metricName: function_calls
      target:
        apiVersion: autoscaling/v2beta1
        kind: Service
        name: hello
      targetValue: 2k           

基于多項名額

如果計劃基于多項度量名額對函數進行自動伸縮,需要直接為運作 function 的 deployment 建立 HPA。

使用如下 yaml 檔案可以為函數 hello 建立一個名為

hello-cpu-and-memory

的 HPA,它将運作該函數的 pod 數量控制在 1 到 10 之間,并嘗試讓所有 pod 的平均 cpu 使用率維持在 50%,平均 memory 使用量維持在 200MB。對于多項度量名額,K8s 會計算出每項名額需要的 pod 數量,取其中的最大值作為最終的目标 pod 數量。

kind: HorizontalPodAutoscaler
apiVersion: autoscaling/v2alpha1
metadata:
  name: hello-cpu-and-memory
  namespace: default
  labels:
    created-by: kubeless
    function: hello
spec:
  scaleTargetRef:
    kind: Deployment
    name: hello
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      targetAverageUtilization: 50
  - type: Resource
    resource:
      name: memory
      targetAverageValue: 200Mi           

自動伸縮政策

一個理想的自動伸縮政策應當處理好下列場景:

  1. 當負載激增時,函數能迅速擴充以應對突發流量;
  2. 當負載下降時,函數能立即收縮以節省資源消耗;
  3. 具備抗噪聲幹擾能力,能夠精确計算出目标容量;
  4. 能夠避免自動伸縮過于頻繁造成系統抖動。

Kubeless 依賴的 HPA 充分考慮了上述情形,不斷改進和完善其使用的自動伸縮政策。下面以 K8s 1.13 版本為例描述該政策。如果想要更加深入地了解政策原理請參考連結

horizontal

HPA 每隔一段時間會根據擷取的度量資料同步一次和該 HPA 關聯的 RC / Deployment 中的 pod 個數,時間間隔通過 kube-controller-manager 的參數

--horizontal-pod-autoscaler-sync-period

指定,預設為 15s。在每一次同步過程中,HPA 需要經曆如下圖所示的計算流程。

開源 serverless 産品原理剖析(一) - Kubeless背景Kubeless 簡介原理剖析總結

計算目标副本數

分别計算 HPA 清單中每項名額需要的 pod 數量,記為 replicaCountProposal。選擇其中的最大值作為 metricDesiredReplicas。在計算每項名額的 replicaCountProposal 過程中會考慮下列因素:

  1. 允許目标路徑成本和實際路徑成本存在一定程度的誤差,如果在誤差範圍内直接使用 currentReplicas 作為 replicaCountProposal。這樣做是為了在可接受範圍内避免伸縮過于頻繁造成系統抖動,該誤內插補點可以通過 kube-controller-manager 的參數

    --horizontal-pod-autoscaler-tolerance

    指定,預設值是 0.1。
  2. 當一個 pod 剛剛啟動時,該 pod 反映的路徑成本往往不是很準确,HPA 會将這種 pod 視為 unready。在計算路徑成本時,HPA 會跳過處于 unready 狀态的 pod。這樣做是為了消除噪聲幹擾,可以通過 kube-controller-manager 的參數

    --horizontal-pod-autoscaler-cpu-initialization-period

    (預設為 5 分鐘)和

    --horizontal-pod-autoscaler-initial-readiness-delay

    (預設為 30 秒)調整 pod 被認為處于 unready 狀态的時間。

平滑目标副本數

将最近一段時間計算出的 metricDesiredReplicas 記錄下來,取其中的最大值作為 stabilizedRecommendation。這樣做是為了讓縮容過程變得平滑,消除度量資料異常波動造成的影響。該時間段可以通過參數

--horizontal-pod-autoscaler-downscale-stabilization-window

指定,預設為 5 分鐘。

規範目标副本數

  1. 限制 desiredReplicas 最大為 currentReplicas * scaleUpLimitFactor,這樣做是為了防止因 采集到了“虛假的”度量資料造成擴容過快。目前 scaleUpLimitFactor 無法通過參數設定,其值固定為 2。
  2. 限制 desiredReplicas 大于等于 hpaMinReplicas,小于等于 hpaMaxReplicas。

執行擴容縮容操作

如果通過上述步驟計算出的 desiredReplicas 不等于 currentReplicas,則“執行”擴容縮容操作。這裡所說的執行隻是将 desiredReplicas 指派給 RC / Deployment 中的 replicas,pod 的建立銷毀會由 kube-scheduler 和 worker node 上的 kubelet 異步完成的。

  1. Kubeless 提供的自動伸縮功能是對 K8s HPA 的簡單封裝,避免了将建立 HPA 的複雜細節直接暴露給使用者;
  2. Kubeless 目前不支援将函數執行個體個數縮容至 0,這是因為 kubeless 的自動伸縮功能直接依賴 HPA,而 HPA 允許的最小副本數是 1;
  3. Kubeless 目前提供的度量名額過少,功能過于簡單。如果使用者希望基于新的度量名額、綜合多項度量名額或者調整自動伸縮的效果,需要深入了解 HPA 的細節;
  4. 目前 HPA 的擴容縮容政策是基于既成事實被動地調整目标副本數,還無法根據曆史規律預測性地進行擴容縮容。

總結

Kubeless 基于 K8s 提供了較為完整的 serverless 解決方案,但和一些商業 serverless 産品還存在一定差距:

  1. Kubeless 并未在鏡像拉取、代碼下載下傳、容器啟動等方面做過多優化,導緻函數冷啟動時間過長;
  2. Kubeless 并未過多考慮多租戶的問題,如果希望多個使用者的函數運作在同一個叢集裡,還需要進行二次開發;
  3. Kubeless 不支援函數間的協調管理,無法像 AWS Step Functions 那樣自定義工作流。

繼續閱讀