全部產品
Search
文件中心

Container Service for Kubernetes:在Knative中使用搶佔式執行個體

更新時間:Nov 02, 2024

如果您的業務為短時服務類型(例如短時Web服務要求等),對業務中斷容忍度較高,可以用完即釋放,不會長時間佔用資源,您可以配置Knative Service使用搶佔式執行個體,其價格相較於隨用隨付的ECS執行個體更為優惠。通過將Knative與搶佔式執行個體結合使用,您可以在保證服務彈性和響應速度的同時,最大化地利用雲端運算資源的成本效益,實現更加經濟高效的Serverless架構。

前提條件

已在叢集中部署Knative,請參見部署Knative

名詞解釋

  • 搶佔式執行個體

    是一種低成本競價型執行個體,您可以對阿里雲當前閑置的資源出價,獲得資源後運行容器,直到出價低於市場價格或者庫存不足等原因導致資源回收。關於搶佔式執行個體的更多資訊,請參見什麼是搶佔式執行個體

  • Knative

    一款基於Kubernetes的開源Serverless應用編排架構,其目標是制定雲原生、跨平台的Serverless應用編排標準。Knative主要功能包括基於請求的自動彈性、縮容到0、多版本管理、基於流量的灰階發布、函數部署以及事件驅動等。關於Knative的更多資訊,請參見ACK Knative概述ACK Serverless Knative概述

實現原理及功能優勢

在Knative中,Serverless工作負載的管理主要通過Knative Service實現。Knative Service可以基於請求自動擴縮容Pod。如果需要使用搶佔式執行個體,只需要配置相應的Pod註解即可。虛擬節點(Virtual Node)會根據Pod的註解自動申請對應的ECI資源規格。當前虛擬節點提供了搶佔式執行個體自動替換能力,可以更加自動化地使用搶佔式執行個體。

image

Knative結合搶佔式執行個體的優勢:

  • Serverless情境:短時Web服務要求,資源隨時使用,用完即釋放,不會長時間佔用資源。

  • 優雅下線的天然適配:在虛擬節點實現自動替換過程中,需要先刪除Pod,然後工作負載控制器再建立新的搶佔式執行個體,這就要求業務容器具備優雅下線的能力。而在Knative中會為每個Pod設定1個queue-proxy Sidecar容器,在刪除Pod時,會先觸發queue-proxy容器等待請求處理完成,然後再刪除業務容器。

  • 成本敏感:對於使用Knative且關心成本的使用者,使用搶佔式執行個體更具吸引力。

結合Knative配置搶佔式執行個體及樣本

配置搶佔式執行個體

重要

僅支援在建立ECI Pod時添加以下Annotation來使ECI功能生效,更新ECI Pod時添加或者修改ECI相關Annotation均不會生效。

在Service中添加Annotation來配置搶佔式執行個體的相關Annotation如下:

Annotation

樣本值

是否必選

說明

k8s.aliyun.com/eci-spot-strategy

SpotAsPriceGo

搶佔式執行個體的出價策略。可根據需要配置為:

  • SpotWithPriceLimit:自訂設定搶佔執行個體價格上限。此時必須通過k8s.aliyun.com/eci-spot-price-limit來指定每小時價格上限。

  • SpotAsPriceGo:系統自動出價,跟隨當前市場實際價格。

    重要

    使用SpotAsPriceGo策略時,如果對應可用性區域規格資源緊張,最高價格可能會達到按量價格。

k8s.aliyun.com/eci-spot-price-limit

"0.5"

搶佔式執行個體的每小時價格上限,最多支援精確到小數點後三位。

僅當k8s.aliyun.com/eci-spot-strategy設定為SpotWithPriceLimit時有效。

k8s.aliyun.com/eci-spot-duration

"1"

搶佔式執行個體的保護期。預設值為1,可設定為0。0表示無保護期。

k8s.aliyun.com/eci-spot-fallback

"true"

搶佔式執行個體沒有庫存時,是否自動轉為隨用隨付,以保證執行個體建立成功。預設為false

樣本一:指定ECS規格,採用SpotWithPriceLimit策略

以下YAML樣本可建立一個ecs.c6規格的搶佔式執行個體。

  • 建立時,如果沒有滿足規格和價格上限要求的庫存,則建立失敗。

  • 建立後,可以穩定使用1小時,超出1小時保護期後,如果某一時刻的市場價格高於出價或執行個體規格庫存不足,搶佔式執行個體會被釋放。

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: helloworld-go
spec:
  template:
    metadata:
      labels:
        alibabacloud.com/eci: "true"
      annotations:
        k8s.aliyun.com/eci-use-specs : "ecs.c6.large"           # 指定ECS執行個體規格。
        k8s.aliyun.com/eci-spot-strategy: "SpotWithPriceLimit"  # 採用自訂設定價格上限的策略。
        k8s.aliyun.com/eci-spot-price-limit: "0.25"            # 設定每小時價格上限。
    spec:         
      containers:
      - env:
        - name: TARGET
          value: "Knative"
        image: registry.cn-hangzhou.aliyuncs.com/knative-sample/helloworld-go:73fbdd56

