

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# ロードバランシング
<a name="load-balancing"></a>

**ヒント**  
 Amazon EKS [https://aws-experience.com/emea/smb/events/series/get-hands-on-with-amazon-eks?trk=4a9b4147-2490-4c63-bc9f-f8a84b122c8c&sc_channel=el](https://aws-experience.com/emea/smb/events/series/get-hands-on-with-amazon-eks?trk=4a9b4147-2490-4c63-bc9f-f8a84b122c8c&sc_channel=el)ワークショップを通じてベストプラクティスをご覧ください。

ロードバランサーは受信トラフィックを受信し、EKS クラスターでホストされている目的のアプリケーションのターゲットに分散します。これにより、アプリケーションの耐障害性が向上します。EKS クラスターにデプロイすると、[AWS Load Balancer コントローラー](https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html)はそのクラスターの AWS Elastic Load Balancer を作成および管理します。LoadBalancer タイプの Kubernetes サービスが作成されると、AWS Load Balancer Controller は、受信したトラフィックを OSI モデルのレイヤー 4 で負荷分散する [Network Load Balancer (NLB)](https://docs.aws.amazon.com/eks/latest/userguide/network-load-balancing.html) を作成します。Kubernetes Ingress オブジェクトを作成すると、AWS Load Balancer Controller は、OSI モデルのレイヤー 7 でトラフィックをロードバランシングする [Application Load Balancer (ALB)](https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html) を作成します。

## Load Balancerタイプの選択
<a name="_choosing_load_balancer_type"></a>

AWS Elastic Load Balancing (ELB) ポートフォリオは、Application Load Balancer (ALB)、Network Load Balancer (NLB)、Gateway Load Balancer (GWLB)、Classic Load Balancer (CLB) のロードバランサーをサポートしています。このベストプラクティスセクションでは、EKS クラスターに最も関連性の高い ALB と NLB に焦点を当てます。

ロードバランサーのタイプを選択する際の主な考慮事項は、ワークロードの要件です。

詳細については、[「製品比較](https://aws.amazon.com/elasticloadbalancing/features/#Product_comparisons)」を参照してください。

### ワークロードが HTTP/HTTPS の場合は Application Load Balancer (ALB) を選択します。
<a name="_choose_the_application_load_balancer_alb_if_your_workload_is_httphttps"></a>

ワークロードが OSI モデルのレイヤー 7 でロードバランシングを必要とする場合、AWS Load Balancer Controller を使用して ALB をプロビジョニングできます。プロビジョニングについては、次のセクションで説明します。ALB は、前述の Ingress リソースによって制御および設定され、HTTP または HTTPS トラフィックをクラスター内の異なる Pod にルーティングします。ALB では、アプリケーショントラフィックルーティングアルゴリズムを柔軟に変更することができます。デフォルトのルーティングアルゴリズムはラウンドロビンで、未処理のリクエストが最も少ないルーティングアルゴリズムもあります。

### ワークロードが TCP の場合、またはワークロードでクライアントのソース IP 保存が必要な場合は、Network Load Balancer (NLB) を選択します。
<a name="_choose_the_network_load_balancer_nlb_if_your_workload_is_tcp_or_if_your_workload_requires_source_ip_preservation_of_clients"></a>

Network Load Balancer は、Open Systems Interconnection (OSI) モデルの 4 番目のレイヤー (トランスポート) で機能します。TCP および UDP ベースのワークロードに適しています。Network Load Balancer は、デフォルトで、ポッドにトラフィックを提示するときに、クライアントのアドレスのソース IP も保持します。

### ワークロードが DNS を利用できない場合は、Network Load Balancer (NLB) を選択します。
<a name="_choose_the_network_load_balancer_nlb_if_your_workload_cannot_utilize_dns"></a>

NLB を使用するもう 1 つの重要な理由は、クライアントが DNS を利用できない場合です。この場合、Network Load Balancer の IPs が静的であるため、NLB はワークロードにより適している可能性があります。クライアントは、ロードバランサーに接続するときにドメイン名を IP アドレスに解決するときに DNS を使用することをお勧めしますが、クライアントのアプリケーションが DNS 解決をサポートしておらず、ハードコードされた IPs のみを受け入れる場合、NLB は IPsが静的であり、NLB の存続期間中は同じであるため、NLB の方が適しています。

## ロードバランサーのプロビジョニング
<a name="_provisioning_load_balancers"></a>

ワークロードに最適なLoad Balancerを決定した後、お客様はロードバランサーをプロビジョニングするためのいくつかのオプションがあります。

### AWS Load Balancer Controller をデプロイしてLoad Balancerをプロビジョニングする
<a name="_provision_load_balancers_by_deploying_the_aws_load_balancer_controller"></a>

EKS クラスター内でロードバランサーをプロビジョニングするには、2 つの主要な方法があります。
+ AWS クラウドプロバイダーでのサービスコントローラーの活用 (レガシー)
+ AWS Load Balancer Controller の活用 (推奨)

デフォルトでは、Kubernetes Service Controller はツリー内コントローラーとも呼ばれ、LoadBalancer タイプの Kubernetes Service リソースを調整します。このコントローラーは、Kubernetes [Cloud Controller Manager として機能する AWS Cloud Provider](https://github.com/kubernetes/cloud-provider-aws) コンポーネントに組み込まれています。 [https://kubernetes.io/docs/concepts/architecture/cloud-controller/](https://kubernetes.io/docs/concepts/architecture/cloud-controller/)

プロビジョニングされた Elastic Load Balancer の設定は、Kubernetes Service マニフェストに追加する必要がある注釈によって制御されます。[Service Controller](https://cloud-provider-aws.sigs.k8s.io/service_controller/) と [AWS Load Balancer Controller](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/service/annotations/) で使用される注釈は異なります。

Service Controller はレガシーであり、現在重要なバグ修正のみを受けています。LoadBalancer タイプの Kubernetes サービスを作成すると、Service Controller はデフォルトで AWS CLB を作成しますが、適切な注釈を使用する場合は AWS NLB を作成することもできます。Service Controller は Kubernetes Ingress リソースをサポートしておらず、IPv6 もサポートしていないことに注意してください。

EKS クラスターで AWS Load Balancer Controller を使用して、Kubernetes サービスと Ingress リソースを照合することをお勧めします。AWS Load Balancer Controller が調整プロセスを所有するように、Kubernetes Service または Ingress マニフェストで適切な注釈を使用する必要があります (Service Controller の代わりに）。

[EKS Auto Mode](https://docs.aws.amazon.com/eks/latest/userguide/automode.html) を使用している場合は、AWS Load Balancer Controller が自動的に提供されます。インストールは必要ありません。

## Load Balancerのターゲットタイプの選択
<a name="_choosing_load_balancer_target_type"></a>

### IP Target-Type を使用して Pod をターゲットとして登録する
<a name="_register_pods_as_targets_using_ip_target_type"></a>

AWS Elastic Load Balancer: Network & Application は、受信したトラフィックをターゲットグループ内の登録済みターゲットに送信します。EKS クラスターには、ターゲットグループに登録できるターゲットのタイプが 2 つあります。インスタンスと IP です。どのターゲットタイプを使用するかは、登録される内容と、Load Balancerからポッドへのトラフィックのルーティング方法に影響します。デフォルトでは、AWS Load Balancer コントローラーは「インスタンス」タイプを使用してターゲットを登録し、このターゲットはワーカーノードの IP と NodePort になります。これには以下が含まれます。
+ Load Balancer からのトラフィックは NodePort のワーカーノードに転送され、これは iptables ルール (ノードで実行されている kube-proxy によって設定) によって処理され、ClusterIP の サービス (まだノード上) に転送されます。最後に、サービスは登録されたポッドをランダムに選択してトラフィックを転送します。このフローには複数のホップが含まれ、特に追加のレイテンシーが発生する可能性があります。これは、サービスが別の AZ にある可能性のある別のワーカーノードで実行されているポッドを選択する場合があるためです。
+ Load Balancer はワーカーノードをターゲットとして登録するため、ターゲットに送信されるヘルスチェックはポッドによって直接受信されるのではなく、NodePort 上のワーカーノードによって受信され、ヘルスチェックトラフィックは上記の同じパスに従います。
+ Load Balancer によって転送されるトラフィックはポッドに直接送信されないため、モニタリングとトラブルシューティングはより複雑です。適切なトラブルシューティングのために、ワーカーノードで受信したパケットをサービスClusterIP に慎重に関連付け、最終的にはポッドがパケットのパスを完全にend-to-endで可視化できるようにする必要があります。

![ロードバランサーのインスタンスターゲットタイプを示す図](http://docs.aws.amazon.com/ja_jp/eks/latest/best-practices/images/networking/lb_target_type_instance.png)


これとは対照的に、ターゲットタイプを「IP」として設定する場合、意味は次のとおりです。
+ Load Balancer からのトラフィックはポッドに直接転送されます。これにより、ワーカーノードとサービスクラスター IP の以前の追加ホップをバイパスするネットワークパスが簡素化され、サービスが別の AZ のポッドにトラフィックを転送し、最後にワーカーノードで iptables ルールのオーバーヘッド処理を削除した場合に発生するレイテンシーが短縮されます。
+ Load Balancer のヘルスチェックはポッドによって直接受信され、応答されます。つまり、ターゲットステータス「正常」または「異常」はポッドのヘルスステータスを直接表したものです。
+ モニタリングとトラブルシューティングが簡単で、パケット IP アドレスをキャプチャするツールを使用すると、送信元フィールドと送信先フィールドの Load Balancer とポッド間の双方向トラフィックが直接明らかになります。

![ロードバランサーの IP アドレスターゲットタイプを示す図](http://docs.aws.amazon.com/ja_jp/eks/latest/best-practices/images/networking/lb_target_type_ip.png)


追加した IP ターゲットを使用する AWS Elastic Load Balancing を作成するには:
+  `alb.ingress.kubernetes.io/target-type: ip` Kubernetes Ingress (Application Load Balancer) を設定する際の Ingress のマニフェストへの注釈
+  `service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip` LoadBalancer (Network Load Balancer) タイプの Kubernetes サービスを設定するときのサービスのマニフェストへの 注釈。

## Load Balancer ヘルスチェックの設定
<a name="_configuring_load_balancer_health_checks"></a>

Kubernetes は独自のヘルスチェックメカニズムを提供しますが (次のセクションで詳しく説明します）、Kubernetes コントロールプレーン外で機能する補完的な保護手段として ELB ヘルスチェックを実装することをお勧めします。この独立したレイヤーは、次の場合でもアプリケーションのモニタリングを継続します。
+ Kubernetes コントロールプレーンの中断
+ プローブ実行の遅延
+ kubelet とポッド間のネットワークパーティション

上記のシナリオで最大可用性の高速復旧を必要とする重要なワークロードの場合、ELB ヘルスチェックは、Kubernetes のネイティブメカニズムの代わりにではなく、 と連携する重要な安全ネットを提供します。

ELB でヘルスチェックを設定して微調整するには、Service Controller または AWS Load Balancer Controller によって調整される Kubernetes Service または Ingress マニフェストで注釈を使用する必要があります。

## 可用性とポッドのライフサイクル
<a name="_availability_and_pod_lifecycle"></a>

アプリケーションのアップグレード中は、ユーザーがダウンタイムを経験しないように、アプリケーションが常にリクエストを処理できることを確認する必要があります。このシナリオの一般的な課題の 1 つは、Kubernetes レイヤーとインフラストラクチャ、例えば外部 Load Balancer 間でワークロードの可用性ステータスを同期することです。次のいくつかのセクションでは、このようなシナリオに対処するためのベストプラクティスに焦点を当てます。

**注記**  
以下の説明は、Kubernetes の[EndpointSlices](https://kubernetes.io/docs/concepts/services-networking/service/#endpointslices) に基づいています。 [https://kubernetes.io/docs/concepts/services-networking/service/#endpoints](https://kubernetes.io/docs/concepts/services-networking/service/#endpoints)以下のシナリオでは、両者の違いはごくわずかです。AWS Load Balancer Controller はデフォルトでエンドポイントを消費し、コントローラーで enable-endpoint-sliceflag を有効にすることで EndpointSlices を有効にできます。 [enable-endpoint-sliceflag](https://github.com/kubernetes-sigs/aws-load-balancer-controller/blob/main/docs/deploy/configurations.md#controller-command-line-flags) 

### ヘルスチェックを使用する
<a name="_use_health_checks"></a>

デフォルトでは、Kubernetes は[プロセスヘルスチェック](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-states)を実行し、ノード上の kubelet プロセスがコンテナのメインプロセスが実行されているかどうかを確認します。そうでない場合は、デフォルトでそのコンテナを再起動します。ただし、コンテナプロセスが実行されているがデッドロック状態にある場合、またはアプリケーションが正常に開始されたかどうかを識別するように [Kubernetes プローブ](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#types-of-probe)を設定することもできます。プローブは、exec、grpc、httpGet、および tcpSocket [メカニズム](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#probe-check-methods)に基づくことができます。プローブのタイプと結果に基づいて、コンテナを再起動できます。

[ポッド作成](#lb-pod-create)プロセスの一連のイベントについては、以下の付録セクションのポッド作成を参照してください。

### 準備状況プローブを使用する
<a name="_use_readiness_probes"></a>

デフォルトでは[、Pod 内のすべてのコンテナが Pod 条件を実行](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-readiness-status)している場合、「準備完了」と見なされます。 [https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions)ただし、アプリケーションは引き続きクライアントリクエストを処理できない場合があります。たとえば、アプリケーションがリクエストを処理できるようにするには、外部リソースから一部のデータまたは設定をプルする必要がある場合があります。このような状態では、アプリケーションを強制終了したり、リクエストを転送したりしたくありません。[準備状況プローブ](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes)を使用すると、ポッドが「準備完了」と見なされないようにできます。つまり、[プローブ結果が](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#probe-outcome) になるまで EndpointSlice オブジェクトに追加されません`success`。一方、プローブが行をさらに下回ると、Pod は EndpointSlice オブジェクトから削除されます。各コンテナの Pod マニフェストで準備状況プローブを設定できます。各ノードの `kubelet`プロセスは、そのノードのコンテナに対して準備状況プローブを実行します。

### Pod の準備状況ゲートを使用する
<a name="_utilize_pod_readiness_gates"></a>

準備状況プローブの 1 つの側面は、外部フィードバック/影響メカニズムがないことです。ノードの kubelet プロセスはプローブを実行し、プローブの状態を定義します。EndpointSlice Controller はエンドポイント (Pod) のリストを常に最新の状態に保つため、Kubernetes レイヤー (東西トラフィック) 内のマイクロサービス自体間のリクエストには影響しません。外部メカニズムが必要な理由とタイミング

Kubernetes Service タイプの Load Balancer または Kubernetes Ingress (北から南へのトラフィックの場合) を使用してアプリケーションを公開する場合、ロードバランサーが最新のリストターゲットも持つように、各 Kubernetes Service の Pod IPs のリストを外部インフラストラクチャロードバランサーに伝播する必要があります。[AWS Load Balancer Controller](https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html) は、ここでギャップを埋めます。AWS Load Balancer Controller を使用して `target group: IP` を利用する場合、AWS Load Balancer Controller `kube-proxy` も更新を受信し ( 経由`watch`)、[ELB API](https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/Welcome.html) と通信して Pod IP を ELB のターゲットとして設定し、登録を開始します。

デプロイのローリング更新を実行すると、新しいポッドが作成され、新しいポッドの条件が「準備完了」になるとすぐに、古い/既存のポッドが終了します。このプロセス中、Kubernetes EndpointSlice オブジェクトは、ELB が新しいポッドをターゲットとして登録するのにかかる時間よりも速く更新されます。[「ターゲット登録](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/target-group-register-targets.html)」を参照してください。しばらくすると、Kubernetes レイヤーとクライアントリクエストを削除できるインフラストラクチャレイヤーの状態が一致しなくなる可能性があります。Kubernetes レイヤー内のこの期間中、新しい Pod はリクエストを処理する準備ができていますが、ELB の観点からは処理できません。

 [Pod Readiness Gates](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-readiness-gate) を使用すると、Pod 条件が「準備完了」と見なされる前に満たす必要がある追加要件を定義できます。AWS ELB の場合、AWS Load Balancer Controller は AWS ELB のターゲット (ポッド) のステータスをモニタリングし、ターゲット登録が完了し、ステータスが「正常」になると[、コントローラーはポッドの条件を「準備完了」に更新](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.4/deploy/pod_readiness_gate/)します。このアプローチでは、AWS ELB のターゲットステータスである外部ネットワークの状態に基づいて Pod 条件に影響します。Pod Readiness Gates はローリング更新シナリオで重要です。これにより、デプロイのローリング更新が古いポッドを終了し、新しく作成されたポッドのターゲットステータスが AWS ELB で「正常」になるのを防ぐことができます。

### アプリケーションの正常なシャットダウン
<a name="_gracefully_shutdown_applications"></a>

クライアントがダウンタイムを経験しないように、アプリケーションは正常なシャットダウンを開始して SIGTERM シグナルに応答する必要があります。つまり、アプリケーションはデータの保存、ファイル記述子の閉鎖、データベース接続の閉鎖、処理中のリクエストの正常な完了、ポッド終了リクエストを満たすためのタイムリーな終了などのクリーンアップ手順を実行する必要があります。クリーンアップを完了できるように、猶予期間を十分な長さに設定する必要があります。SIGTERM シグナルに応答する方法については、アプリケーションで使用する各プログラミング言語のリソースを参照してください。

SIGTERM シグナルを受信したときにアプリケーションが正常にシャットダウンできない場合、または[シグナルを無視/受信しない場合](https://petermalmgren.com/signal-handling-docker/)、代わりに [PreStop フック](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks)を使用してアプリケーションの正常なシャットダウンを開始できます。プリストップフックは、SIGTERM シグナルが送信される直前に実行され、アプリケーションコード自体にこれらのオペレーションを実装することなく、任意のオペレーションを実行できます。

イベントの全体的なシーケンスを次の図に示します。注: アプリケーションの正常なシャットダウン手順の結果や PreStop フックの結果に関係なく、アプリケーションコンテナは最終的に SIGKILL を介して猶予期間の終了時に終了します。

![ポッド終了のプロセスシーケンス図](http://docs.aws.amazon.com/ja_jp/eks/latest/best-practices/images/networking/lb_podterminationlifecycle.png)


[ポッド削除](#lb-pod-delete)プロセスの一連のイベントについては、以下の付録セクションのポッド削除を参照してください。

### クライアントリクエストを適切に処理する
<a name="_gracefully_handle_the_client_requests"></a>

Pod 削除のイベントのシーケンスは、Pod の作成とは異なります。Pod が作成されると、Kubernetes API の Pod IP `kubelet`が更新され、EndpointSlice オブジェクトのみが更新されます。一方、ポッドが終了すると、Kubernetes API は kubelet と EndpointSlice コントローラーの両方に同時に通知します。イベントのシーケンスを示す次の図を慎重に検査します。

![kubelet を更新するプロセスを示す図](http://docs.aws.amazon.com/ja_jp/eks/latest/best-practices/images/networking/lb_statepropagation.png)


状態が API サーバーから上記で説明したノードの iptables ルールまで伝播する方法は、興味深い競合状態を作成します。各ノードの kube-proxy がローカル iptables ルールを更新するよりもかなり早くコンテナが SIGKILL シグナルを受信する可能性が高いためです。このような場合、言及する価値のある 2 つのシナリオは次のとおりです。
+ アプリケーションが SIGTERM を受信したときに処理中のリクエストと接続をすぐに急に切断した場合、クライアントはその場で 50 倍のエラーが発生することになります。
+ アプリケーションが SIGTERM を受信したときにすべての処理中のリクエストと接続が完全に処理されるようにしても、猶予期間中は、iptables ルールがまだ更新されていない可能性があるため、新しいクライアントリクエストがアプリケーションコンテナに送信されます。クリーンアップ手順がコンテナのサーバーソケットを閉じるまで、これらの新しいリクエストは新しい接続になります。猶予期間が終了すると、SIGTERM 後に確立された接続は、SIGKILL が送信されるため、その時点で無条件に削除されます。

Pod 仕様で猶予期間を十分長く設定すると、この課題に対処できますが、伝播の遅延と実際のクライアントリクエストの数によっては、アプリケーションが接続を適切に終了するまでにかかる時間を予測するのが困難です。したがって、ここではあまり完全ではなく、最も実行可能なアプローチは、PreStop フックを使用して iptables ルールが更新されるまで SIGTERM シグナルを遅らせ、既存の接続のみが継続されるのではなく、新しいクライアントリクエストがアプリケーションに送信されないようにすることです。PreStop フックは、 などのシンプルな Exec ハンドラーにすることができます`sleep 10`。

上記の動作と推奨事項は、AWS Load Balancer Controller を使用して Kubernetes Service type of Load Balancer または Kubernetes Ingress (North-South トラフィック用) を使用してアプリケーションを公開し`target group: IP`、 を利用する場合も同様に適用されます。 Load Balancer `kube-proxy` AWS Load Balancer Controller と同様に、EndpointSlice オブジェクトの更新も (監視を介して) 受信し、[ELB API](https://docs.aws.amazon.com/elasticloadbalancing/latest/APIReference/Welcome.html) と通信して ELB から Pod IP の登録解除を開始するためです。ただし、Kubernetes API または ELB API の負荷によっては時間がかかる場合があり、SIGTERM はすでにアプリケーションに送信されている可能性があります。ELB がターゲットの登録解除を開始すると、そのターゲットへのリクエストの送信が停止されるため、アプリケーションは新しいリクエストを受信せず、ELB はデフォルトで 300 秒[の登録解除の遅延](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-target-groups.html#deregistration-delay)も開始します。登録解除プロセス中、ターゲットは基本的に ELB `draining`がそのターゲットへの処理中のリクエスト/既存の接続がドレインするのを待機します。登録解除の遅延が期限切れになると、ターゲットは使用されず、そのターゲットへの処理中のリクエストは強制的に削除されます。

### Pod 中断予算を使用する
<a name="_use_pod_disruption_budget"></a>

アプリケーションの[ポッド中断予算](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/#pod-disruption-budgets) (PDB) を設定します。PDBlimits[します](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/#voluntary-and-involuntary-disruptions)。これにより、StatefulSet またはデプロイでポッドの最小数または割合が維持されます。たとえば、クォーラムベースのアプリケーションでは、実行中のレプリカの数がクォーラムに必要な数を下回ることがないようにする必要があります。または、ウェブフロントエンドにより、ロードを処理するレプリカの数が合計の特定の割合を下回ることがないようにすることができます。PDB は、ドレインされるノードやロールアウトされるデプロイの新しいバージョンなどのアクションからアプリケーションを保護します。PDB の は、ノードオペレーティングシステムの障害やネットワーク接続の喪失などの意図しない中断からアプリケーションを保護しないことに注意してください。詳細については、[「Kubernetes でのアプリケーションの中断予算の指定](https://kubernetes.io/docs/tasks/run-application/configure-pdb/)」のドキュメントを参照してください。

## リファレンス
<a name="_references"></a>
+ KubeCon Europe 2019 セッション - [準備完了? サービスヘルスのためのポッド準備ゲートの詳細](https://www.youtube.com/watch?v=Vw9GmSeomFg) 
+ 書籍 - [Kubernetes in Action](https://www.amazon.com/Kubernetes-Action-Marko-Luksa/dp/1617293725/) 
+ AWS ブログ - [ALB on EKS (トラフィックを失うことなく) を使用してアプリケーションを迅速にスケーリングする方法](https://aws.amazon.com/blogs/containers/how-to-rapidly-scale-your-application-with-alb-on-eks-without-losing-traffic/) 

## 付録
<a name="_appendix"></a>

### ポッドの作成
<a name="lb-pod-create"></a>

ポッドがデプロイされ、クライアントリクエストを受信して処理する準備が整うシナリオでは、イベントのシーケンスを理解することが不可欠です。イベントのシーケンスについて説明します。

1. ポッドは Kubernetes コントロールプレーンに作成されます (kubectl コマンド、デプロイの更新、スケーリングアクション など）。

1.  `kube-scheduler` は、ポッドをクラスター内のノードに割り当てます。

1. 割り当てられたノードで実行されている kubelet プロセスは ( を介して`watch`) 更新を受け取り、コンテナランタイムと通信して Pod 仕様で定義されたコンテナを開始します。

1. コンテナの実行が開始されると、kubelet は Kubernetes API の [Pod オブジェクトのように Pod 条件](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-conditions)を更新します。 `Ready`

1. [EndpointSlice Controller](https://kubernetes.io/docs/concepts/overview/components/#kube-controller-manager) は Pod 条件の更新を ( 経由で`watch`) 受信し、Pod IP/Port を新しいエンドポイントとして各 Kubernetes サービスの [EndpointSlice](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/) オブジェクト (Pod IPs) に追加します。

1.  各ノードの [kube-proxy](https://kubernetes.io/docs/concepts/overview/components/#kube-proxy) プロセスは、EndpointSlice オブジェクトの更新を ( を介して`watch`) 受信し、各ノードの [iptables](https://en.wikipedia.org/wiki/Iptables) ルールを新しい Pod IP/ポートで更新します。

### ポッドの削除
<a name="lb-pod-delete"></a>

ポッドの作成と同様に、ポッドの削除中のイベントのシーケンスを理解することが不可欠です。イベントのシーケンスについて説明します。

1. ポッド削除リクエストが Kubernetes API サーバーに送信されます (`kubectl`コマンド、デプロイの更新、スケーリングアクション など）。

1. Kubernetes API サーバーは、Pod オブジェクトの [deletionTimestamp](https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion) フィールドを設定することで、デフォルトで 30 秒の[猶予期間を開始します](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination)。(猶予期間は を介してポッド仕様で設定できます`terminationGracePeriodSeconds`)

1. ノードで実行されている`kubelet`プロセスは、Pod オブジェクトの更新を (監視を介して) 受信し、その Pod の各コンテナ内のプロセス識別子 1 (PID 1) に [SIGTERM](https://en.wikipedia.org/wiki/Signal_(IPC)#SIGTERM) シグナルを送信します。次に、 を監視します`terminationGracePeriodSeconds`。

1. [EndpointSlice Controller](https://kubernetes.io/docs/concepts/overview/components/#kube-controller-manager) は、ステップ 2 から ( を介して`watch`) 更新を受け取り、各 Kubernetes サービスの [EndpointSlice](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/#conditions) オブジェクト (ポッド IPs」に設定します。

1.  各ノードの [kube-proxy](https://kubernetes.io/docs/concepts/overview/components/#kube-proxy) プロセスは、EndpointSlice オブジェクトの更新 ( 経由`watch`) を受け取り、各ノードの [iptables](https://en.wikipedia.org/wiki/Iptables) ルールが kube-proxy によって更新されて、クライアントリクエストの Pod への転送を停止します。

1. `terminationGracePeriodSeconds` の有効期限が切れると、 は Pod 内の各コンテナの親プロセスに [SIGKILL](https://en.wikipedia.org/wiki/Signal_(IPC)#SIGKILL) シグナル`kubelet`を送信し、強制的に終了します。

1.  [TheEndpointSlice](https://kubernetes.io/docs/concepts/overview/components/#kube-controller-manager)は、[EndpointSlice](https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/#conditions) オブジェクトからエンドポイントを削除します。

1. API サーバーは Pod オブジェクトを削除します。