Amazon EBS マルチアタッチを使用して、Amazon EKS の複数のワークロードに同じボリュームをアタッチするにはどうすればよいですか?
Amazon Elastic Kubernetes Service (Amazon EKS) の複数のクラスターにわたる複数のワークロードで Amazon Elastic Block Store (Amazon EBS) マルチアタッチを使用することを考えています。
簡単な説明
永続ワークロードを Amazon EBS ストレージのある Amazon EKS で作成する場合、デフォルトのボリュームタイプは gp2 です。Amazon EBS マルチアタッチでは、プロビジョンド IOPS SSD (io1 または io2) ボリューム1つを同じアベイラビリティーゾーンの複数のインスタンスにアタッチできます。
Amazon EBS マルチアタッチは、汎用 SSD ボリューム (gp2や gp3など) ではサポートされていません。Amazon EBS CSI ドライバーでは、同じクラスターにある別々のノードで実行されるワークロードへのボリュームのマルチアタッチはサポートしていません。
同じ Amazon EBS 永続ストレージを別々のクラスターにわたって複数のワークロードにマルチアタッチするには、プロビジョンド IOPS SSD ボリュームを使用します。クラスター全体にわたって、複数のポッドが同じアベイラビリティーゾーン (AZ) のワーカーノードで実行されるようにします。
**注:**ワークロードが複数のアベイラビリティーゾーンにある場合は、クラスターが同じでも異なっていても Amazon Elastic File System (Amazon EFS) を使用してください。詳細については、GitHub ウェブサイトの「Create an Amazon EFS file system for Amazon EKS (Amazon EKS 向け Amazon EFS ファイルシステムの作成)」を参照してください。
解決方法
開始する前に、Amazon EBS CSI ドライバーを必要とされる Amazon EKS クラスターにインストールしておきます。
**注:**マルチアタッチ対応ボリュームは、同じアベイラビリティーゾーンにある Nitro System に構築した Linux インスタンス最大16個にアタッチできます。
Amazon EBS Multi-Attach を使用して、複数のクラスターにわたる複数のワークロードに同じボリュームをアタッチするには、次の手順を実行します。
Amazon EBS ボリュームをプロビジョニングする
Amazon EBS ボリュームをプロビジョニングするには、次の手順を実行します。
- 次のようにして、ボリュームを静的にプロビジョニングします。
**注:****<example-region>を、必要とする AWS リージョンに置き換えます。<example-az>**を、必要とするアベイラビリティーゾーンに置き換えます。aws ec2 create-volume --volume-type io2 --multi-attach-enabled --size 10 --iops 2000 --region <example-region> --availability-zone <example-az> --tag-specifications 'ResourceType=volume,Tags=[{Key=purpose,Value=prod},{Key=Name,Value=multi-attach-eks}]'
- gp2ボリュームか gp3ボリュームを含む既存のワークロードがある場合は、まずボリュームのスナップショットを作成します。続いて、そのスナップショットから io2ボリュームを作成します。
**注:**io1 ボリュームを作成してから Amazon EBS Multi-Attach をオンにすることはできません。Amazon EBS Multi-Attach は、io2 ボリュームに対しては、作成されてからインスタンスにアタッチされていなければオンにできます。Amazon EKS の io2動的ストレージプロビジョニングでは、ストレージクラスを作成するためのポッドなしでボリュームをプロビジョニングする Immediate モードを指定します。Amazon EBS Multi-Attach は、ポッドを作成する前にオンにしておいてください。
ボリューム ID を取得する
ワークロード向けにプロビジョニングされているボリューム ID を取得します。
aws ec2 describe-volumes --filters "Name=tag:Name,Values=multi-attach-eks*" --query "Volumes[*].{ID:VolumeId}" --region <example-region>
**注:**example-region は、必要とする AWS リージョンに置き換えます。
永続ワークロードを既存のクラスターに前述のボリューム ID を使用してプロビジョニングする
-
次のマニフェストを workloadA.yml という名前で作成します。
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: <example-pv-claim-name-a> spec: storageClassName: "" volumeName: <example-pv-name-a> accessModes: - ReadWriteOnce resources: requests: storage: 5Gi --- apiVersion: v1 kind: Pod metadata: name: <example-pod-a> spec: containers: - name: <example-pod-container-name> image: centos command: ["/bin/sh"] args: ["-c", "while true; do echo $(date -u) on pod A >> /data/out.txt; sleep 15; done"] volumeMounts: - name: <example-volume-mount-name> mountPath: /data volumes: - name: <example-volume-mount-name> persistentVolumeClaim: claimName: <example-pv-claim-name-a> --- apiVersion: v1 kind: PersistentVolume metadata: name: <example-pv-name-a> spec: accessModes: - ReadWriteOnce capacity: storage: 5Gi csi: driver: ebs.csi.aws.com fsType: ext4 volumeHandle: <example-preceding-volume-id> nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: topology.ebs.csi.aws.com/zone operator: In values: - <example-az>
注:次のコマンドのサンプル文字列はすべて、必要とする値に置き換えてください。**StorageClassName ** パラメータ値は、空の文字列「****」に設定しておいてください。
-
kubectl コンテキストをクラスター A に切り替えてから、ワークロードをデプロイします。
kubectl config use-context <example-clusterA-context> kubectl apply -f workloadA.yml
前述のボリューム ID を使用して、別のワークロードを別のクラスターに作成します。
-
次のマニフェストを workloadB.yml という名前で作成してデプロイします。
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: <example-pv-claim-name-b> spec: storageClassName: "" volumeName: <example-pv-name-b> accessModes: - ReadWriteOnce resources: requests: storage: 5Gi --- apiVersion: v1 kind: Pod metadata: name: <example-pod-b> spec: containers: - name: <example-pod-container-name> image: centos command: ["/bin/sh"] args: ["-c", "tail -f /data/out.txt"] volumeMounts: - name: <example-volume-mount-name> mountPath: /data volumes: - name: <example-volume-mount-name> persistentVolumeClaim: claimName: <example-pv-claim-name-b> --- apiVersion: v1 kind: PersistentVolume metadata: name: <example-pv-name-b> spec: accessModes: - ReadWriteOnce capacity: storage: 5Gi csi: driver: ebs.csi.aws.com fsType: ext4 volumeHandle: <example-preceding-volume-id> nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: topology.ebs.csi.aws.com/zone operator: In values: - example-az
注:****サンプル文字列はすべて、必要とする値に置き換えてください。**StorageClassName ** パラメータ値は、空の文字列「****」に設定しておいてください。
-
kubectl コンテキストをクラスター B に切り替えてから、ワークロードをデプロイします。
kubectl config use-context <example-clusterB-context> kubectl apply -f workloadB.ym
注: example-clusterB-context は、自分のコンテキストに置き換えてください。
複数のポッドが動作していてコンテンツが同じであることを確認する
-
異なったクラスター間で認証を行い、次のコマンドを実行します。
kubectl get pods
クラスター A の出力例:
NAME READY STATUS RESTARTS AGE example-pod-a 1/1 Running 0 18m
クラスター B の出力例:
NAME READY STATUS RESTARTS AGE example-pod-b 1/1 Running 0 3m13s
-
example-pod-a の場合、次のコマンドを実行して、ストレージに書き込まれているコンテンツを表示します。
kubectl exec -it <example-pod-a> -- cat /data/out.txt
出力例:
Fri Sep 22 12:39:04 UTC 2024 on example-pod-a Fri Sep 22 12:39:19 UTC 2024 on example-pod-a Fri Sep 22 12:39:34 UTC 2024 on example-pod-a
-
example-pod-b の場合、次のコマンドを実行して、example-pod-a と同じストレージに書き込まれているコンテンツを読み取ります。
kubectl logs -f <example-pod-b>
出力例:
Fri Sep 22 12:39:04 UTC 2024 on example-pod-b Fri Sep 22 12:39:19 UTC 2024 on example-pod-b Fri Sep 22 12:39:34 UTC 2024 on example-pod-b
**注:**XFS や EXT4 などの標準ファイルシステムへは複数のサーバーから同時にアクセスすることはできません。詳細については、「考慮事項と制限事項」を参照してください。
関連情報
関連するコンテンツ
- 質問済み 1年前lg...
- 質問済み 2ヶ月前lg...
- 質問済み 5年前lg...
- 質問済み 3ヶ月前lg...
- AWS公式更新しました 2年前