雲計算

開箱即用,Knative 給您極致的容器 Serverless 體驗

頭圖.png

作者 | 冬島  阿里巴巴技術專家

導讀:託管 Knative 開箱即用,您不需要為這些常駐實例付出任何成本。結合 SLB 雲產品提供 Gateway 的能力以及基於突發性能型實例的保留規格功能,極大的節省您的 IaaS 開支,您支付的每一分錢都沒有浪費。

<關注阿里巴巴雲原生公眾號,回覆 報告 即可下載完整調查報告>

CNCF 發佈的年度調查報告顯示 2019 年 Serverless 技術進一步獲得了更大的認可。其中 41% 的受訪者表示已經在使用 Serverless,另外 20% 的受訪者表示計劃在未來 12-18 個月內會採用 Serverless 技術。而在眾多開源的 Serverless 項目中 Knative 是最受歡迎的一個。如下圖所示, Knative 佔據了 34% 的份額,遙遙領先於第二名 OpenFaaS,Knative 是自己搭建 Serverless 平臺的首選。

1.png

Knative 之所以這麼受歡迎和容器的生態不無關係。和 FaaS 模式不同的是 Knative 不要求用戶對應用做非常大的改造,只要用戶的應用完成了容器化就能部署在 Knative 中。並且 Knative 在 Kubernetes 之上提供了更聚焦的應用模型,讓用戶無需為應用的升級、流量灰度花費精力,這一切都是自動完成的。

雲主機的發展歷程

在雲計算出現之前,企業想要在互聯網上對外提供服務需要先在 IDC 租賃物理機,然後再把應用部署在 IDC 的物理機上。而物理機的性能在過去十幾年裡始終保持著摩爾定律的速度在增長。這就導致單個應用根本無法充分利用整個物理機的資源。所以就需要有一種技術解決資源利用率的問題。簡單的想如果一個應用不夠就多部署幾個。但在同一個物理機下多個應用混合部署會帶來很多問題,比如:

  • 端口衝突
  • 資源隔離
  • 系統依賴以及運維困難

虛擬機的出現就很好的解決了上述問題,通過虛擬機技術可以在同一個物理機上虛擬出多個主機,每一個主機只部署一個應用,這樣一臺物理機不但可以部署多個應用,還能保證應用之間的獨立性。

隨著企業的發展,一家企業可能會維護很多應用。而每一個應用需要很多的發佈、升級、回滾等操作,同時這些應用可能還需要在不同的地域分別部署一套。這就帶來了很多運維負擔,這些運維難題首當其衝的就是應用的運行環境。所以後來出現了容器技術,容器技術通過內核級別的輕量級隔離能力不但具備與 VM 幾乎同等的隔離體驗,還帶來了一個巨大的創新就是容器鏡像。通過容器鏡像可以非常容易的複製應用的運行環境,開發人員只需要把應用的依賴都做到鏡像中,當鏡像運行的時候直接使用自帶的依賴提供服務。這就解決了應用發佈、升級和回滾以及多地域部署等過程中的運行環境問題。

當人們開始大規模使用容器技術之後發現大大減輕了維護實例運行環境的負擔,此時最大的問題就是應用多實例的協調以及多個應用之間的協調。所以容器技術普及不久 Kubernetes 就出現了,和以往的 VM、容器技術不同,Kubernetes 天然就是一個分佈式面向終態的設計,不是單機上的能力。Kubernetes 對 IaaS 的資源分配抽象了更友好的 API,用戶無需關心具體的分配細節,Kubernetes Controller 會根據面向終態的生命自動完成分配和故障轉移以及負載均衡等。這使得應用開發人員無需關心具體的實例是運行在哪裡,只要在需要的時候 Kubernetes 能夠分配出資源即可。

