日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

开源 serverless 产品原理剖析 - Kubeless

發(fā)布時間:2025/3/21 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 开源 serverless 产品原理剖析 - Kubeless 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

背景

Serverless 架構(gòu)的出現(xiàn)讓開發(fā)者不用過多地考慮傳統(tǒng)的服務(wù)器采購、硬件運維、網(wǎng)絡(luò)拓撲、資源擴容等問題,可以將更多的精力放在業(yè)務(wù)的拓展和創(chuàng)新上。

隨著 serverless 概念的深入人心,各大云計算廠商紛紛推出了各自的 serverless 產(chǎn)品,其中比較有代表性的有?AWS lambda、Azure Function、Google Cloud Functions、阿里云函數(shù)計算等。

另外,CNCF 也于 2016 年創(chuàng)立了?Serverless Working Group,它致力于 cloud native 和 serverless 技術(shù)的結(jié)合。下圖是 CNCF serverless 全景圖,它將這些產(chǎn)品分成了工具型、安全型、框架型和平臺型等類別。

同時,容器以及容器編排工具的出現(xiàn),大大降低了 serverless 產(chǎn)品的開發(fā)成本,促進了一大批優(yōu)秀開源 serverless 產(chǎn)品的誕生,它們大多構(gòu)建于?kubernetes?之上,如下圖所示。

Kubeless 簡介

本文將要介紹的 kubeless 便是這些開源 serverless 產(chǎn)品的典型代表。根據(jù)官方的定義,kubeless 是 kubernetes native 的無服務(wù)計算框架,它可以讓用戶在 kubernetes 之上使用 FaaS 構(gòu)建高級應(yīng)用程序。從 CNCF 視角,kubeless 屬于平臺型產(chǎn)品。

