翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
Kubernetes データプレーン
EC2 インスタンスタイプの選択は、複数のワークロードを持つクラスターでお客様が直面する最も難しい決定の 1 つである可能性があります。すべてのソリューションを one-size-fitsことはできません。スケーリングコンピューティングの一般的な落とし穴を回避するのに役立つヒントをいくつか紹介します。
自動ノード自動スケーリング
負荷を減らし、Kubernetes と深く統合するノードの自動スケーリングを使用することをお勧めします。マネージド型ノードグループと Karpenter
マネージド型ノードグループは、Amazon EC2 Auto Scaling グループの柔軟性と、マネージド型アップグレードと設定の利点を提供します。Kubernetes Cluster Autoscaler
Karpenter は、AWS によって作成されたオープンソースのワークロードネイティブノードオートスケーラーです。ノードグループを管理せずに、リソース (GPU など) のワークロード要件とテイントと許容範囲 (ゾーンスプレッドなど) に基づいてクラスター内のノードをスケーリングします。ノードは EC2 から直接作成されるため、デフォルトのノードグループクォータである 1 グループあたり 450 ノードが回避され、運用オーバーヘッドが少なく、インスタンス選択の柔軟性が向上します。可能な場合は Karpenter を使用することをお勧めします。
さまざまな EC2 インスタンスタイプを使用する
各 AWS リージョンでは、インスタンスタイプごとに使用できるインスタンスの数が制限されています。1 つのインスタンスタイプのみを使用するクラスターを作成し、リージョンの容量を超えてノード数をスケーリングすると、使用可能なインスタンスがないというエラーが表示されます。この問題を回避するには、クラスターで使用できるインスタンスのタイプを任意に制限しないでください。
Karpenter は、デフォルトで互換性のあるインスタンスタイプの幅広いセットを使用し、保留中のワークロード要件、可用性、コストに基づいてプロビジョニング時にインスタンスを選択します。NodePoolskarpenter.k8s.aws/instance-category
キーで使用されるインスタンスタイプのリストを拡張できます。
Kubernetes Cluster Autoscaler では、ノードグループを一貫してスケーリングできるように、同じサイズにする必要があります。CPU とメモリのサイズに基づいて複数のグループを作成し、個別にスケーリングする必要があります。ec2-instance-selector
ec2-instance-selector --service eks --vcpus-min 8 --memory-min 16 a1.2xlarge a1.4xlarge a1.metal c4.4xlarge c4.8xlarge c5.12xlarge c5.18xlarge c5.24xlarge c5.2xlarge c5.4xlarge c5.9xlarge c5.metal
API サーバーの負荷を軽減するためにより大きなノードを優先する
使用するインスタンスタイプを決定する場合、Kubernetes コントロールプレーンの負荷が少なくなります。kubelets と DaemonSets の実行が少なくなるためです。ただし、大きなノードは小さなノードのように完全には使用できない場合があります。ノードサイズは、ワークロードの可用性とスケール要件に基づいて評価する必要があります。
3 つの u-24tb1.metal インスタンス (24 TB のメモリと 448 コア) を持つクラスターには 3 つの kubelets があり、デフォルトでノードあたり 110 ポッドに制限されます。ポッドがそれぞれ 4 つのコアを使用している場合、これは想定されている可能性があります (4 コア x 110 = 440 コア/ノード)。3 ノードクラスターでは、1 つのインスタンスの停止がクラスターの 1/3 に影響を与える可能性があるため、インスタンスインシデントを処理する機能は低くなります。Kubernetes スケジューラがワークロードを適切に配置できるように、ワークロードにノード要件とポッドスプレッドを指定する必要があります。
ワークロードは、必要なリソースと、テイント、許容範囲、PodTopologySpread
リソースが利用可能な場合、Kubernetes スケジューラは自動的にワークロードをアベイラビリティーゾーンとホストに分散しようとします。使用可能な容量がない場合、Kubernetes Cluster Autoscaler は各アベイラビリティーゾーンにノードを均等に追加しようとします。Karpenter は、ワークロードが他の要件を指定しない限り、できるだけ迅速かつ安価にノードを追加しようとします。
スケジューラと新しいノードを使用してワークロードをアベイラビリティーゾーンに分散させるには、topologySpreadConstraints を使用する必要があります。
spec: topologySpreadConstraints: - maxSkew: 3 topologyKey: "topology.kubernetes.io/zone" whenUnsatisfiable: ScheduleAnyway labelSelector: matchLabels: dev: my-deployment - maxSkew: 2 topologyKey: "kubernetes.io/hostname" whenUnsatisfiable: ScheduleAnyway labelSelector: matchLabels: dev: my-deployment
同様のノードサイズを使用して一貫したワークロードパフォーマンスを実現する
ワークロードは、一貫したパフォーマンスと予測可能なスケーリングを可能にするために実行する必要があるノードのサイズを定義する必要があります。5 億 CPU をリクエストするワークロードは、4 コアのインスタンスと 16 コアのインスタンスで動作が異なります。T シリーズインスタンスなどのバースト CPU CPUs。
ワークロードの一貫したパフォーマンスを確保するために、ワークロードはサポートされている Karpenter ラベル
kind: deployment ... spec: template: spec: containers: nodeSelector: karpenter.k8s.aws/instance-size: 8xlarge
Kubernetes Cluster Autoscaler を使用してクラスターでスケジュールされているワークロードは、ラベルマッチングに基づいてノードセレクタとノードグループを一致させる必要があります。
spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: eks.amazonaws.com/nodegroup operator: In values: - 8-core-node-group # match your node group name
コンピューティングリソースを効率的に使用する
コンピューティングリソースには、EC2 インスタンスとアベイラビリティーゾーンが含まれます。コンピューティングリソースを効果的に使用すると、スケーラビリティ、可用性、パフォーマンスが向上し、総コストが削減されます。複数のアプリケーションを持つ Auto Scaling 環境では、効率的なリソース使用量を予測することは非常に困難です。Karpenter
Karpenter を使用すると、ワークロードはまずノードグループを作成したり、特定のノードのラベルテイントを設定したりすることなく、必要なコンピューティングリソースのタイプを宣言できます。詳細については、Karpenter のベストプラクティスを参照してください。Karpenter プロビジョナーで統合を有効にして、使用率の低いノードを置き換えることを検討してください。
Amazon マシンイメージ (AMI) の更新を自動化する
ワーカーノードコンポーネントを最新の状態に保つことで、Kubernetes API と互換性のある最新のセキュリティパッチと機能を確保できます。kubelet の更新は Kubernetes 機能の最も重要なコンポーネントですが、OS、カーネル、およびローカルにインストールされたアプリケーションパッチを自動化すると、スケーリングに伴うメンテナンスが軽減されます。
ノードイメージには、最新の Amazon EKS 最適化 Amazon Linux 2 または Amazon EKS 最適化 Bottlerocket AMI を使用することをお勧めします。Karpenter は、利用可能な最新の AMI
マネージド型ノードグループの場合、パッチリリースで使用できるようになったら、Auto Scaling Group (ASG) 起動テンプレートを新しい AMI IDs で更新する必要があります。AMI マイナーバージョン (1.23.5 から 1.24.3 など) は、ノードグループのアップグレードとして EKS コンソールと API で使用できます。パッチリリースバージョン (1.23.5 から 1.23.6 など) は、ノードグループのアップグレードとして表示されません。AMI パッチリリースでノードグループを最新の状態に保つ場合は、新しい起動テンプレートバージョンを作成し、ノードグループにインスタンスを新しい AMI リリースに置き換えさせる必要があります。
利用可能な最新の AMI は、このページから検索することも、AWS CLI を使用することもできます。
aws ssm get-parameter \ --name /aws/service/eks/optimized-ami/1.24/amazon-linux-2/recommended/image_id \ --query "Parameter.Value" \ --output text
コンテナに複数の EBS ボリュームを使用する
EBS ボリュームには、ボリュームのタイプ (gp3 など) とディスクのサイズに基づいて入出力 (I/O) クォータがあります。アプリケーションがホストと単一の EBS ルートボリュームを共有する場合、ホスト全体のディスククォータを使い果たし、他のアプリケーションが使用可能な容量を待機する可能性があります。アプリケーションは、オーバーレイパーティションにファイルを書き込んだり、ホストからローカルボリュームをマウントしたり、使用したログ記録エージェントに応じて標準出力 (STDOUT) にログアウトしたりすると、ディスクに書き込みます。
ディスク I/O の枯渇を回避するには、2 番目のボリュームをコンテナ状態フォルダ (/run/containerd など) にマウントし、ワークロードストレージに個別の EBS ボリュームを使用し、不要なローカルログ記録を無効にする必要があります。
eksctl
managedNodeGroups: - name: al2-workers amiFamily: AmazonLinux2 desiredCapacity: 2 volumeSize: 80 additionalVolumes: - volumeName: '/dev/sdz' volumeSize: 100 preBootstrapCommands: - | "systemctl stop containerd" "mkfs -t ext4 /dev/nvme1n1" "rm -rf /var/lib/containerd/*" "mount /dev/nvme1n1 /var/lib/containerd/" "systemctl start containerd"
terraform を使用してノードグループをプロビジョニングする場合は、「Terraform の EKS 設計図blockDeviceMappings
EBS ボリュームをポッドに直接マウントするには、AWS EBS CSI ドライバー
--- apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: ebs-sc provisioner: ebs.csi.aws.com volumeBindingMode: WaitForFirstConsumer --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: ebs-claim spec: accessModes: - ReadWriteOnce storageClassName: ebs-sc resources: requests: storage: 4Gi --- apiVersion: v1 kind: Pod metadata: name: app spec: containers: - name: app image: public.ecr.aws/docker/library/nginx volumeMounts: - name: persistent-storage mountPath: /data volumes: - name: persistent-storage persistentVolumeClaim: claimName: ebs-claim
ワークロードで EBS ボリュームを使用している場合、EBS アタッチ制限が低いインスタンスを避ける
EBS は、ワークロードに永続的ストレージを持たせる最も簡単な方法の 1 つですが、スケーラビリティにも制限があります。各インスタンスタイプには、アタッチできる EBS ボリュームの最大数があります。ワークロードは、実行するインスタンスタイプを宣言し、Kubernetes テイントを持つ 1 つのインスタンスでレプリカの数を制限する必要があります。
ディスクへの不要なログ記録を無効にする
本番環境でデバッグログ記録を使用してアプリケーションを実行せず、ディスクへの読み取りと書き込みを頻繁に行うログ記録を無効にすることで、不要なローカルログ記録を回避できます。Journald は、ログバッファをメモリに保持し、定期的にディスクにフラッシュするローカルログ記録サービスです。Journald は、すべての行をディスクにすぐにログに記録する syslog よりも優先されます。syslog を無効にすると、必要なストレージの合計量も減り、複雑なログローテーションルールが不要になります。syslog を無効にするには、次のスニペットを cloud-init 設定に追加します。
runcmd: - [ systemctl, disable, --now, syslog.service ]
OS 更新速度が必要なときにインスタンスにパッチを適用する
重要
インスタンスのパッチ適用は、必要な場合にのみ行う必要があります。Amazon では、インフラストラクチャをイミュータブルとして扱い、アプリケーションと同じように低い環境を通じて昇格される更新を徹底的にテストすることをお勧めします。このセクションは、それが不可能な場合に適用されます。
コンテナ化されたワークロードを中断することなく、既存の Linux ホストにパッケージをインストールするには数秒かかります。パッケージは、インスタンスを接続、ドレイン、または置き換えることなくインストールおよび検証できます。
インスタンスを置き換えるには、まず新しい AMIs を作成、検証、配布する必要があります。インスタンスには置換が作成されている必要があり、古いインスタンスは接続およびドレインされている必要があります。次に、新しいインスタンスでワークロードを作成し、検証して、パッチを適用する必要があるすべてのインスタンスに対して繰り返す必要があります。ワークロードを中断することなくインスタンスを安全に置き換えるには、数時間、数日、数週間かかります。
Amazon では、自動化された宣言型システムから構築、テスト、昇格されるイミュータブルなインフラストラクチャの使用を推奨していますが、システムへの迅速なパッチ適用が必要な場合は、新しい AMIs が利用可能になったときに、システムへのパッチ適用と置き換えを行う必要があります。パッチ適用とシステムの置き換えには大きな時間差があるため、必要に応じて AWS Systems Manager Patch Manager を使用してパッチノードを自動化することをお勧めします。
ノードにパッチを適用すると、AMI の更新後にセキュリティ更新プログラムをすばやくロールアウトし、定期的にインスタンスを置き換えることができます。Flatcar Container Linux