無論是早期的物理機模式,還是現在的 Kubernetes 模式,應用開發者本身其實並不想管理什麼底層資源,應用開發者只是想要把應用跑起來而已。在物理機模式中人們需要獨佔物理機,在 Kubernetes 模式中其實人們並不關心自己的業務進程是跑在哪個物理機上,事實上也無法提前預知。只要應用能夠跑起來就好,至於是在哪兒運行的其實已不重要。物理機 -> 虛擬機 -> 容器 -> Kubernetes ,整個過程其實都是在簡化應用使用 IaaS 資源的門檻。在這個演進過程可以發現一個清晰的脈絡,IaaS 和應用之間的耦合越來越低,基礎平臺只要做到在應用需要運行的時候給應用分配相應的 IaaS 資源即可,應用管理者只是 IaaS 的使用者,並不需要感知 IaaS 分配的細節

Knative Serving

在介紹 Knative 之前咱們先通過一個 web 應用看一下通過 Kubernetes 做流量接入、應用發佈和 Knative 做流量接入、應用發佈的差別。如下圖所示,在左側是 Kubernetes 模式,右側是 Knative 模式。

2.png

  • 在 Kubernetes 模式下:1. 用戶需要自己管理 Ingress Controller;2. 要對外暴露服務需要維護 Ingress 和 Service 的關係;3. 發佈時如果想要做灰度觀察需要使用多個 Deployment 輪轉才能完成升級;
  • 在 Knative 模式下:用戶只需要維護一個 Knative Service 資源即可。

當然 Knative 並不能完全替代 Kubernetes ,Knative 是建立在 Kubernetes 能力之上的。Kubernetes 和 Knative 除了用戶需要直接管理的資源不同,其實還有一個巨大的理念差異:

Kubernetes 的作用是解耦 IaaS 和應用,降低 IaaS 資源分配的成本,Kubernetes 主要聚焦於 IaaS 資源的編排。而 Knative 是更偏向應用層,是以彈性為核心的應用編排。

Knative 是一款基於 Kubernetes 的 Serverless 編排引擎,其目標是制定雲原生、跨平臺的 Serverless 編排標準。Knative 通過整合容器構建、工作負載管理(動態擴縮)以及事件模型這三者來實現的這一 Serverless 標準。Serving 正是運行 Serverless 工作負載的核心模塊。

3.png

  • 應用託管

    • Kubernetes 是面向 IaaS 管理的抽象,通過 Kubernetes 直接部署應用需要維護的資源比較多
    • 通過 Knative Service 一個資源就能定義應用的託管
  • 流量管理

    • Knative 通過 Gateway 結果應用流量,然後可以對流量按百分比進行分割,這為彈性、灰度等基礎能力做好了基礎
  • 灰度發佈

    • 支持多版本管理,應用同時有多個版本在線提供服務很容易實現
    • 不同版本可以設置不同的流量百分比,對灰度發佈等功能實現起來很容易
  • 彈性

    • Knative 幫助應用節省成本的核心能力是彈性,在流量增加的時候自動擴容,流量下降的時候自動縮容
    • 每一個灰度的版本都有自己的彈性策略,並且彈性策略和分配到當前版本的流量是相關聯的。Knative 會根據分配過來的流量多少進行擴容或者縮容的決策

Knative 更多介紹請移步這裡這裡瞭解更多。

為什麼是 ASK

社區的 Kubernetes 需要您提前購買主機並註冊成 Kubernetes 節點才能調度 Pod,提前購買主機這其實不符合應用的使用邏輯,應用開發人員只是想在需要運行應用實例的時候分配出 IaaS 資源即可,並不想維護繁雜的 IaaS 資源。所以如果存在一種 Kubernetes 和社區的 Kubernetes API 完全兼容,但是不需要自己運維管理複雜的 IaaS 資源,在需要的時候可以自動分配出資源,這更符合應用的對資源的使用理念。ASK 就是秉持這樣的理念給您帶來 Serverless Kubernetes 的使用體驗。

ASK 的全稱是 Serverless Kubernetes,是一種無服務器的 Kubernetes 集群,用戶無需購買節點即可直接部署容器應用,無需對集群進行節點維護和容量規劃,並且根據應用配置的 CPU 和內存資源量進行按需付費。ASK 集群提供完善的 Kubernetes 兼容能力,同時極大降低了 Kubernetes 使用門檻,讓用戶更專注於應用程序,而不是管理底層基礎設施。

