EKS コントロールプレーン - Amazon EKS

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

EKS コントロールプレーン

Amazon Elastic Kubernetes Service (EKS) は、独自の Kubernetes コントロールプレーンまたはワーカーノードをインストール、運用、保守することなく、AWS で Kubernetes を簡単に実行できるようにするマネージド Kubernetes サービスです。アップストリーム Kubernetes を実行し、Kubernetes 準拠の認定を受けています。この準拠により、EC2 またはオンプレミスにインストールできるオープンソースのコミュニティバージョンと同様に、EKS は Kubernetes APIs を確実にサポートします。アップストリーム Kubernetes で実行されている既存のアプリケーションは、Amazon EKS と互換性があります。

EKS は、Kubernetes コントロールプレーンノードの可用性とスケーラビリティを自動的に管理し、異常なコントロールプレーンノードを自動的に置き換えます。

EKS アーキテクチャ

EKS アーキテクチャは、Kubernetes コントロールプレーンの可用性と耐久性を損なう可能性のある単一障害点を排除するように設計されています。

EKS によって管理される Kubernetes コントロールプレーンは、EKS マネージド VPC 内で実行されます。EKS コントロールプレーンは、Kubernetes API サーバーノード、 etcd クラスターで構成されます。API サーバー、スケジューラなどのコンポーネントを実行し、Auto Scaling グループでkube-controller-manager実行する Kubernetes API サーバーノード。EKS は、AWS リージョンの 内の個別のアベイラビリティーゾーン (AZs) で、少なくとも 2 つの API サーバーノードを実行します。同様に、耐久性のために、 etcd サーバーノードは 3 つの AZs にまたがる Auto Scaling グループでも実行されます。EKS は各 AZ で NAT ゲートウェイを実行し、API サーバーと etcd サーバーはプライベートサブネットで実行されます。このアーキテクチャにより、単一の AZ のイベントが EKS クラスターの可用性に影響を与えなくなります。

新しいクラスターを作成すると、Amazon EKS はクラスターとの通信に使用するマネージド Kubernetes API サーバーの高可用性エンドポイントを作成します ( などのツールを使用kubectl)。マネージドエンドポイントは、NLB を使用して Kubernetes API サーバーをロードバランシングします。EKS は、ワーカーノードとの通信を容易にするために、異なる AZs に 2 つの ENI もプロビジョニングします。

EKS データプレーンのネットワーク接続

接続

Kubernetes クラスターの API サーバーにパブリックインターネット (パブリックエンドポイントを使用) からアクセス可能か、VPC (EKS マネージド ENIs) からアクセス可能か、またはその両方でアクセス可能かを設定できます。

ユーザーとワーカーノードがパブリックエンドポイントまたは EKS マネージド ENI を使用して API サーバーに接続するかどうかにかかわらず、接続には冗長パスがあります。

レコメンデーション

以下の推奨事項を確認してください。

コントロールプレーンメトリクスのモニタリング

Kubernetes API メトリクスをモニタリングすると、コントロールプレーンのパフォーマンスに関するインサイトが得られ、問題を特定できます。異常なコントロールプレーンは、クラスター内で実行されているワークロードの可用性を損なう可能性があります。たとえば、コントローラーの書き込みが不十分な場合、API サーバーが過負荷になり、アプリケーションの可用性に影響する可能性があります。

Kubernetes は/metrics、エンドポイントでコントロールプレーンメトリクスを公開します。

を使用して公開されているメトリクスを表示できますkubectl

kubectl get --raw /metrics

これらのメトリクスは Prometheus テキスト形式で表されます。

Prometheus を使用して、これらのメトリクスを収集して保存できます。2020 年 5 月、CloudWatch は CloudWatch Container Insights で Prometheus メトリクスのモニタリングのサポートを追加しました。そのため、Amazon CloudWatch を使用して EKS コントロールプレーンをモニタリングすることもできます。新しい Prometheus スクレイプターゲットの追加のチュートリアル: Prometheus KPI サーバーメトリクスを使用してメトリクスを収集し、CloudWatch ダッシュボードを作成してクラスターのコントロールプレーンをモニタリングできます。

Kubernetes API サーバーのメトリクスは、こちらで確認できます。例えば、 apiserver_request_duration_seconds は API リクエストの実行にかかる時間を指定できます。

これらのコントロールプレーンメトリクスのモニタリングを検討してください。

API サーバー

メトリクス 説明

apiserver_request_total

verb、dry run 値、グループ、バージョン、リソース、スコープ、コンポーネント、HTTP レスポンスコードごとに分割された apiserver リクエストのカウンター。

apiserver_request_duration_seconds*

動詞、ドライラン値、グループ、バージョン、リソース、サブリソース、スコープ、コンポーネントごとのレスポンスレイテンシーの秒単位の分布。

apiserver_admission_controller_admission_duration_seconds

アドミッションコントローラーのレイテンシーヒストグラム。名前で識別され、各オペレーションと API リソースとタイプ (検証または承認) に分割されます。

apiserver_admission_webhook_rejection_count