樣本二:設定沒有庫存時自動轉為隨用隨付

以下YAML樣本可建立一個ecs.c6規格的搶佔式執行個體。

  • 建立時,如果有滿足規格和價格上限要求的庫存,則會建立一個搶佔式執行個體。建立後,可以穩定使用1小時,超出1小時保護期後,如果某一時刻的市場價格高於出價或執行個體規格庫存不足,搶佔式執行個體會被釋放。

  • 建立時,如果沒有滿足規格和價格上限要求的庫存,則會建立一個隨用隨付的執行個體。建立後,系統不會主動釋放執行個體。執行個體建立成功後,您可以通過kubectl describe pod命令查看對應Pod的事件來確認是否轉為隨用隨付執行個體,如果看到SpotDegraded事件,則表明已轉為隨用隨付執行個體。

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: helloworld-go
spec:
  template:
    metadata:
      labels:
        alibabacloud.com/eci: "true" 
      annotations:
        k8s.aliyun.com/eci-use-specs : "ecs.c6.large"           # 指定ECS執行個體規格。
        k8s.aliyun.com/eci-spot-strategy: "SpotWithPriceLimit"  # 採用自訂設定價格上限的策略。
        k8s.aliyun.com/eci-spot-price-limit: "0.05"             # 設定每小時價格上限。
        k8s.aliyun.com/eci-spot-fallback: "true"                # 當搶佔式執行個體沒有庫存時,自動轉為隨用隨付。
    spec:         
      containers:
      - env:
        - name: TARGET
          value: "Knative"
        image: registry.cn-hangzhou.aliyuncs.com/knative-sample/helloworld-go:73fbdd56

步驟一:為Knative Service配置搶佔式執行個體

為儘可能降低計算資源成本,您可以為Knative Service配置k8s.aliyun.com/eci-spot-strategy註解,這樣服務會優先使用搶佔式執行個體(ECI Spot執行個體),這類執行個體的價格相較於按需執行個體更為優惠。

然而,執行個體在市場價格高於出價或執行個體規格庫存不足時會被回收,這可能導致服務中斷。為了避免這種情況影響商務持續性,您可以同時設定k8s.aliyun.com/eci-spot-fallback: "true"註解,在搶佔式執行個體因資源不足無法繼續使用時,配置了該註解的Knative Service會自動回退到使用按需執行個體,從而確保服務的穩定運行和連續性。這樣既能有效節約成本,又能兼顧服務可靠性。

  1. 登入Container Service管理主控台,在左側導覽列選擇叢集

  2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇應用 > Knative

  3. Knative頁面的服務管理頁簽下,選擇命名空間default,然後單擊使用模板建立,單擊樣本模板右側的下拉式清單,選擇自訂,將以下範例程式碼粘貼至模板,最後單擊建立,建立一個名為helloworld-go的Knative服務。

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: helloworld-go
    spec:
      template:
        metadata:
          labels:
            alibabacloud.com/eci: "true" 
          annotations:
            k8s.aliyun.com/eci-use-specs : "ecs.c6.large"           # 指定ECS執行個體規格。
            k8s.aliyun.com/eci-spot-strategy: "SpotAsPriceGo"       # 採用自訂設定價格上限的策略。
            k8s.aliyun.com/eci-spot-duration: "1"                   # 設定無保護期。預設為1,單位:h。您可以在建立執行個體時根據實際需求指定保護期時間長度。
            k8s.aliyun.com/eci-spot-fallback: "true"                # 當搶佔式執行個體沒有庫存時,自動轉為隨用隨付。
        spec:         
          containers:
          - env:
            - name: TARGET
              value: "Knative"
            image: registry-vpc.{REGION-ID}.aliyuncs.com/knative-samples/helloworld-go:160e4dc8 # {REGION-ID}為對應叢集所在的地區,如cn-hangzhou。

    以上YAML樣本可建立一個ecs.c6規格的搶佔式執行個體。

    • 建立時,如果沒有滿足規格要求的庫存,則建立失敗。

    • 建立後,可以穩定使用1小時,在此期間內,即使市場價格高於出價,執行個體也不會被釋放。超出1小時保護期後,如果某一時刻的市場價格高於出價或者因為資產庫存不足,搶佔式執行個體有可能會被阿里雲自動釋放。此時,通過k8s.aliyun.com/eci-spot-fallback: "true"設定,當搶佔式執行個體因任何原因無法擷取或被釋放時,系統會自動轉為隨用隨付執行個體以確保服務可用性。

