翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
ノードアフィニティ、テイント、許容範囲を使用して Kubernetes ポッドを Amazon EKS に配置します。
Hitesh Parikh (AWS) とRaghu Bhamidimarri (AWS) によって作成されました
環境:PoC またはパイロット | テクノロジー:コンテナとマイクロサービス | ワークロード:オープンソース |
AWS サービス:Amazon EKS |
[概要]
このパターンは、Kubernetes ノードアフィニティ、ノードテイント、ポッドトレレーションを使用して、Amazon Web Services (AWS) クラウド上の Amazon Elastic Kubernetes Service (Amazon EKS) クラスター内の特定のワーカーノードにアプリケーションポッドを意図的にスケジュールする方法を示しています。
テイントは、ノードが一連のポッドを拒否できるようにするノードプロパティです。トレレーションは、Kubernetes スケジューラーがテイントが一致するノードにポッドをスケジュールできるようにするポッドプロパティです。
ただし、許容値だけでは、スケジューラーがテイントのないワーカーノードにポッドを配置するのを防ぐことはできません。たとえば、許容範囲のある計算負荷の高いポッドが、テイントされていない汎用のノードに意図せずスケジュールされる可能性があります。このシナリオでは、ポッドのノードアフィニティプロパティは、ノードアフィニティで指定されたノード選択基準を満たすノードにポッドを配置するようにスケジューラーに指示します。
テイント、トレレーション、ノードアフィニティが一体となって、ポッドで指定されたノードアフィニティノード選択基準に一致するテイントとノードラベルを持つノード上で一貫してポッドをスケジュールするようにスケジューラーに指示します。
このパターンは、Kubernetes デプロイマニフェストファイルの例と、EKS クラスターの作成、アプリケーションのデプロイ、ポッド配置の検証の手順を示しています。
前提条件と制限
前提条件
AWS アカウントでリソースを作成するように設定された認証情報を 持つ AWS アカウント
AWS コマンドラインインターフェイス (AWS CLI)
eksctl
kubectl
Docker
がインストールされ (使用しているオペレーティングシステム用)、エンジンが起動した (Docker のライセンス要件については、Docker サイト を参照してください)。 Fedora バージョン 34 以降
お気に入りの統合開発環境 (IDE) で実行される Java マイクロサービス。たとえば、AWS Cloud9
、IntelliJ IDEA Community Edition 、Eclipse (Java マイクロサービスをお持ちでない場合は、Amazon EKS でのサンプル Java マイクロサービスのデプロイ パターンと マイクロサービスと Spring によるマイクロサービスを参照してください)。
機能制限
このパターンは Java コードを提供するものではなく、既に Java に精通していることを前提としています。基本的な Java マイクロサービスを作成するには、Amazon EKS へのサンプル Java マイクロサービスのデプロイ を参照してください。
この記事のステップでは、コストが発生する可能性のある AWS リソースを作成します。パターンを実装して検証する手順を完了したら、必ず AWS リソースをクリーンアップしてください。
アーキテクチャ
ターゲットテクノロジースタック
Amazon EKS
Java
Docker
Amazon Elastic Container Registry (Amazon ECR)
ターゲット アーキテクチャ
ソリューションアーキテクチャ図は、2 つのポッド (デプロイ 1 とデプロイ 2) と、それぞれ 2 つのノードを持つ 2 つのノードグループ (ng1 と ng2) で構成される Amazon EKS を示しています。トリガー と には、以下のプロパティがあります。
| デプロイ 1 ポッド | デプロイ 2 ポッド | ノードグループ 1 (ng1) | ノードグループ 2 (ng2) |
---|---|---|---|---|
容認 | key: classified_workload、value: true、 effect: NoSchedule key: machine_ learning_workload、value: true、 effect: NoSchedule | なし |
|
|
ノードアフィニティ | キー:alpha.eksctl.io/nodegroup-name = ng1; | なし | nodeGroups.name = ng1 |
|
テイント |
|
| key: classified_workload、value: true、 effect: NoSchedule key: machine_ learning_workload、value: true、 effect: NoSchedule | なし |
Deployment 1 Pod には許容範囲とノードアフィニティが定義されています。これにより、Kubernetes スケジューラーにデプロイメントポッドをノードグループ 1 (ng1) ノードに配置するよう指示されます。
ノードグループ 2 (ng2) にはデプロイ 1 のノードアフィニティノードセレクター式と一致するノードラベルがないため、ポッドは ng2 ノードでスケジュールされません。
Deployment 2 ポッドには、デプロイマニフェストで許容範囲やノードアフィニティが定義されていません。ノードにテイントがあるため、スケジューラーはノードグループ 1 でのデプロイ 2 ポッドのスケジュールを拒否します。
ノードにはテイントがないため、デプロイ 2 ポッドは代わりにノードグループ 2 に配置されます。
このパターンは、テイントとトレレーションをノードアフィニティと組み合わせて使用することで、特定のワーカーノードセットでのポッドの配置を制御できることを示しています。
ツール
AWS サービス
「AWS コマンドラインインターフェイス (AWS CLI)」は、オープンソースのツールであり、コマンドラインシェルのコマンドを使用して AWS サービスとやり取りすることができます。
Amazon Elastic Container Registry (Amazon ECR) は、セキュリティ、スケーラビリティ、信頼性を備えたマネージドコンテナイメージレジストリサービスです。
Amazon Elastic Kubernetes Service (Amazon EKS) は、 で Kubernetes を実行する際に役立ちます。独自の Kubernetes コントロールプレーンまたはノードをインストールおよび維持する必要はありません。
eksctl はAWS kubectlに相当し、EKSの作成に役立ちます。
その他のツール
エピック
タスク | 説明 | 必要なスキル |
---|---|---|
クラスター.yaml ファイルを作成します。 |
| アプリ所有者、AWS DevOps、クラウド管理者、 DevOps エンジン |
eksctl を使用してクラスターを作成します。 |
| AWS DevOps、AWS システム管理者、アプリ開発者 |
タスク | 説明 | 必要なスキル |
---|---|---|
Amazon ECR リポジトリを作成します。 | Amazon ECR コンソールを使ってリポジトリを作成するには、リポジトリを作成するを参照してください。リポジトリの URI をメモしておきます。 | AWS DevOps、 DevOps エンジニア、アプリ開発者 |
Dockerfile を作成します。 | パターンのテストに使用する Docker コンテナイメージがすでにある場合は、このステップを省略できます。 Dockerfile を作成するには、以下のスニペットを参考にしてください。エラーが発生した場合は、トラブルシューティング セクションを参照してください。
| AWS DevOps、 DevOps エンジニア |
pom.xml とソースファイルを作成し、Docker イメージをビルドしてプッシュします。 |
そのパターンの指示に従って Docker イメージをビルドしてプッシュします。 | AWS DevOps、 DevOps エンジニア、アプリ開発者 |
タスク | 説明 | 必要なスキル |
---|---|---|
デプロイメント.yaml ファイルを作成します。 |
コードでは、ノードアフィニティの鍵はノードグループの作成時に作成するラベルです。このパターンは eksctl が作成したデフォルトのラベルを使用します。ラベルのカスタマイズについては、Kubernetes ドキュメントの ノードへのポッドの割り当て ノードアフィニティキーの値は、 次のコマンドを実行して、テイントのキーと値を取得します。
イメージは、前のステップで作成した Amazon ECR リポジトリの URI です。 | AWS DevOps、 DevOps エンジニア、アプリ開発者 |
ファイルをデプロイします。 | Amazon EKS にデプロイするには、次のコマンドを実行します。
| アプリ開発者、 DevOps エンジニア、AWS DevOps |
デプロイを確認してください。 |
| アプリ開発者、 DevOps エンジニア、AWS DevOps |
許容範囲やノードアフィニティなしで 2 つ目のデプロイ.yaml ファイルを作成します。 | この追加ステップは、デプロイメントマニフェストファイルにノードアフィニティや許容値が指定されていない場合に、生成されるポッドがテイントのあるノードにスケジュールされないことを検証することです。(テイントのないノードでスケジュールする必要があります)。次のコードを使用して、
| アプリ開発者、AWS DevOps、 DevOps エンジン |
2 番目のデプロイ.yaml ファイルをデプロイし、ポッドの配置を検証します。 |
| アプリ開発者、AWS DevOps、 DevOps エンジン |
タスク | 説明 | 必要なスキル |
---|---|---|
リソースをクリーンアップします。 | 稼働したままのリソースに対して AWS 料金が発生しないようにするには、以下のコマンドを使用します。
| AWS DevOps、アプリ開発者 |
トラブルシューティング
問題 | ソリューション |
---|---|
システムが arm64 アーキテクチャ
| Dockerfile の実行中にエラーが発生した場合は、
|
関連リソース
ノードへのポッドの割り当て
(Kubernetes ドキュメント) テイントとトレレーション
(Kubernetes ドキュメント)
追加情報
deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: microservice-deployment spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: java-microservice template: metadata: labels: app.kubernetes.io/name: java-microservice spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: alpha.eksctl.io/nodegroup-name operator: In values: - <node-group-name-from-cluster.yaml> tolerations: #only this pod has toleration and is viable to go to ng with taint - key: "<Taint key>" #classified_workload in our case operator: Equal value: "<Taint value>" #true effect: "NoSchedule" - key: "<Taint key>" #machine_learning_workload in our case operator: Equal value: "<Taint value>" #true effect: "NoSchedule" containers: - name: java-microservice-container image: <account_number>.dkr.ecr<region>.amazonaws.com/<repository_name>:latest ports: - containerPort: 4567
ポッドのサンプル出力を説明してください
Name: microservice-deployment-in-tainted-nodes-5684cc495b-vpcfx Namespace: default Priority: 0 Node: ip-192-168-29-181.us-west-1.compute.internal/192.168.29.181 Start Time: Wed, 14 Sep 2022 11:06:47 -0400 Labels: app.kubernetes.io/name=java-microservice-taint pod-template-hash=5684cc495b Annotations: kubernetes.io/psp: eks.privileged Status: Running IP: 192.168.13.44 IPs: IP: 192.168.13.44 Controlled By: ReplicaSet/microservice-deployment-in-tainted-nodes-5684cc495b Containers: java-microservice-container-1: Container ID: docker://5c158df8cc160de8f57f62f3ee16b12725a87510a809d90a1fb9e5d873c320a4 Image: 934188034500.dkr.ecr.us-east-1.amazonaws.com/java-eks-apg Image ID: docker-pullable://934188034500.dkr.ecr.us-east-1.amazonaws.com/java-eks-apg@sha256:d223924aca8315aab20d54eddf3443929eba511b6433017474d01b63a4114835 Port: 4567/TCP Host Port: 0/TCP State: Running Started: Wed, 14 Sep 2022 11:07:02 -0400 Ready: True Restart Count: 0 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-ddvvw (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: kube-api-access-ddvvw: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true QoS Class: BestEffort Node-Selectors: <none> Tolerations: classifled_workload=true:NoSchedule machine_learning_workload=true:NoSchedule node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: <none>