すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:プリエンプティブルインスタンスでKnativeを使用する

最終更新日:Nov 15, 2024

webサービスリクエストなど、ビジネスを長時間実行する必要がなく、中断に対する耐性が高く、不要になったときにリリースできる場合は、従量課金のElastic Compute service (ECS) インスタンスよりも費用対効果の高いプリエンプティブルインスタンスを使用するようにKnative Serviceを設定できます。 プリエンプティブルインスタンスでKnativeを使用すると、サービスの柔軟性と応答速度が保証され、クラウドコンピューティングリソースの費用対効果が最大限に向上し、より効率的で費用対効果の高いサーバーレスフレームワークに加えてアプリケーションが開発されます。

前提条件

Knativeはクラスターにデプロイされています。 詳細については、「」「Knativeのデプロイ」をご参照ください。

条件

  • プリエンプティブルインスタンス

    プリエンプティブルインスタンスは、費用対効果の高いスポットインスタンスです。 Alibaba Cloudでアイドル状態のコンピューティングインスタンスに入札し、入札価格が市場価格より高い場合は、これらのインスタンスでコンテナを実行できます。 市場価格が入札価格を超えた場合、またはインスタンスが在庫切れの場合、プリエンプティブルインスタンスは回収されます。 詳細については、「」をご参照ください。プリエンプティブルインスタンスとは.

  • Knative

    Knativeは、Kubernetesに基づいて開発されたオープンソースのサーバーレスアプリケーションオーケストレーションフレームワークです。 Knativeは、クラウドネイティブおよびクロスプラットフォームのサーバーレスアプリケーションオーケストレーションを目的としています。 Knativeには、リクエストベースの自動スケーリング、ゼロへのスケーリング、バージョン管理、トラフィックベースのカナリアリリース、関数のデプロイ、イベンティングなどの機能があります。 Knativeの詳細については、「ACK Knativeの概要」および「ACK Serverless Knativeの概要」をご参照ください。

実装、機能、および利点

Knativeでは、サーバーレスワークロードはKnative Servicesを介して管理されます。 Knative Servicesは、リクエストに基づいてポッドを自動的にスケーリングできます。 プリエンプティブルインスタンスを使用するには、対応するポッド注釈を追加するだけです。 仮想ノードは、ポッド注釈で指定された仕様に基づいて、エラスティックコンテナインスタンスに自動的に適用されます。 仮想ノードは、プリエンプティブルインスタンスの自動置換もサポートし、プリエンプティブルインスタンスの使用を自動化します。

image

プリエンプティブルインスタンスでKnativeを使用する利点:

  • サーバーレスシナリオ: 短期webサービスのリソースをオンデマンドで作成およびリリースできます。

  • グレースフルシャットダウンに適応: プリエンプティブルインスタンスの自動置換中、ワークロードコントローラーは現在のポッドを削除してから、新しいプリエンプティブルインスタンスを作成する必要があります。 これには、アプリケーションコンテナがグレースフルシャットダウンをサポートする必要があります。 Knativeでは、各ポッドにはキュープロキシサイドカーコンテナが含まれています。 ワークロードコントローラーがポッドを削除する場合、キュープロキシサイドカーコンテナーがすべてのリクエストの処理を完了するまで待機してから、すべてのアプリケーションコンテナーを削除できるようにする必要があります。

  • コストに敏感なユーザー: プリエンプティブルインスタンスは、コストに敏感なKnativeユーザーに適しています。

プリエンプティブルインスタンスでのKnativeの使用例

プリエンプティブルインスタンスの設定

重要

エラスティックコンテナインスタンスを使用するには、ポッドの作成時に次のアノテーションをエラスティックコンテナインスタンスベースのポッドに追加する必要があります。 アノテーションを既存のElastic Container Instanceベースのポッドに追加する場合、またはElastic Container Instanceベースのポッドのアノテーションを直接変更する場合、アノテーションは有効になりません。

次の表の注釈をサービスに追加して、プリエンプティブルインスタンスを構成できます。

注釈

必須

説明

k8s.aliyun.com/eci-spot-strategy

SpotAsPriceGo

必須

