webサービスリクエストなど、ビジネスを長時間実行する必要がなく、中断に対する耐性が高く、不要になったときにリリースできる場合は、従量課金のElastic Compute service (ECS) インスタンスよりも費用対効果の高いプリエンプティブルインスタンスを使用するようにKnative Serviceを設定できます。 プリエンプティブルインスタンスでKnativeを使用すると、サービスの柔軟性と応答速度が保証され、クラウドコンピューティングリソースの費用対効果が最大限に向上し、より効率的で費用対効果の高いサーバーレスフレームワークに加えてアプリケーションが開発されます。
前提条件
Knativeはクラスターにデプロイされています。 詳細については、「」「Knativeのデプロイ」をご参照ください。
条件
実装、機能、および利点
Knativeでは、サーバーレスワークロードはKnative Servicesを介して管理されます。 Knative Servicesは、リクエストに基づいてポッドを自動的にスケーリングできます。 プリエンプティブルインスタンスを使用するには、対応するポッド注釈を追加するだけです。 仮想ノードは、ポッド注釈で指定された仕様に基づいて、エラスティックコンテナインスタンスに自動的に適用されます。 仮想ノードは、プリエンプティブルインスタンスの自動置換もサポートし、プリエンプティブルインスタンスの使用を自動化します。
プリエンプティブルインスタンスでKnativeを使用する利点:
サーバーレスシナリオ: 短期webサービスのリソースをオンデマンドで作成およびリリースできます。
グレースフルシャットダウンに適応: プリエンプティブルインスタンスの自動置換中、ワークロードコントローラーは現在のポッドを削除してから、新しいプリエンプティブルインスタンスを作成する必要があります。 これには、アプリケーションコンテナがグレースフルシャットダウンをサポートする必要があります。 Knativeでは、各ポッドにはキュープロキシサイドカーコンテナが含まれています。 ワークロードコントローラーがポッドを削除する場合、キュープロキシサイドカーコンテナーがすべてのリクエストの処理を完了するまで待機してから、すべてのアプリケーションコンテナーを削除できるようにする必要があります。
コストに敏感なユーザー: プリエンプティブルインスタンスは、コストに敏感なKnativeユーザーに適しています。
プリエンプティブルインスタンスでのKnativeの使用例
プリエンプティブルインスタンスの設定
エラスティックコンテナインスタンスを使用するには、ポッドの作成時に次のアノテーションをエラスティックコンテナインスタンスベースのポッドに追加する必要があります。 アノテーションを既存のElastic Container Instanceベースのポッドに追加する場合、またはElastic Container Instanceベースのポッドのアノテーションを直接変更する場合、アノテーションは有効になりません。
次の表の注釈をサービスに追加して、プリエンプティブルインスタンスを構成できます。
注釈 | 例 | 必須 | 説明 |
k8s.aliyun.com/eci-spot-strategy | SpotAsPriceGo | 必須 | プリエンプティブルインスタンスの入札ポリシーを指定します。 有効な値:
|
k8s.aliyun.com/eci-spot-price-limit | 「0.5」 | 選択可能 | プリエンプティブルインスタンスの最大時間料金。 この値は、小数点第3位まで正確であり得る。 このアノテーションは、 |
k8s.aliyun.com/eci-spot-duration | "1" | 選択可能 | プリエンプティブルインスタンスの保護期間を指定します。 デフォルト値は 1 です。 値を0に設定できます。 値0は、保護期間が指定されていないことを示します。 |
k8s.aliyun.com/eci-spot-fallback | "true" | 選択可能 | 指定されたタイプのプリエンプティブルインスタンスが在庫切れの場合に、従量課金インスタンスを自動的に作成するかどうかを指定します。 デフォルト値: |
例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"
アノテーションを設定します。 これにより、コストとサービスの安定性のバランスを取ります。
ACKコンソールにログインします。 左側のナビゲーションウィンドウで、[クラスター] をクリックします。
[クラスター] ページで、管理するクラスターの名前をクリックします。 左側のナビゲーションウィンドウで、 を選択します。
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
に変更することで通知します。
次の図は、通知の例です。
期限切れのプリエンプティブルインスタンスのグレースフルシャットダウンの設定
プリエンプティブル弾性コンテナインスタンスの再利用によるビジネスの中断を回避するために、仮想ノードではプリエンプティブル弾性コンテナインスタンスのグレースフルシャットダウンを設定できます。 これを行うには、プリエンプティブルインスタンスにスケジュールされているポッドにk8s.aliyun.com/eci-spot-release-strategy: api-evict
アノテーションを追加します。 仮想ノードがSpotToBeReleasedイベント
を受信すると、Eviction APIを呼び出してプリエンプティブルインスタンスを削除します。 削除は、PodDisruptionBudgets
およびterminationGracePeriodSeconds
の設定に準拠しています。 APIを呼び出してEvictionオブジェクトを作成することは、ポッド制御ポリシーのDELETE
アクションに似ています。
API呼び出しを行う: 仮想ノードがSpotToBeReleasedイベントを受信すると、ノードはEviction APIを呼び出します。
PDBのチェック: APIサーバーは、追い出し対象のポッド用に設定されたPDBをチェックします。
削除の実行: APIサーバーが削除要求を検証した後、ポッドは次の手順で削除されます。
ポッドは削除タイムスタンプを更新し、終了するポッドをAPIサーバーが認識できるようにします。 ポッドには、設定した猶予期間もスタンプされます。
ポッドが実行される仮想ノードのkubeletはポッドを認識し、ポッドのグレースフルシャットダウンを開始します。
kubeletがポッドを終了すると、クラスターの制御プレーンは、関連するEndpointsおよびEndpointslicesからポッドの関連付けを解除します。 この場合、ポッドコントローラはポッドを有効と認識しなくなります。
猶予期間が終了すると、kubeletは強制的にポッドを終了します。
kubeletは、ポッドを削除するようにシステムに通知します。
APIサーバーはポッドを削除します。
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
参照
コールドスタート遅延を回避するために、リザーブドインスタンス機能を使用して、低仕様のバースト可能インスタンスを予約することを推奨します。 これは、コストと効率のバランスを取るのに役立ちます。 詳細は、「リザーブドインスタンスの設定」をご参照ください。