(可選)步驟二:配置搶佔式執行個體的優雅下線

使用限制

虛擬節點群組件ACK Virtual Node需要升級到v2.11.0及以上,才支援通過Pod Conditions來進行搶佔執行個體中斷通知以及配置Eviction API來驅逐搶佔式執行個體。關於ACK Virtual Node的更多資訊,請參見ACK Virtual Node

搶佔式執行個體中斷通知

搶佔式執行個體會在中斷前3分鐘發出SpotToBeReleased Event,同時會更新Pod Conditions的ContainerInstanceExpired欄位為true

Pod的Conditions欄位和Events欄位顯示如下。圖片 1.png

配置搶佔式執行個體到期的優雅處理方式

為了盡量避免ECI搶佔式執行個體回收導致的業務中斷,虛擬節點提供了可配置的ECI搶佔式執行個體優雅下線的功能。您可以為搶佔型Pod配置annotationsk8s.aliyun.com/eci-spot-release-strategy: api-evict。那麼當虛擬節點接收到SpotToBeReleased Event時,則會調用Eviction API來驅逐該搶佔式執行個體。API發起的驅逐將遵從您的PodDisruptionBudgetsterminationGracePeriodSeconds配置。使用API建立Eviction對象,類似於對Pod執行策略控制的DELETE操作。

  1. 調用API請求:虛擬節點接收到SpotToBeReleased Event,調用Eviction API。

  2. PDB檢查:API伺服器驗證與目標Pod關聯的PodDisruptionBudget。

  3. 驅逐執行:如果API伺服器允許驅逐,Pod將按照如下方式刪除。

    1. API伺服器中的Pod資源會更新刪除時間戳記,之後API伺服器會認為此Pod資源將被終止。 此Pod資源還會標記上配置的寬限期。

    2. 本地運行狀態的Pod所處的節點上的kubelet注意到Pod資源被標記為終止,並開始優雅停止本地Pod。

    3. 當kubelet停止Pod時,控制面從EndpointEndpointSlice對象中移除該Pod。因此,控制器不再將此Pod視為有用對象。

    4. Pod的寬限期到期後,kubelet強制終止本地Pod。

    5. kubelet告訴API伺服器刪除Pod資源。

    6. API伺服器刪除Pod資源。

  4. 在Knative情境下,每個Service的Pod中包含一個queue-proxy Sidecar容器。在刪除Pod時,queue-proxy會首先等待所有進行中的請求處理完成,以保證服務的連續性和資料完整性,最後才會停止業務容器,從而實現平滑的Pod縮容或更新操作。

釋放說明

搶佔式執行個體建立成功後,在保護期內可以正常運行。超出保護期後,如果市場價格高於出價或者資產庫存不足,搶佔式執行個體會被釋放。您可以通過以下資訊瞭解搶佔式執行個體的釋放情況。

  • 預釋放事件

    搶佔式執行個體在釋放前約5分鐘,會產生SpotToBeReleased事件。

    重要

    ECI會通過Kubernetes Events事件通知的方式告知您搶佔式執行個體將被釋放,在此期間,您可以做一定的處理來確保業務不受執行個體釋放所影響。

    • 通過kubectl describe命令查看Pod詳細資料,在返回資訊的Events中可以看到預釋放事件。樣本如下:

      Events:
        Type     Reason            Age    From          Message
        ----     ------            ----   ----          -------
        Warning  SpotToBeReleased  3m32s  kubelet, eci  Spot ECI will be released in 3 minutes
    • 通過kukubectl get events命令查看事件資訊,在返回資訊中可以看到預釋放事件。樣本如下:

      LAST SEEN   TYPE      REASON             OBJECT         MESSAGE
      3m39s       Warning   SpotToBeReleased   pod/pi-frmr8   Spot ECI will be released in 3 minutes
  • 釋放後Pod狀態

    搶佔式執行個體釋放後,執行個體資訊仍會保留,狀態變更為Failed,Failed原因為BidFailed。

    • 通過kubectl get pod命令查看Pod資訊,在返回資訊中可以看到Pod狀態已變更。樣本如下:

      NAME       READY   STATUS      RESTARTS   AGE
      pi-frmr8   1/1     BidFailed   0          3h5m
    • 通過kubectl describe命令查看Pod詳細資料,在返回資訊中可以看到Pod狀態資訊。樣本如下:

      Status:             Failed
      Reason:             BidFailed
      Message:            The pod is spot instance, and have been released at 2020-04-08T12:36Z

相關文檔

如果您的應用對冷啟動延時較為敏感,推薦您使用保留執行個體功能,保留一個低規格的突發效能執行個體,平衡好使用成本和啟動時間長度,請參見配置保留執行個體