プリエンプティブルインスタンスの入札ポリシーを指定します。 有効な値:

  • SpotWithPriceLimit: 1時間あたりの最大料金でプリエンプティブルインスタンスを作成します。 1時間あたりの最大価格を設定するには、k8s.aliyun.com/eci-spot-price-limitアノテーションを設定します。

  • SpotAsPriceGo: システムが現在の市場価格に基づいて自動的に入札するプリエンプティブルインスタンスを作成します。

    重要

    SpotAsPriceGoを選択し、指定されたゾーンで指定されたタイプのインスタンスが不足している場合、1時間あたりの最大料金がインスタンスの従量課金に達する可能性があります。

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

「0.5」

選択可能

プリエンプティブルインスタンスの最大時間料金。 この値は、小数点第3位まで正確であり得る。

このアノテーションは、k8s.aliyun.com/eci-spot-strategySpotWithPriceLimitに設定されている場合にのみ有効です。

k8s.aliyun.com/eci-spot-duration

"1"

選択可能

プリエンプティブルインスタンスの保護期間を指定します。 デフォルト値は 1 です。 値を0に設定できます。 値0は、保護期間が指定されていないことを示します。

k8s.aliyun.com/eci-spot-fallback

"true"

選択可能

指定されたタイプのプリエンプティブルインスタンスが在庫切れの場合に、従量課金インスタンスを自動的に作成するかどうかを指定します。 デフォルト値: "false"

例1: ECSインスタンスタイプを指定し、SpotWithPriceLimitポリシーを使用します。