4.png

也就是說您無需提前準備 ECS 資源,即可直接創建一個 Kubernetes 集群,然後就能部署自己的服務了。關於 ASK 更詳細的介紹參見這裡

前面分析 Serverless 歷程的時候咱們總結出來的 Serverless 發展主脈絡其實就是 IaaS 和應用之間的耦合越來越低,基礎平臺只要做到在應用需要運行的時候給應用分配相應的 IaaS 資源即可,應用管理者只是 IaaS 的使用者,並不需要感知 IaaS 分配的細節。ASK 就是這個隨時分配 IaaS 資源的平臺,Knative 負責感知應用的實時狀態,在需要的時候自動從 ASK 中“申請”IaaS 資源(Pod)。Knative 和 ASK 的結合可以給您帶來更極致的 Serverless 體驗。

關於 ASK 更深入的介紹請參見 《Serverless Kubernetes - 理想,現實與未來》

亮點介紹

基於 SLB 的 Gateway

Knative 社區默認支持 Istio、Gloo、Contour、Kourier 和 ambassador 等多種 Gateway 實現。在這些眾多的實現中 Istio 當然是最流行的一個,因為 Istio 除了可以充當 Gateway 的角色還能做 ServiceMesh 服務使用。這些 Gateway 雖然功能完備但是作為 Serverless 服務的 Gateway 就有點兒違背初衷。首先需要有 Gateway 實例常駐運行,而為了保證高可用至少要有兩個實例互為備份。其次這些 Gateway 的管控端也需要常駐運行,這些常駐實例的 IaaS 費用和運維都是業務需要支付的成本。

為了給用戶提供極致的 Serverless 體驗,我們通過阿里雲 SLB 實現了 Knative  Gateway,所有需要的功能都具備而且是雲產品級別的支撐。不需要常駐資源不但節省了您的 IaaS 成本還省去了很多運維負擔。

低成本的保留實例

保留實例是 ASK Knative 獨有的功能。社區的 Knative 默認在沒有流量的時候可以縮容到零,但是縮容到零之後從零到一的冷啟動問題很難解決。冷啟動除了要解決 IaaS 資源的分配、Kubernetes 的調度、拉鏡像等問題以外還涉及到應用的啟動時長。應用啟動時長從毫秒到分鐘級別都有,這在通用的平臺層面幾乎無法控制。當然這些問題在所有的 serverless 產品中都存在。傳統 FaaS 產品大多都是通過維護一個公共的 IaaS 池子運行不同的函數,為了保護這個池子不會被打滿、和極低的冷啟動時間,FaaS 產品的解法大多是對用戶的函數做各種限制。比如:

  • 處理請求的超時時間:如果超過這個時間沒起來就認為失敗;
  • 突增併發:默認所有函數都有一個併發上限,請求量超過這個上限就會被限流;
  • CPU 以及內存:不能超過 CPU 和內存的上限。

ASK Knative 對這個問題的解法是通過低價格的保留實例來平衡成本和冷啟動問題。阿里雲 ECI 有很多規格,不同規格的計算能力不一樣價格也不一樣。如下所示是對 2c4G 配置的計算型實例和突發性能型實例的價格對比。

5.png

通過上面的對比可知突發性能實例比計算型便宜 46%,可見如果在沒有流量的時候使用突發性能實例提供服務不單單解決了冷啟動的問題還能節省很多成本。

突發性能實例除了價格優勢以外還有一個非常亮眼的功能就是 CPU 積分。突發性能實例可以利用 CPU 積分應對突發性能需求。突發性能實例可以持續獲得 CPU 積分,在性能無法滿足負載要求時,可以通過消耗積累的 CPU 積分無縫提高計算性能,不會影響部署在實例上的環境和應用。通過 CPU 積分,您可以從整體業務角度分配計算資源,將業務平峰期剩餘的計算能力無縫轉移到高峰期使用(簡單的理解就是油電混動啦☺️☺️)。突發性能實例的更多細節參見這裡

