全部產品
Search
文件中心

Elastic Container Instance:建立搶佔式執行個體

更新時間:Nov 20, 2024

ECI支援搶佔式執行個體,對於短時間啟動並執行Job任務,以及部分擴充性和容錯率高的無狀態應用,使用搶佔式執行個體可以有效地節約執行個體使用成本。本文介紹在Kubernetes叢集中,如何建立搶佔式執行個體類型的ECI Pod。

背景資訊

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

搶佔式執行個體適用於短時間啟動並執行Job任務,以及部分擴充性和容錯率高的無狀態應用,例如可Auto Scaling的Web網站服務、映像渲染、巨量資料分析和大規模並行計算等。應用程式的分布度、可擴充性和容錯能力越高,越適合使用搶佔式執行個體節省成本和提升輸送量。更多資訊,請參見什麼是搶佔式執行個體

基本概念

建立搶佔式執行個體前,您需要瞭解以下資訊:

  • 計費方式

    搶佔式執行個體的市場價格隨供需變化而浮動,您需要在建立搶佔式執行個體時指定出價模式,當指定執行個體規格的即時市場價格低於出價且庫存充足時,就能成功建立搶佔式執行個體。建立成功後,在保護期(預設1小時)內按照成交時的市場價格計費。超過保護期後,按照即時的市場價格計費。

    說明

    搶佔式執行個體相對於隨用隨付執行個體價格有一定的折扣,實際價格隨供求波動,並按實際使用時間長度進行收費。更多資訊,請參見搶佔式執行個體計費

  • 回收機制

    超過保護期後,系統每隔5分鐘將自動檢測一次執行個體規格的市場價格和庫存。如果某一時刻的市場價格高於出價或執行個體規格庫存不足,搶佔式執行個體會被釋放。

    說明
    • 資源回收前約3分鐘,系統會產生準備釋放的事件。

    • 資源回收後,執行個體不再收費,但會保留執行個體資訊,且狀態會變更為已到期(Expired)。

注意事項

基於搶佔式執行個體的特點,使用搶佔式執行個體時,請注意以下資訊:

  • 選擇一個合適的執行個體規格和一個合理的出價。

    您可以通過ECS的OpenAPI介面查詢搶佔式執行個體近30天的資訊,以便選擇執行個體規格和出價。相關介面如下:

    重要

    您的出價應該足夠高,同時充分考慮了市場價格的波動,並且符合您對自身業務評估後的預期。這樣才能成功建立搶佔式執行個體,且執行個體不會因為價格因素被釋放,在滿足業務需求的同時實現成本節約。

  • 使用不受搶佔式執行個體釋放影響的儲存介質來儲存您的重要資料,例如:雲端硬碟(關閉隨執行個體釋放)、NAS等。

建立方式

支援指定ECS規格,或者指定vCPU和記憶體來建立搶佔式ECI執行個體:

  • 指定ECS規格

    計費以指定規格的按量市場價格和即時折扣為準。

  • 指定vCPU和記憶體

    該方式與指定ECS規格方式的效果相同。系統會自動匹配滿足規格和價格要求的ECS規格,並以此規格的市場價格作為計費的原始市場價格,即折扣是基於該ECS規格的市場價,而非對應ECI的vCPU和記憶體的按量價格。

    該方式僅支援2 vCPU及以上規格,支援指定的vCPU和記憶體規格如下表所示。如果指定的規格不支援,系統會自動向上規整。

    vCPU

    記憶體(GiB)

    2

    2、4、8、16

    4

    4、8、16、32

    8

    8、16、32、64

    12

    12、24、48、96

    16

    16、32、64 、128

    24

    24、48、96、192

    32

    32、64、128、256

    52

    96、192、384

    64

    128、256、512

配置說明

您可以在Pod metadata中添加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

"0"

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

k8s.aliyun.com/eci-spot-fallback

"true"

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

重要
  • Annotation請添加在Pod的metadata下,例如:建立Job時,Annotation需添加在spec>template>metadata下。

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

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

apiVersion: batch/v1
kind: Job
metadata:
  name: test
spec:
  template:
    metadata:
      labels:
        app: perl
        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:
      - name: pi
        image: registry.cn-shanghai.aliyuncs.com/eci_open/perl:5
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

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

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

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