次のYAMLテンプレートは、ecs.c6型のプリエンプティブルインスタンスを作成します。

  • インスタンスタイプと最大時間料金要件を満たすインスタンスが在庫切れの場合、プリエンプティブルインスタンスは作成されません。

  • プリエンプティブルインスタンスの作成後、保護期間 (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"           # Specify an Elastic Compute Service (ECS) instance type. 
        k8s.aliyun.com/eci-spot-strategy: "SpotWithPriceLimit"  # Use the SpotWithPriceLimit policy to set the maximum hourly price. 
        k8s.aliyun.com/eci-spot-price-limit: "0.250"   # Specify the maximum hourly price. 
    spec:         
      containers:
      - env:
        - name: TARGET
          value: "Knative"
        image: registry.cn-hangzhou.aliyuncs.com/knative-sample/helloworld-go:73fbdd56

例2: インベントリが不十分なときに従量課金インスタンスを自動的に作成する

次のYAMLテンプレートは、ecs.c6型のプリエンプティブルインスタンスを作成します。

  • プリエンプティブルインスタンスは、インスタンスタイプと最大時間料金要件が満たされている場合に作成されます。 プリエンプティブルインスタンスの作成後、保護期間 (1時間) 内にインスタンスを使用することが保証されます。 保護期間が終了した後、市場価格が入札価格を超えた場合、または指定されたタイプのインスタンスが不十分になった場合、プリエンプティブルインスタンスはリリースされます。

  • インスタンスタイプと1時間あたりの最大価格要件を満たすインスタンスが在庫切れの場合、従量課金インスタンスが作成されます。 従量課金インスタンスは自動的にリリースされません。 従量課金インスタンスの作成後、kubectl describe 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"           # Specify an ECS instance type. 
        k8s.aliyun.com/eci-spot-strategy: "SpotWithPriceLimit"  # Use the SpotWithPriceLimit policy to set the maximum hourly price. 
        k8s.aliyun.com/eci-spot-price-limit: "0.05"             # Set the maximum hourly price. 
        k8s.aliyun.com/eci-spot-fallback: "true"                # Create a pay-as-you-go instance when preemptible instances are out of stock. 
    spec:         
      containers:
      - env:
        - name: TARGET
          value: "Knative"
        image: registry.cn-hangzhou.aliyuncs.com/knative-sample/helloworld-go:73fbdd56

手順1: Knativeサービスのプリエンプティブルインスタンスの設定

コンピューティングコストを最小限に抑えるために、k8s.aliyun.com/eci-spot-strategy注釈をKnative Serviceに追加できます。 このようにして、サービスはプリエンプティブルのエラスティックコンテナインスタンスを優先します。 プリエンプティブルインスタンスは、従量課金インスタンスよりも費用対効果が高くなります。

ただし、プリエンプティブルインスタンスは、市場価格が入札価格を超える場合、または指定されたタイプのインスタンスが在庫切れの場合に回収されます。 これは、サービスの中断を引き起こす。 ビジネスの継続性と安定性を確保するには、プリエンプティブルインスタンスが不十分な場合に、Knative Serviceが従量課金インスタンスを作成できるように、k8s.aliyun.com/eci-spot-fallback: "true" アノテーションを設定します。 これにより、コストとサービスの安定性のバランスを取ります。

  1. ACKコンソールにログインします。 左側のナビゲーションウィンドウで、[クラスター] をクリックします。

  2. [クラスター] ページで、管理するクラスターの名前をクリックします。 左側のナビゲーションウィンドウで、[アプリケーション] > [ネイティブ] を選択します。

  3. Knativeページの [サービス] タブで、名前空間デフォルトに設定し、[テンプレートから作成] をクリックします。 [サンプルテンプレート] ドロップダウンリストから [カスタム] を選択し、次のコンテンツをテンプレートにコピーし、[作成] をクリックして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"           # Specify an ECS instance type. 
            k8s.aliyun.com/eci-spot-strategy: "SpotAsPriceGo"       # Use the SpotAsPriceGo policy. 
            k8s.aliyun.com/eci-spot-duration: "1"                   # Set the protection period. Default value: 1. Unit: hours. You can specify a protection period on demand. 
            k8s.aliyun.com/eci-spot-fallback: "true"                # Create a pay-as-you-go instance when preemptible instances are out of stock. 
        spec:         
          containers:
          - env:
            - name: TARGET
              value: "Knative"
            image: registry-vpc.{REGION-ID}.aliyuncs.com/knative-samples/helloworld-go:160e4dc8 # {REGION-ID} indicates the region of the cluster, such as cn-hangzhou.

    上記のYAMLファイルは、ecs.c6タイプのプリエンプティブルインスタンスを作成します。

    • 指定されたタイプのインスタンスが在庫切れの場合、プリエンプティブルインスタンスは作成されません。

    • プリエンプティブルインスタンスの作成後、そのインスタンスを1時間使用することが保証されます。 市場価格が入札価格を超えても、保護期間内にインスタンスはリリースされません。 保護期間の終了後、市場価格が入札価格を超える場合、または指定されたタイプのインスタンスが在庫切れの場合、Alibaba Cloudはプリエンプティブインスタンスをリリースする可能性があります。 この問題を回避するには、k8s.aliyun.com/eci-spot-fallback: "true" アノテーションを設定して従量課金インスタンスを作成し、プリエンプティブルインスタンスが不十分またはリリースされた場合にビジネスの継続性を確保します。

(オプション) 手順2: プリエンプティブルインスタンスのグレースフルシャットダウンの設定

制限事項

ポッド条件を使用してプリエンプティブルインスタンスの中断に関する通知を有効にし、Eviction APIを使用してプリエンプティブルインスタンスを削除するには、ack-virtual-nodeを2.11.0以降に更新する必要があります。 ack-virtual-nodeの詳細については、「ack-virtual-node」をご参照ください。

プリエンプティブルインスタンスの中断に関する通知

Alibaba Cloudは、プリエンプティブルインスタンスの中断の3分前に、SpotToBeReleasedイベントを送信し、ポッド条件のContainerInstanceExpiredの値をtrueに変更することで通知します。

次の図は、通知の例です。图片 1.png

期限切れのプリエンプティブルインスタンスのグレースフルシャットダウンの設定

プリエンプティブル弾性コンテナインスタンスの再利用によるビジネスの中断を回避するために、仮想ノードではプリエンプティブル弾性コンテナインスタンスのグレースフルシャットダウンを設定できます。 これを行うには、プリエンプティブルインスタンスにスケジュールされているポッドにk8s.aliyun.com/eci-spot-release-strategy: api-evictアノテーションを追加します。 仮想ノードがSpotToBeReleasedイベントを受信すると、Eviction APIを呼び出してプリエンプティブルインスタンスを削除します。 削除は、PodDisruptionBudgetsおよびterminationGracePeriodSecondsの設定に準拠しています。 APIを呼び出してEvictionオブジェクトを作成することは、ポッド制御ポリシーのDELETEアクションに似ています。

  1. API呼び出しを行う: 仮想ノードがSpotToBeReleasedイベントを受信すると、ノードはEviction APIを呼び出します。

  2. PDBのチェック: APIサーバーは、追い出し対象のポッド用に設定されたPDBをチェックします。

  3. 削除の実行: APIサーバーが削除要求を検証した後、ポッドは次の手順で削除されます。

    1. ポッドは削除タイムスタンプを更新し、終了するポッドをAPIサーバーが認識できるようにします。 ポッドには、設定した猶予期間もスタンプされます。

    2. ポッドが実行される仮想ノードのkubeletはポッドを認識し、ポッドのグレースフルシャットダウンを開始します。

    3. kubeletがポッドを終了すると、クラスターの制御プレーンは、関連するEndpointsおよびEndpointslicesからポッドの関連付けを解除します。 この場合、ポッドコントローラはポッドを有効と認識しなくなります。

    4. 猶予期間が終了すると、kubeletは強制的にポッドを終了します。

    5. kubeletは、ポッドを削除するようにシステムに通知します。

    6. APIサーバーはポッドを削除します。

  4. Knativeシナリオでは、各Serviceポッドにキュープロキシサイドカーコンテナーが含まれます。 ビジネスの継続性とデータの整合性を確保するために、システムがポッドを削除すると、キュープロキシサイドカーコンテナーが進行中のすべてのリクエストの処理を完了するまで待機してから、すべてのアプリケーションコンテナーを終了できます。 これにより、シームレスなポッドのスケーリングと更新が可能になります。

プリエンプティブルインスタンスのリリース

プリエンプティブルインスタンスの作成後、保護期間中は正常に実行できます。 保護期間が終了すると、市場価格が入札価格よりも高い場合、またはインベントリリソースが不足している場合、プリエンプティブルインスタンスはリリースされます。 以下の操作を実行することで、プリエンプティブルインスタンスのリリースステータスを把握できます。

  • SpotToBeReleasedイベント

    プリエンプティブルインスタンスがリリースされる約5分前にSpotToBeReleasedイベントが生成されます。

    重要

    Elastic Container Instanceは、イベントをKubernetesイベントのリストに送信します。 5分間は、プリエンプティブルインスタンスのリリースによってビジネスが影響を受けないように対策を講じることができます。

    • kubectl describeコマンドを実行して、プリエンプティブルインスタンスの詳細を表示します。 SpotToBeReleasedイベントは、コマンド出力のイベントセクションに表示されます。 例:

      Events:
        Type     Reason            Age    From          Message
        ----     ------            ----   ----          -------
        Warning  SpotToBeReleased  3m32s  kubelet, eci  Spot ECI will be released in 3 minutes
    • kukubectl get eventsコマンドを実行して、イベント情報を表示します。 SpotToBeReleasedイベントがコマンド出力に表示されます。 例:

      LAST SEEN   TYPE      REASON             OBJECT         MESSAGE
      3m39s       Warning   SpotToBeReleased   pod/pi-frmr8   Spot ECI will be released in 3 minutes
  • プリエンプティブルインスタンスのリリース後のステータス

    プリエンプティブルインスタンスがリリースされた後も、インスタンス情報は保持されます。 インスタンスのステータスがFailedに変更され、失敗の原因はBidFailedです。

    • kubectl get podコマンドを実行して、インスタンス情報を表示します。 コマンド出力に表示されるインスタンスのステータスがBidFailedに変わります。 例:

      NAME       READY   STATUS      RESTARTS   AGE
      pi-frmr8   1/1     BidFailed   0          3h5m
    • kubectl describeコマンドを実行して、プリエンプティブルインスタンスの詳細を表示します。 次に、コマンド出力でインスタンスステータスの詳細を表示します。 例:

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

参照

コールドスタート遅延を回避するために、リザーブドインスタンス機能を使用して、低仕様のバースト可能インスタンスを予約することを推奨します。 これは、コストと効率のバランスを取るのに役立ちます。 詳細は、「リザーブドインスタンスの設定」をご参照ください。