所以 ASK Knative 的策略是在業務波谷時使用突發性能實例替換標準的計算型實例,當第一個請求來臨時再無縫切換到標準的計算型實例。這樣可以幫助您降低流量低谷的成本,並且在低谷時獲得的 CPU 積分還能在業務高峰到來時消費掉,您支付的每一分錢都沒有浪費。

使用突發性能實例作為保留實例只是默認策略,您可以指定自己期望的其他類型實例作為保留實例的規格。當然您也可以指定最小保留一個標準實例,從而關閉保留實例的功能。

Demo 展示

Serverless Kubernetes(ASK) 集群創建好以後可以通過以下釘釘群申請開通 Knative 功能。然後您就可以在 ASK 集群中直接使用 Knative 提供的能力了。

6.png

Knative 功能打開後會在 knative-serving namespace 中創建一個叫做 ingress-gateway 的 service,這是一個 loadbalance 類型的 service,會通過 ccm 自動創建一個 SLB 出來。如下所示 47.102.220.35 就是 SLB 的公網 IP,接下來就可以通過此公網 IP 訪問 Knative 服務了。

# kubectl -n knative-serving get svc
NAME              TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)        AGE
ingress-gateway   LoadBalancer   172.19.8.35   47.102.220.35   80:30695/TCP   26h

咱們後續的一系列操作就從一家咖啡店 (cafe) 開始談起。假設這家咖啡店有兩個品類:咖啡(coffee)和茶(tea)。咱們先部署 coffee 服務,然後再部署 tea 服務。同時還會包含版本升級、流量灰度、自定義 Ingress 以及自動彈性等特性的演示。

部署 coffee 服務

把如下內容保存到 coffee.yaml 文件中,然後通過 kubectl 部署到集群:

# cat coffee.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: coffee
spec:
  template:
    metadata:
      annotations:
        autoscaling.knative.dev/target: "10"
    spec:
      containers:
        - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/helloworld-go:160e4dc8
          env:
            - name: TARGET
              value: "coffee"

執行 kubectl apply -f coffee.yaml 部署 coffee 服務,稍等一會兒應該可以看到 coffee 服務已經部署好了。

# kubectl get ksvc
NAME     URL                                 LATESTCREATED   LATESTREADY    READY   REASON
coffee   http://coffee.default.example.com   coffee-fh85b    coffee-fh85b   True

上面這個命令的執行結果中 coffee.default.example.com 就是 Knative 為每一個 ksvc 生成的唯一子域名。現在通過 curl 命令指定 host 和前面的 SLB 公網 IP 就能訪問部署的這個服務了, 如下所示 Hello coffee! 就是 coffee 服務返回的內容。

# curl -H "Host: coffee.default.example.com" http://47.102.220.35
Hello coffee!

自動彈性

Autoscaler 是 Knative 的一等公民,這是 Knative 幫助用戶節省成本的核心能力。Knative 默認的 KPA 彈性策略可以根據實時的流量請求自動調整 Pod 的數量。現在咱們就來感受一下 Knative 的彈性能力,先看一下當前的 pod 信息:

# kubectl get pod
NAME                                       READY   STATUS    RESTARTS   AGE
coffee-bwl9z-deployment-765d98766b-nvwmw   2/2     Running   0          42s

可以看到現在有 1 個 pod 在運行,接下來開始準備壓測。在開始壓測之前咱們先回顧一下 coffee 應用的配置,前面的 yaml 中有一個這樣的配置, 如下所示,其中 autoscaling.knative.dev/target: "10" 意思就是每一個 Pod 的併發上限是 10 ,如果併發請求多餘 10 就應該擴容新的 Pod 接受請求。關於 Knative Autoscaler 更詳細的介紹請參見這裡