Kubless 有三個核心概念:

  • Functions - 代表需要被執(zhí)行的用戶代碼,同時包含運行時依賴、構(gòu)建指令等信息;
  • Triggers - 代表和函數(shù)關(guān)聯(lián)的事件源。如果把事件源比作生產(chǎn)者,函數(shù)比作執(zhí)行者,那么觸發(fā)器就是聯(lián)系兩者的橋梁;
  • Runtime - 代表函數(shù)運行時所依賴的環(huán)境。
  • 原理剖析

    本章節(jié)將以 kubeless 為例介紹 serverless 產(chǎn)品需要具備的基本能力,以及 kubeless 是如何利用 K8s 現(xiàn)有功能來實現(xiàn)它們的。這些基本能力包括:

  • 敏捷構(gòu)建 - 能夠基于用戶提交的源碼迅速構(gòu)建可執(zhí)行的函數(shù),簡化部署流程;
  • 靈活觸發(fā) - 能夠方便地基于各類事件觸發(fā)函數(shù)的執(zhí)行,并能方便快捷地集成新的事件源;
  • 自動伸縮 - 能夠根據(jù)業(yè)務(wù)需求,自動完成擴容縮容,無須人工干預(yù)。
  • 本文所做的調(diào)研基于kubeless v1.0.0和k8s 1.13。

    敏捷構(gòu)建

    CNCF 對函數(shù)生命周期的定義如下圖所示。用戶只需提供源碼和函數(shù)說明,構(gòu)建部署等工作通常由 serverless 平臺完成。 因此,基于用戶提交的源碼迅速構(gòu)建可執(zhí)行函數(shù)是 serverless 產(chǎn)品必須具備的基礎(chǔ)能力。

    在 kubeless 里,創(chuàng)建函數(shù)非常簡單:

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

    該命令各參數(shù)含義如下:

  • hello:將要部署的函數(shù)名稱;
  • --runtime python2.7: 指定使用 python 2.7 作為運行環(huán)境。Kubeless 可供選擇的運行環(huán)境請參考鏈接?runtimes。
  • --from-file test.py:指定函數(shù)源碼文件(支持 zip 格式)。
  • --handler test.hello:指定使用 test.py 中的 hello 方法處理請求。
  • 函數(shù)資源與 K8s Operator

    Kubeless 函數(shù)是一個自定義 K8s 對象,本質(zhì)上是?k8s operator。k8s operator 原理如下圖所示:

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

  • 使用 k8s 的?CustomResourceDefinition(CRD)?定義資源,這里創(chuàng)建了一個名為functions.kubeless.io的 CRD 來代表 kubeless 函數(shù);
  • 創(chuàng)建一個 controller 監(jiān)聽自定義資源的 ADD、UPDATE、DELETE 事件并綁定 hander。這里創(chuàng)建了一個名為function-controller的 CRD controller,該 controller 會監(jiān)聽針對 function 的 ADD、UPDATE、DELETE 事件,并綁定 handler(參閱?AddEventHandler);
  • 用戶執(zhí)行創(chuàng)建、更新、刪除自定義資源的命令;
  • Controller 根據(jù)監(jiān)聽到的事件調(diào)用相應(yīng)的 handler。
  • 除了函數(shù)外,下文將要介紹的 trigger 也是一個 k8s operator。

    函數(shù)構(gòu)成

    Kubeless 的?function-controller監(jiān)聽到針對 function 的 ADD 事件后,會觸發(fā)相應(yīng) handler 創(chuàng)建函數(shù)。一個函數(shù)由若干 K8s 對象組成,包括 ConfigMap、Service、Deployment、Pod 等,其結(jié)構(gòu)如下圖所示:

    ConfigMap

    函數(shù)中的 ConfigMap 用于描述函數(shù)源碼和依賴。

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

    Service

    函數(shù)中的 Service 用于描述該函數(shù)的訪問方式。該 Service 會與執(zhí)行 function 邏輯的 Pods 相關(guān)聯(lián),類型是 ClusterIP。

    apiVersion: v1 kind: Service metadata:labels:created-by: kubelessfunction: hello# 該 Service 名稱name: hellonamespace: default... spec:clusterIP: 10.109.2.217ports:- name: http-function-portport: 8080protocol: TCPtargetPort: 8080selector:created-by: kubelessfunction: hello# Service 類型type: ClusterIP ...

    Deployment

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

    apiVersion: extensions/v1beta1 kind: Deployment metadata:labels:created-by: kubelessfunction: helloname: hellonamespace: default... spec:# 指定函數(shù)期望的個數(shù)replicas: 1 ...

    Pod

    函數(shù)中的 Pod 包含真正執(zhí)行函數(shù)邏輯的容器。

    Volumes

    Pod 中的 volumes 段指定了該函數(shù)的 ConfigMap。這會將 ConfigMap 中的源碼和依賴添加到 volumeMounts.mountPath 指定的目錄里面。從容器視角來看,文件路徑為/src/test.py和?/src/requirements。

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

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

  • 將源碼和依賴文件拷貝到指定目錄;
  • 安裝第三方依賴。
  • Func Container

    Pod 中的 Func Container 會加載 Init Container 準備好的源碼和依賴并執(zhí)行函數(shù)。不同 runtime 加載代碼的方式大同小異,可參考?kubeless.py,Handler.java。

    小結(jié)

  • Kubeless 通過綜合運用 K8s 中的多種組件以及利用各語言的動態(tài)加載能力實現(xiàn)了從用戶源碼到可執(zhí)行的函數(shù)的構(gòu)建邏輯;
  • 考慮了函數(shù)運行的安全性,通過?Security Context?機制限制容器中的進程以非 root 身份運行。
  • 靈活觸發(fā)

    一款成熟的 serverless 產(chǎn)品需要具備靈活觸發(fā)能力,以滿足事件源的多樣性需求,同時需要能夠方便快捷地接入新事件源。CNCF 將函數(shù)的觸發(fā)方式分成了如下圖所示的幾種類別,關(guān)于它們的詳細介紹可參考鏈接?Function Invocation Types。

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

    觸發(fā)方式類別
    kubeless CLISynchronous Req/Rep
    Http TriggerSynchronous Req/Rep
    Cronjob TriggerJob (Master/Worker)
    Kafka TriggerAsync Message Queue
    Nats TriggerAsync Message Queue
    Kinesis TriggerMessage Stream

    下圖展示了 kubeless 函數(shù)部分觸發(fā)方式的原理:

    HTTP trigger

    如果希望通過發(fā)送 HTTP 請求觸發(fā)函數(shù)執(zhí)行,需要為函數(shù)創(chuàng)建 HTTP 觸發(fā)器。 Kubeless 利用?K8s ingress?機制實現(xiàn)了 http trigger。Kubeless 創(chuàng)建了一個名為httptriggers.kubeless.io的 CRD 來代表 http trigger 對象。同時,kubeless 包含一個名為http-trigger-controller的 CRD controller,它會持續(xù)監(jiān)聽針對 http trigger 和 function 的 ADD、UPDATE、DELETE 事件,并執(zhí)行對應(yīng)的操作。

    以下命令將為函數(shù) hello 創(chuàng)建一個名為http-hello的 http trigger,并指定選用 nginx 作為 gateway。

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

    該命令會創(chuàng)建如下 ingress 對象,可以參考?CreateIngress?深入了解 ingress 的創(chuàng)建邏輯。

    apiVersion: extensions/v1beta1 kind: Ingress metadata:# 該 Ingress 的名字,即創(chuàng)建 http trigger 時指定的 namename: http-hello... spec:rules:- host: example.comhttp:paths:- backend:# 指向 kubeless 為函數(shù) hello 創(chuàng)建的 ClusterIP 類型的 ServiceserviceName: helloservicePort: 8080path: /echo

    Ingress 只是用于描述路由規(guī)則,要讓規(guī)則生效、實現(xiàn)請求轉(zhuǎn)發(fā),集群中需要有一個正在運行的 ingress controller。可供選擇的 ingress controller 有?Contour、F5 BIG-IP Controller for Kubernetes、Kong Ingress Controllerfor Kubernetes、NGINX Ingress Controller for Kubernetes、Traefik?等。這種路由規(guī)則描述和路由功能實現(xiàn)相分離的思想很好地提現(xiàn)了 K8s 始終堅持的需求和供給分離的設(shè)計理念。

    上文中的命令在創(chuàng)建 trigger 時指定了 nginx 作為 gateway,因此需要部署一個?nginx-ingress-controller。該 controller 的基本工作原理如下:

  • 以 pod 的形式運行在獨立的命名空間中;
  • 以 hostPort 的形式暴露出來供外界訪問;
  • 內(nèi)部運行著一個 nginx 實例;
  • 監(jiān)聽和 ingress、service 等資源相關(guān)的事件。如果發(fā)現(xiàn)這些事件最終會影響到路由規(guī)則,ingress controller 會采用向 Lua hander 發(fā)送新的 endpoints 列表或者直接修改 nginx.conf 并 reload nginx 等手段達到更新路由規(guī)則的目的。
  • 想要更深入地了解 nginx-ingress-controller 的工作原理可參考文章?how-it-works。

    完成上述工作后,我們便可以通過發(fā)送 HTTP 請求觸發(fā)函數(shù) hello 的執(zhí)行:

  • HTTP 請求首先會由 nginx-ingress-controller 中的 nginx 處理;
  • Nginx 根據(jù) nginx.conf 中的路由規(guī)則將請求轉(zhuǎn)發(fā)給函數(shù)對應(yīng)的 service;
  • 最后,請求會轉(zhuǎn)發(fā)至掛載在 service 后的某個函數(shù)進行處理。
  • 樣例如下:

    curl --data '{"Another": "Echo"}' \--header "Host: example.com" \--header "Content-Type:application/json" \example.com/echo# 函數(shù)返回 {"Another": "Echo"}

    Cronjob trigger

    如果希望定期觸發(fā)函數(shù)執(zhí)行,需要為函數(shù)創(chuàng)建 cronjob 觸發(fā)器。K8s 支持通過?CronJob?定期運行任務(wù),kubeless 利用這個特性實現(xiàn)了 cronjob trigger。Kubeless 創(chuàng)建了一個名為cronjobtriggers.kubeless.io的 CRD 來代表 cronjob trigger 對象。同時,kubeless 包含一個名為cronjob-trigger-controller的 CRD controller,它會持續(xù)監(jiān)聽針對 cronjob trigger 和 function 的 ADD、UPDATE、DELETE 事件,并執(zhí)行對應(yīng)的操作。

    以下命令將為函數(shù) hello 創(chuàng)建一個名為scheduled-invoke-hello的 cronjob trigger,該觸發(fā)器每分鐘會觸發(fā)函數(shù) hello 執(zhí)行一次。

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

    該命令會創(chuàng)建如下 CronJob 對象,可以參考?EnsureCronJob?深入了解 CronJob 的創(chuàng)建邏輯。

    apiVersion: batch/v1beta1 kind: CronJob metadata:# 該 CronJob 的名字,即創(chuàng)建 cronjob trigger 時指定的 namename: scheduled-invoke-hello... spec:# 該 CronJob 的執(zhí)行計劃,即創(chuàng)建 cronjob trigger 時指定的 scheduleschedule: */1 * * * *...jobTemplate:spec:activeDeadlineSeconds: 180template: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 創(chuàng)建一個 ClusterIP 類型的 Service# 可以根據(jù) service 的 name、namespace 拼出 endpoint- http://hello.default.svc.cluster.local:8080image: kubeless/unzipname: triggerrestartPolicy: Never...

    自定義 trigger

    如果發(fā)現(xiàn) kubeless 默認提供的觸發(fā)器無法滿足業(yè)務(wù)需求,可以自定義新的觸發(fā)器。新觸發(fā)器的構(gòu)建流程如下:

  • 為新的事件源創(chuàng)建一個 CRD 來描述事件源觸發(fā)器;
  • 在自定義資源對象的 spec 里描述該事件源的屬性,例如?KafkaTriggerSpec、HTTPTriggerSpec;
  • 為該 CRD 創(chuàng)建一個 CRD controller。

  • 該 controller 需要持續(xù)監(jiān)聽針對事件源觸發(fā)器和 function 的 CRUD 操作并作出正確的處理。例如,controller 監(jiān)聽到 function 的刪除事件,需要把和該 function 關(guān)聯(lián)的觸發(fā)器一并刪掉;
  • 當事件發(fā)生時,觸發(fā)關(guān)聯(lián)函數(shù)的執(zhí)行。
  • 我們可以看到,自定義 trigger 的流程遵循了?K8s Operator?設(shè)計模式。

    小結(jié)

  • Kubeless 提供了一些基本常用的觸發(fā)器,如果有其他事件源也可以通過自定義觸發(fā)器接入;
  • 不同事件源的接入方式不同,但最終都是通過訪問函數(shù) ClusterIP 類型的 service 觸發(fā)函數(shù)執(zhí)行。
  • 自動伸縮

    K8s 通過?Horizontal Pod Autoscaler?實現(xiàn) pod 的自動水平伸縮。Kubeless 的 function 通過 K8s deployment 部署運行,因此天然可以利用 HPA 實現(xiàn)自動伸縮。

    度量數(shù)據(jù)獲取

    自動伸縮的第一步是要讓 HPA 能夠獲取度量數(shù)據(jù)。目前,kubeless 中的函數(shù)支持基于 cpu 和 qps 這兩種指標進行自動伸縮。下圖展示了 HPA 獲取這兩種度量數(shù)據(jù)的途徑。

    內(nèi)置度量指標 cpu

    CPU 使用率屬于內(nèi)置度量指標,對于這類指標 HPA 可以通過 metrics API 從?Metrics Server?中獲取數(shù)據(jù)。Metrics Server 是?Heapster?的繼承者,它可以通過kubernetes.summary_api從 Kubelet、cAdvisor 中獲取度量數(shù)據(jù)。

    自定義度量指標 qps

    QPS 屬于自定義度量指標,想要獲取這類指標的度量數(shù)據(jù)需要完成下列步驟。

  • 部署用于存儲度量數(shù)據(jù)的系統(tǒng),這里選擇已經(jīng)被納入 CNCF 的?Prometheus。Prometheus 是一套開源監(jiān)控&告警&時序數(shù)據(jù)解決方案,并且被 DigitalOcean、Red Hat、SUSE 和 Weaveworks 這些 cloud native 領(lǐng)導(dǎo)者廣泛使用;
  • 采集度量數(shù)據(jù),并寫入部署好的 Prometheus 中。Kubeless 提供的函數(shù)框架會在函數(shù)每次被調(diào)用時,將下列度量數(shù)據(jù) function_duration_seconds、function_calls_total、function_failures_total 寫入 Prometheus(可參考?python 樣例)。
  • 部署實現(xiàn)了 custom metrics API 的 custom API server。這里,因為度量數(shù)據(jù)被存入了 Prometheus,因此選擇部署?k8s-prometheus-adapter,它可以從 Prometheus 中獲取度量數(shù)據(jù)。
  • 完成上述步驟后,HPA 就可以通過 custom metrics API 從 Prometheus Adapter 中獲取 qps 度量數(shù)據(jù)。詳細配置步驟可參考文章?kubeless-autoscaling。

    K8s 度量指標簡介

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

    目前,K8s 1.13 版本支持的度量指標類型如下:

    準備好相應(yīng)的度量數(shù)據(jù)和獲取數(shù)據(jù)的組件,HPA 就能基于它們對函數(shù)進行自動伸縮。更多關(guān)于 K8s 度量指標的介紹可參考文章?hpa-external-metrics。

    度量數(shù)據(jù)使用

    知道了 HPA 獲取度量數(shù)據(jù)的途徑后,下面描述 HPA 如何基于這些數(shù)據(jù)對函數(shù)進行自動伸縮。

    基于 cpu 使用率

    假設(shè)已經(jīng)存在一個名為 hello 的函數(shù),以下命令將為該函數(shù)創(chuàng)建一個基于 cpu 使用率的 HPA,它將運行該函數(shù)的 pod 數(shù)量控制在 1 到 3 之間,并通過增加或減少 pod 個數(shù)使得所有 pod 的平均 cpu 使用率維持在 70%。

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

    Kubeless 使用的是?autoscaling/v2alpha1?版本的 HPA API,該命令將要創(chuàng)建的 HPA 如下:

    kind: HorizontalPodAutoscaler apiVersion: autoscaling/v2alpha1 metadata:name: hellonamespace: defaultlabels:created-by: kubelessfunction: hello spec:scaleTargetRef:kind: Deploymentname: hellominReplicas: 1maxReplicas: 3metrics:- type: Resourceresource:name: cputargetAverageUtilization: 70

    該 HPA 計算目標 pod 數(shù)量的公式如下:

    TargetNumOfPods = ceil(sum(CurrentPodsCPUUtilization) / Target)

    基于 qps

    以下命令將為函數(shù) hello 創(chuàng)建一個基于 qps 的 HPA,它將運行該函數(shù)的 pod 數(shù)量控制在 1 到 5 之間,并通過增加或減少 pod 個數(shù)確保所有掛在服務(wù) hello 后的 pod 每秒能處理的請求次數(shù)之和達到 2000。

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

    該命令將要創(chuàng)建的 HPA 如下:

    kind: HorizontalPodAutoscaler apiVersion: autoscaling/v2alpha1 metadata:name: hellonamespace: defaultlabels:created-by: kubelessfunction: hello spec:scaleTargetRef:kind: Deploymentname: hellominReplicas: 1maxReplicas: 5metrics:- type: Objectobject:metricName: function_callstarget:apiVersion: autoscaling/v2beta1kind: Servicename: hellotargetValue: 2k

    基于多項指標

    如果計劃基于多項度量指標對函數(shù)進行自動伸縮,需要直接為運行 function 的 deployment 創(chuàng)建 HPA。

    使用如下 yaml 文件可以為函數(shù) hello 創(chuàng)建一個名為hello-cpu-and-memory的 HPA,它將運行該函數(shù)的 pod 數(shù)量控制在 1 到 10 之間,并嘗試讓所有 pod 的平均 cpu 使用率維持在 50%,平均 memory 使用量維持在 200MB。對于多項度量指標,K8s 會計算出每項指標需要的 pod 數(shù)量,取其中的最大值作為最終的目標 pod 數(shù)量。

    kind: HorizontalPodAutoscaler apiVersion: autoscaling/v2alpha1 metadata:name: hello-cpu-and-memorynamespace: defaultlabels:created-by: kubelessfunction: hello spec:scaleTargetRef:kind: Deploymentname: hellominReplicas: 1maxReplicas: 10metrics:- type: Resourceresource:name: cputargetAverageUtilization: 50- type: Resourceresource:name: memorytargetAverageValue: 200Mi

    自動伸縮策略

    一個理想的自動伸縮策略應(yīng)當處理好下列場景:

  • 當負載激增時,函數(shù)能迅速擴展以應(yīng)對突發(fā)流量;
  • 當負載下降時,函數(shù)能立即收縮以節(jié)省資源消耗;
  • 具備抗噪聲干擾能力,能夠精確計算出目標容量;
  • 能夠避免自動伸縮過于頻繁造成系統(tǒng)抖動。
  • Kubeless 依賴的 HPA 充分考慮了上述情形,不斷改進和完善其使用的自動伸縮策略。下面以 K8s 1.13 版本為例描述該策略。如果想要更加深入地了解策略原理請參考鏈接?horizontal。

    HPA 每隔一段時間會根據(jù)獲取的度量數(shù)據(jù)同步一次和該 HPA 關(guān)聯(lián)的 RC / Deployment 中的 pod 個數(shù),時間間隔通過 kube-controller-manager 的參數(shù)--horizontal-pod-autoscaler-sync-period指定,默認為 15s。在每一次同步過程中,HPA 需要經(jīng)歷如下圖所示的計算流程。

    計算目標副本數(shù)

    分別計算 HPA 列表中每項指標需要的 pod 數(shù)量,記為 replicaCountProposal。選擇其中的最大值作為 metricDesiredReplicas。在計算每項指標的 replicaCountProposal 過程中會考慮下列因素:

  • 允許目標度量值和實際度量值存在一定程度的誤差,如果在誤差范圍內(nèi)直接使用 currentReplicas 作為 replicaCountProposal。這樣做是為了在可接受范圍內(nèi)避免伸縮過于頻繁造成系統(tǒng)抖動,該誤差值可以通過 kube-controller-manager 的參數(shù)--horizontal-pod-autoscaler-tolerance指定,默認值是 0.1。
  • 當一個 pod 剛剛啟動時,該 pod 反映的度量值往往不是很準確,HPA 會將這種 pod 視為 unready。在計算度量值時,HPA 會跳過處于 unready 狀態(tài)的 pod。這樣做是為了消除噪聲干擾,可以通過 kube-controller-manager 的參數(shù)--horizontal-pod-autoscaler-cpu-initialization-period(默認為 5 分鐘)和--horizontal-pod-autoscaler-initial-readiness-delay(默認為 30 秒)調(diào)整 pod 被認為處于 unready 狀態(tài)的時間。
  • 平滑目標副本數(shù)

    將最近一段時間計算出的 metricDesiredReplicas 記錄下來,取其中的最大值作為 stabilizedRecommendation。這樣做是為了讓縮容過程變得平滑,消除度量數(shù)據(jù)異常波動造成的影響。該時間段可以通過參數(shù)--horizontal-pod-autoscaler-downscale-stabilization-window指定,默認為 5 分鐘。

    規(guī)范目標副本數(shù)

  • 限制 desiredReplicas 最大為 currentReplicas * scaleUpLimitFactor,這樣做是為了防止因 采集到了“虛假的”度量數(shù)據(jù)造成擴容過快。目前 scaleUpLimitFactor 無法通過參數(shù)設(shè)定,其值固定為 2。
  • 限制 desiredReplicas 大于等于 hpaMinReplicas,小于等于 hpaMaxReplicas。
  • 執(zhí)行擴容縮容操作

    如果通過上述步驟計算出的 desiredReplicas 不等于 currentReplicas,則“執(zhí)行”擴容縮容操作。這里所說的執(zhí)行只是將 desiredReplicas 賦值給 RC / Deployment 中的 replicas,pod 的創(chuàng)建銷毀會由 kube-scheduler 和 worker node 上的 kubelet 異步完成的。

    小結(jié)

  • Kubeless 提供的自動伸縮功能是對 K8s HPA 的簡單封裝,避免了將創(chuàng)建 HPA 的復(fù)雜細節(jié)直接暴露給用戶。
  • Kubeless 目前提供的度量指標過少,功能過于簡單。如果用戶希望基于新的度量指標、綜合多項度量指標或者調(diào)整自動伸縮的效果,需要深入了解 HPA 的細節(jié)。
  • 目前 HPA 的擴容縮容策略是基于既成事實被動地調(diào)整目標副本數(shù),還無法根據(jù)歷史規(guī)律預(yù)測性地進行擴容縮容。
  • 總結(jié)

    Kubeless 基于 K8s 提供了較為完整的 serverless 解決方案,但和一些商業(yè) serverless 產(chǎn)品還存在一定差距:

  • Kubeless 并未在鏡像拉取、代碼下載、容器啟動等方面做過多優(yōu)化,導(dǎo)致函數(shù)冷啟動時間過長;
  • Kubeless 并未過多考慮多租戶的問題,如果希望多個用戶的函數(shù)運行在同一個集群里,還需要進行二次開發(fā)。


  • 本文作者:吳波bruce_wu

    閱讀原文

    本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。

    總結(jié)

    以上是生活随笔為你收集整理的开源 serverless 产品原理剖析 - Kubeless的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。