アドミッションウェブフック拒否の数。名前、オペレーション、Rejection_code、タイプ (検証または承認)、error_type (calling_webhook_error、apiserver_internal_error、no_error) で識別されます

rest_client_request_duration_seconds

リクエストのレイテンシーを秒単位で指定します。動詞と URL で分類されます。

rest_client_requests_total

ステータスコード、メソッド、ホストでパーティション分割された、HTTP リクエスト数。

etcd

メトリクス 説明

etcd_request_duration_seconds

オペレーションとオブジェクトタイプごとに、リクエストのレイテンシーを秒単位で返します。

etcd_db_total_size_in_bytes または apiserver_storage_db_total_size_in_bytes (EKS v1.26 以降) または apiserver_storage_size_bytes (EKS v1.28 以降)

Etcd データベースサイズ。

Kubernetes モニタリング概要ダッシュボードを使用して、Kubernetes API サーバーのリクエストとレイテンシーおよび etcd レイテンシーメトリクスを視覚化およびモニタリングすることを検討してください。

次の Prometheus クエリを使用して、 etcd の現在のサイズをモニタリングできます。クエリは、API メトリクスエンドポイントからメトリクスをスクレイピングkube-apiserverするために というジョブがあり、EKS バージョンが v1.26 未満であることを前提としています。

max(etcd_db_total_size_in_bytes{job="kube-apiserver"} / (8 * 1024 * 1024 * 1024))
重要

データベースのサイズ制限を超えると、 etcd はスペースなしアラームを発行し、それ以降の書き込みリクエストの実行を停止します。つまり、クラスターは読み取り専用になり、新しいポッドの作成、デプロイのスケーリングなどのオブジェクトを変更するすべてのリクエストは、クラスターの API サーバーによって拒否されます。

クラスター認証

EKS は現在、ベアラー/サービスアカウントトークンウェブフックトークン認証を使用する IAM 認証の 2 種類の認証をサポートしています。ユーザーが Kubernetes API を呼び出すと、ウェブフックはリクエストに含まれる認証トークンを IAM に渡します。トークンは、ベース 64 署名付き URL であり、AWS コマンドラインインターフェイス (AWS CLI) によって生成されます。

EKS クラスターを作成する IAM ユーザーまたはロールは、クラスターへのフルアクセスを自動的に取得します。EKS クラスターへのアクセスを管理するには、aws-auth configmap を編集します。

aws-auth 設定マップを誤って設定し、クラスターにアクセスできなくなった場合でも、クラスター作成者のユーザーまたはロールを使用して EKS クラスターにアクセスできます。

万一、AWS リージョンで IAM サービスを使用できない場合は、Kubernetes サービスアカウントのベアラートークンを使用してクラスターを管理することもできます。

クラスター内のすべてのアクションを実行できるsuper-adminアカウントを作成します。

kubectl -n kube-system create serviceaccount super-admin

スーパー管理者クラスター管理者ロールを付与するロールバインディングを作成します。

kubectl create clusterrolebinding super-admin-rb --clusterrole=cluster-admin --serviceaccount=kube-system:super-admin

サービスアカウントのシークレットを取得する:

SECRET_NAME=`kubectl -n kube-system get serviceaccount/super-admin -o jsonpath='{.secrets[0].name}'`

シークレットに関連付けられたトークンを取得します。

TOKEN=`kubectl -n kube-system get secret $SECRET_NAME -o jsonpath='{.data.token}'| base64 --decode`

サービスアカウントとトークンを に追加しますkubeconfig

kubectl config set-credentials super-admin --token=$TOKEN

スーパー管理者アカウントを使用するにはkubeconfig、 で現在のコンテキストを設定します。

kubectl config set-context --current --user=super-admin

最終kubeconfig版は次のようになります。

apiVersion: v1 clusters: - cluster: certificate-authority-data:<REDACTED> server: https://<CLUSTER>.gr7.us-west-2.eks.amazonaws.com name: arn:aws:eks:us-west-2:<account number>:cluster/<cluster name> contexts: - context: cluster: arn:aws:eks:us-west-2:<account number>:cluster/<cluster name> user: super-admin name: arn:aws:eks:us-west-2:<account number>:cluster/<cluster name> current-context: arn:aws:eks:us-west-2:<account number>:cluster/<cluster name> kind: Config preferences: {} users: #- name: arn:aws:eks:us-west-2:<account number>:cluster/<cluster name> # user: # exec: # apiVersion: client.authentication.k8s.io/v1alpha1 # args: # - --region # - us-west-2 # - eks # - get-token # - --cluster-name # - <<cluster name>> # command: aws # env: null - name: super-admin user: token: <<super-admin sa’s secret>>

アドミッションウェブフック

Kubernetes には 2 種類のアドミッションウェブフックがあります。アドミッションウェブフックの検証とアドミッションウェブフックの変更です。これにより、ユーザーは kubernetes API を拡張し、オブジェクトが API によって受け入れられる前に検証または変更することができます。これらのウェブフックの設定が不十分な場合、クラスターの重要なオペレーションがブロックされ、EKS コントロールプレーンが不安定になる可能性があります。