# cat coffee-v2.yaml
... ...
      name: coffee-v2
      annotations:
        autoscaling.knative.dev/target: "10"
    spec:
      containers:
        - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/helloworld-go:160e4dc8
... ...

好咱們現在開始壓測一下試試。使用 hey 命令發起壓測請求, hey 命令下載鏈接:

hey -z 30s -c 90 --host "coffee.default.example.com" "http://47.100.6.39/?sleep=100"

上面這條命令的含義:

  • -z 30s 表示連續壓測 30 秒;
  • -c 90 表示使用 90 個併發請求發起壓測;
  • --host "coffee.default.example.com" 表示綁定 host;
  • "http://47.100.6.39/?sleep=100" 就是請求 url,其中 sleep=100 在測試鏡像中表示 sleep 100 毫秒,模擬真實的線上服務。

執行上述命令進行壓測,然後觀察 Pod 數量的變化情況。可以使用 watch -n 1 'kubectl  get pod' 這條命令查看 Pod 監測 Pod 數量。如下所示做半邊是 Pod 數量的變化,右半邊是壓測命令執行的過程。可以通過這個 gif 圖觀察一下壓測的過程中 pod 的變化情況。當壓力上來之後 Knative 就會自動擴容,所以 Pod 數量就會變多。當壓測結束之後 Knative 監測到流量變少就會自動縮容,這是一個完全自動化的擴容和縮容的過程。

7.gif

保留實例

前面亮點一節中介紹了 ASK Knative 會使用保留實例解決冷啟動和成本問題。接下來咱們就看一下保留實例和標準實例的切換過程。

前面的壓測結束以後多過一會兒,再使用 kubectl get pod 查看一下 Pod 的數量可能會發現只有一個 Pod 了,並且 Pod  名字是 xxx-reserve-xx  這種,reserve 的含義就是保留實例。這時候其實已經在使用保留實例提供服務了。當線上長時間沒有請求之後 Knative 就會自動擴容保留實例,並且把標準實例縮容到零,從而達到節約成本的目的。

# kubectl get pod
NAME                                               READY   STATUS    RESTARTS   AGE
coffee-bwl9z-deployment-reserve-85fd89b567-vpwqc   2/2     Running   0          5m24s

如果此時有流量進來會發生什麼呢?咱們就來驗證一下。通過下面的 gif 可以看出此時如果有流量進來就會自動擴容標準實例,待標準實例 ready 之後保留實例就會被縮容。

8.gif

保留實例默認會使用 ecs.t5-lc1m2.small(1c2g) 這個規格。當然有些應用默認啟動的時候就要分配好內存(比如 JVM),假設有一個應用需要 4G 的內存,則可能需要把 ecs.t5-c1m2.large(2c4g) 作為保留實例的規格。所以我們也提供了用戶指定保留實例規格的方法,用戶在提交 Knative Service 時可以通過 Annotation 的方式指定保留實例的規格, 比如 knative.aliyun.com/reserve-instance-eci-use-specs: ecs.t5-lc2m1.nano 這個配置的意思是使用 ecs.t5-lc2m1.nano 作為保留實例規格。 把下面內容保存到 coffee-set-reserve.yaml 文件:

# cat coffee-set-reserve.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: coffee
spec:
  template:
    metadata:
      annotations:
        knative.aliyun.com/reserve-instance-eci-use-specs: "ecs.t5-c1m2.large"
        autoscaling.knative.dev/target: "10"
    spec:
      containers:
        - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/helloworld-go:160e4dc8
          env:
            - name: TARGET
              value: "coffee-set-reserve"

執行 kubectl apply -f coffee-set-reserve.yaml 提交到 Kubernetes 集群。稍微等待一會兒,待新版本縮容到保留實例之後查看一下 Pod 列表:

# kubectl get pod
NAME                                               READY   STATUS    RESTARTS   AGE
coffee-vvfd8-deployment-reserve-845f79b494-lkmh9   2/2     Running   0          2m37s

查看 set-reserve 的保留實例規格, 可以看到已經設置成 2c4g 的 ecs.t5-c1m2.large 規格:

# kubectl get pod coffee-vvfd8-deployment-reserve-845f79b494-lkmh9 -oyaml |head -20
apiVersion: v1
kind: Pod
metadata:
  annotations:
    ... ...
    k8s.aliyun.com/eci-instance-cpu: "2.000"
    k8s.aliyun.com/eci-instance-mem: "4.00"
    k8s.aliyun.com/eci-instance-spec: ecs.t5-c1m2.large
    ... ...

升級 coffee 服務

在升級之前咱們先看一下現在的 Pod 實例:

# kubectl get pod
NAME                                               READY   STATUS    RESTARTS   AGE
coffee-fh85b-deployment-8589564f7b-4lsnf           1/2     Running   0          26s

現在咱們來對 coffee 服務做一次升級。把下面的內容保存到 coffee-v1.yaml 文件中:

# cat coffee-v1.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: coffee
spec:
  template:
    metadata:
      name: coffee-v1
      annotations:
        autoscaling.knative.dev/target: "10"
    spec:
      containers:
        - image: registry.cn-hangzhou.aliyuncs.com/knative-sample/helloworld-go:160e4dc8
          env:
            - name: TARGET
              value: "coffee-v1"

當前部署的這個版本中添加了兩點:

  • 給當前部署的 revision 設置了一個名字 coffee-v1 (如果不設置就自動生成);
  • 環境變量中設置了 v1 字樣,這樣可以通過 http 返回的內容中判斷當前提供服務的是 v1 版本
    執行  kubectl apply -f coffee-v1.yaml 命令部署 v1 版本。部署完以後繼續使用 curl -H "Host: coffee.default.example.com" [http://47.102.220.35](http://47.102.220.35) 進行驗證。

過幾秒鐘可以發現返回的內容是 Hello coffee-v1! ,在這個過程中服務沒有中斷,也不需要手動做任何切換,修改完以後直接提交即可自動完成新版本和老版本實例的切換。

# curl -H "Host: coffee.default.example.com" http://47.102.220.35
Hello coffee-v1!

現在咱們再來看一下 pod 實例的狀態, 可以見 Pod 實例發生了切換。老版本的 Pod 自動被新版本替換掉了。

# kubectl get pod
NAME                                    READY   STATUS    RESTARTS   AGE
coffee-v1-deployment-5c5b59b484-z48gm   2/2     Running   0          54s

還有更多複雜功能的 Demo 演示,請移步這裡

總結

Knative 是 Kubernetes 生態最流行的 Serverless 編排框架。社區原生的 Knative 需要常駐的 Controller 和常駐的網關才能提供服務。這些常駐實例除了需要支付 IaaS 成本以外還帶來了很多運維負擔,給應用的 Serverless 化帶來了一定的難度。所以我們在 ASK 中完全託管了 Knative Serving。開箱即用,您不需要為這些常駐實例付出任何成本。除了通過 SLB 雲產品提供 Gateway 的能力以外我們還提供了基於突發性能型實例的保留規格功能,這樣可以讓您的服務在流量波谷時期大大的減少 IaaS 開支,並且流量波谷時期積攢的 CPU 積分可以在流量高峰時期消費,您支付的每一分錢都沒有浪費。

更多 Knative 的資料請參見這裡或者這裡

參考資料

特別放送

9.png

Knative on ASK 底層使用 ECI 承載,當前可以免費領券100代金券進行試用。

試用地址:https://www.aliyun.com/daily-act/ecs/eci_freetry

課程推薦

為了更多開發者能夠享受到 Serverless 帶來的紅利,這一次,我們集結了 10+ 位阿里巴巴 Serverless 領域技術專家,打造出最適合開發者入門的 Serverless 公開課,讓你即學即用,輕鬆擁抱雲計算的新範式——Serverless。

點擊即可免費觀看課程:https://developer.aliyun.com/learning/roadmap/serverless

阿里巴巴雲原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的公眾號。”

Leave a Reply

Your email address will not be published. Required fields are marked *