樣本二:指定vCPU和記憶體,採用SpotAsPriceGo策略

  • 通過pod.spec.resources指定vCPU和記憶體規格

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: test
    spec:
      template:
        metadata:
          labels:
            app: perl
            alibabacloud.com/eci: "true" 
          annotations:
            k8s.aliyun.com/eci-spot-strategy: "SpotAsPriceGo"  #採用系統自動出價,跟隨當前市場實際價格
        spec:
          containers:
          - name: pi
            image: registry.cn-shanghai.aliyuncs.com/eci_open/perl:5
            command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
            resources:
              limits:              #指定pi容器的vCPU為2 vCPU,記憶體為4 GiB
                cpu: 2000m
                memory: 4096Mi
          restartPolicy: Never
  • 通過Annotation指定vCPU和記憶體規格

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: test
    spec:
      template:
        metadata:
          labels:
            app: perl
            alibabacloud.com/eci: "true" 
          annotations:
            k8s.aliyun.com/eci-use-specs : "2-4Gi"             #指定vCPU和記憶體,僅支援2 vCPU及以上規格
            k8s.aliyun.com/eci-spot-strategy: "SpotAsPriceGo"  #採用系統自動出價,跟隨當前市場實際價格
        spec:
          containers:
          - name: pi
            image: registry.cn-shanghai.aliyuncs.com/eci_open/perl:5
            command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
          restartPolicy: Never

以上YAML樣本可建立一個2 vCPU,4 GiB記憶體的搶佔式執行個體。

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

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

樣本三:設定無保護期

apiVersion: batch/v1
kind: Job
metadata:
  name: test
spec:
  template:
    metadata:
      labels:
        app: perl
        alibabacloud.com/eci: "true" 
      annotations:
        k8s.aliyun.com/eci-use-specs : "2-4Gi"             #指定vCPU和記憶體,僅支援2 vCPU及以上規格
        k8s.aliyun.com/eci-spot-strategy: "SpotAsPriceGo"  #採用系統自動出價,跟隨當前市場實際價格
        k8s.aliyun.com/eci-spot-duration: "0"              #設定無保護期
    spec:
      containers:
      - name: pi
        image: registry.cn-shanghai.aliyuncs.com/eci_open/perl:5
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

以上YAML樣本可建立一個2 vCPU,4 GiB記憶體的搶佔式執行個體。

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

  • 建立後,沒有穩定使用的保護期,只要某一時刻的市場價格高於出價或執行個體規格庫存不足,搶佔式執行個體就會被釋放。

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

apiVersion: batch/v1
kind: Job
metadata:
  name: test
spec:
  template:
    metadata:
      labels:
        app: perl
        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:
      - name: pi
        image: registry.cn-shanghai.aliyuncs.com/eci_open/perl:5
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

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

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

  • 建立時,如果沒有滿足規格和價格上限要求的庫存,則會建立一個隨用隨付的執行個體。建立後,系統不會主動釋放執行個體。

    執行個體建立成功後,您可以通過kubectl describe pod命令查看對應Pod的事件來確認是否轉為隨用隨付執行個體,如果看到SpotDegraded事件,則表明已轉為隨用隨付執行個體。

    spot轉按量事件..png

釋放說明

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

  • 預釋放事件

    搶佔式執行個體在釋放前約3分鐘,會產生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

優雅下線

搶佔式執行個體在釋放前約3分鐘,會產生SpotToBeReleased事件,同時會將Pod Conditions中的ContainerInstanceExpired欄位置為true。為盡量避免搶佔式執行個體回收導致的業務中斷,您可以基於這些通知機制,進行搶佔執行個體的優雅退出和Pod輪轉等處理。

目前虛擬節點已支援配置ECI搶佔式執行個體優雅下線的功能。您可以為搶佔式執行個體類型的ECI Pod添加k8s.aliyun.com/eci-spot-release-strategy: api-evict的Annotation,實現當虛擬節點收到SpotToBeReleased事件時,會調用Eviction API來驅逐該搶佔式執行個體。

重要

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

API發起的驅逐將遵從您的PodDisruptionBudget(PDB)和terminationGracePeriodSeconds配置。使用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時,控制面從Endpoint和EndpointSlice對象中移除該Pod。因此,控制器不再將此Pod視為有用對象。

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

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

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

  4. 負載Reconcile

    如果目標Pod是由控制器(如ReplicaSet、StatefulSet,以及設定了容錯的Job、sparkApplication、Workflow)管理的,控制器通常會建立一個新的Pod來替代被驅逐的Pod。

說明

如果PodDisruptionBudget配置錯誤,或者調用Eviction API時工作負載存在大量尚未Ready的Pod, 則會導致Eviction阻塞。在搶佔式執行個體到期前,如果仍未完成Eviction動作,搶佔式執行個體會被直接釋放。