クラスターの重要なオペレーションへの影響を避けるために、次のような「キャッチオール」ウェブフックの設定は避けてください。

- name: "pod-policy.example.com" rules: - apiGroups: ["*"] apiVersions: ["*"] operations: ["*"] resources: ["*"] scope: "*"

または、タイムアウトが 30 秒未満のフェイルオープンポリシーがウェブフックにあることを確認し、ウェブフックが使用できない場合にクラスターの重要なワークロードが損なわれないようにします。

安全でないポッドをブロックする sysctls

Sysctl は Linux ユーティリティで、ユーザーが実行時にカーネルパラメータを変更できるようにします。これらのカーネルパラメータは、ネットワーク、ファイルシステム、仮想メモリ、プロセス管理など、オペレーティングシステムの動作のさまざまな側面を制御します。

Kubernetes では、ポッドにsysctlプロファイルを割り当てることができます。Kubernetes は、安全で安全でないsystclsと分類されます。Safe sysctlsはコンテナまたは Pod に名前空間化され、設定してもノードまたはノード自体の他の Pod には影響しません。これとは対照的に、安全でない sysctl は、他の Pod を中断したり、ノードを不安定にしたりする可能性があるため、デフォルトでは無効になっています。

安全でない sysctlsはデフォルトで無効になっているため、kubelet は安全でないsysctlプロファイルを持つ Pod を作成しません。このような Pod を作成すると、スケジューラはそのような Pod をノードに繰り返し割り当てますが、ノードは起動に失敗します。この無限ループは、最終的にクラスターコントロールプレーンに負荷をかけ、クラスターを不安定にします。

OPA Gatekeeper または Kyverno を使用して、安全でない のポッドを拒否することを検討してくださいsysctls

クラスターのアップグレードの処理

2021 年 4 月以降、Kubernetes リリースサイクルは 1 年に 4 つのリリース (四半期に 1 回) から 1 年に 3 つのリリースに変更されました。新しいマイナーバージョン (1.21 や 1.22 など) が約 15 週間ごとにリリースされます。Kubernetes 1.19 以降、各マイナーバージョンは、最初のリリースから約 12 か月間サポートされています。Kubernetes v1.28 の登場により、コントロールプレーンとワーカーノード間の互換性スキューが n-2 から n-3 マイナーバージョンに拡大されました。詳細については、「クラスターのアップグレードのベストプラクティス」を参照してください。

クラスターエンドポイントの接続

Amazon EKS (Elastic Kubernetes Service) を使用する場合、Kubernetes コントロールプレーンのスケーリングやパッチ適用などのイベント中に接続のタイムアウトやエラーが発生することがあります。これらのイベントにより、kube-apiserver インスタンスが置き換えられる可能性があり、FQDN を解決するときに異なる IP アドレスが返される可能性があります。このドキュメントでは、Kubernetes API コンシューマーが信頼性の高い接続を維持するためのベストプラクティスの概要を説明します。注: これらのベストプラクティスを実装するには、新しい DNS 再解決および再試行戦略を効果的に処理するために、クライアント設定またはスクリプトの更新が必要になる場合があります。

主な問題は、DNS クライアント側のキャッシュと、EKS エンドポイントの古い IP アドレス - パブリックエンドポイントの場合はパブリック NLB、プライベートエンドポイントの場合は X-ENI の可能性です。kube-apiserver インスタンスが置き換えられると、完全修飾ドメイン名 (FQDN) が新しい IP アドレスに解決される場合があります。ただし、AWS マネージド Route 53 ゾーンで 60 秒に設定された DNS 有効期限 (TTL) 設定により、クライアントは短期間、古い IP アドレスを引き続き使用できます。

これらの問題を軽減するには、Kubernetes API コンシューマー (kubectl、CI/CD パイプライン、カスタムアプリケーションなど) に次のベストプラクティスを実装する必要があります。

  • DNS 再解決の実装

  • バックオフとジッターを使用して再試行を実装します。例えば、この記事の「障害の発生」を参照してください。

  • クライアントタイムアウトを実装します。長時間実行されるリクエストがアプリケーションをブロックしないように、適切なタイムアウトを設定します。一部の Kubernetes クライアントライブラリ、特に OpenAPI ジェネレーターによって生成されたライブラリでは、カスタムタイムアウトを簡単に設定できない場合があります。

    • kubectl の例 1:

      kubectl get pods --request-timeout 10s # default: no timeout

これらのベストプラクティスを実装することで、Kubernetes API を操作する際のアプリケーションの信頼性と耐障害性を大幅に向上させることができます。これらの実装は、特にシミュレートされた障害条件下で徹底的にテストし、実際のスケーリングまたはパッチ適用イベント中に期待どおりに動作することを確認してください。

大規模なクラスターの実行

EKS は、コントロールプレーンインスタンスの負荷をアクティブにモニタリングし、自動的にスケーリングして、高いパフォーマンスを確保します。ただし、大規模なクラスターを実行する場合は、Kubernetes 内の潜在的なパフォーマンスの問題と制限、および AWS サービスのクォータを考慮する必要があります。

その他のリソース: