スキップしてコンテンツを表示

Amazon EKS で Amazon EBS Multi-Attach を使用して、同じボリュームを複数のワークロードにアタッチするにはどうすればよいですか?

所要時間3分
0

Amazon Elastic Kubernetes Service(Amazon EKS)で、複数のクラスターにまたがる複数のワークロードから、Amazon Elastic Block Store(Amazon EBS)の Multi-Attach を使用したいと考えています。

簡単な説明

Amazon EBS マルチアタッチでは、プロビジョンド IOPS SSD (io1 または io2) ボリューム 1 つを同じアベイラビリティーゾーンの複数のインスタンスにアタッチできます。マルチアタッチを使用すると、異なる Amazon EKS クラスターの複数のワークロード間で永続ストレージを共有できます。

解決策

注: AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生した場合は、「AWS CLI のエラーのトラブルシューティング」を参照してください。また、AWS CLI の最新バージョンを使用していることを確認してください。

重要: XFS や EXT4 などの標準ファイルシステムは、複数のサーバーから同時にアクセスできるようには設計されていません。クラスター化されたファイルシステムを使用して、本番環境のワークロードにおけるデータの耐障害性と信頼性を確保します。

開始する前に、Amazon EBS CSI ドライバーを、必要とされる Amazon EKS クラスターにインストールしておきます。

Amazon EBS CSI ドライバーのインストールの詳細については、「Amazon EBS で Kubernetes ボリュームストレージを使用する」を参照してください。

注: マルチアタッチ対応ボリュームは、同じアベイラビリティーゾーンにある Nitro System に構築した Linux インスタンス最大 16 個にアタッチできます。

Amazon EBS マルチアタッチを使用して、複数のクラスターにわたる複数のワークロードに同一のボリュームをアタッチするには、次の手順を実行します。

Amazon EBS ボリュームをプロビジョニングする

次の AWS CLI コマンド create-volume を実行します。

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}]'

注: example-region を実際の AWS リージョンに置き換えてください。example-az を実際のアベイラビリティーゾーンに置き換えてください。

重要: Amazon EBS Multi-Attach は、io2 ボリュームに対しては、作成されてからインスタンスにアタッチされていなければオンにできます。io1 ボリュームを作成してから Amazon EBS マルチアタッチをオンにすることはできません。

ボリューム ID を取得する

次の AWS CLI コマンド describe-volumes を実行します。

aws ec2 describe-volumes --filters "Name=tag:Name,Values=multi-attach-eks*" --query "Volumes[*].{ID:VolumeId}" --region example-region

注: example-region を実際の AWS リージョンに置き換えます。

ストレージクラスを作成する

次の設定でストレージクラスマニフェストを作成します。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: io2
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
  type: io2
  iops: "2000"

ストレージクラスを適用します。

kubectl apply -f storageclass.yaml

クラスター A に永続ワークロードをプロビジョニングする

次のマニフェストを workloadA.yaml という名前で作成します。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: example-pv-claim-name-a
spec:
  storageClassName: io2
  volumeName: example-pv-name-a
  accessModes:
    - ReadWriteMany
  volumeMode: Block
  resources:
    requests:
      storage: 10Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: example-pod-a
spec:
  containers:
    - name: <example-pod-container-name>
      image: centos:6.6
      command: ["/bin/sh"]
      args: ["-c", "while true; do echo $(date -u) on pod A >> /data/out.txt; sleep 15; done"]
      volumeDevices:
        - name: example-volume-device-name
          devicePath: "/dev/xvda"
  volumes:
    - name: example-volume-device-name
      persistentVolumeClaim:
        claimName: example-pv-claim-name-a
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv-name-a
spec:
  storageClassName: io2
  volumeMode: Block
  accessModes:
    - ReadWriteMany
  capacity:
    storage: 10Gi
  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

注: マニフェスト内のすべての例の文字列を実際の値に置き換えます。

同一のボリューム ID を使用して、クラスター B に別のワークロードを作成する

次のマニフェストを workloadB.yaml という名前で作成します:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: example-pv-claim-name-b
spec:
  storageClassName: io2
  volumeName: example-pv-name-b
  accessModes:
    - ReadWriteMany
  volumeMode: Block
  resources:
    requests:
      storage: 10Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: example-pod-b
spec:
  containers:
    - name: example-pod-container-name
      image: centos:6.6
      command: ["/bin/sh"]
      args: ["-c", "while true; do echo $(date -u) on pod B >> /data/out.txt; sleep 15; done"]
      volumeDevices:
        - name: example-volume-device-name
          devicePath: "/dev/xvda"
  volumes:
    - name: example-volume-device-name
      persistentVolumeClaim:
        claimName: example-pv-claim-name-b
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv-name-b
spec:
  storageClassName: io2
  volumeMode: Block
  accessModes:
    - ReadWriteMany
  capacity:
    storage: 10Gi
  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

注: すべての例の文字列を実際の値に置き換えてください。

kubectl コンテキストをクラスター B に切り替え、ワークロードをデプロイします:

kubectl config use-context example-clusterB-context
kubectl apply -f workloadB.yaml

注: example-clusterB-context は、実際のクラスター B のコンテキストに置き換えてください。

複数のポッドが動作していてコンテンツが同じであることを確認する

異なるクラスター間で認証を行い、次のコマンドを実行します。

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

関連情報

Attach an EBS volume to multiple EC2 instances using Multi-Attach (マルチアタッチを使用して複数の EC2 インスタンスに EBS ボリュームをアタッチする)

Enable Multi-Attach for an Amazon EBS volume (Amazon EBS ボリュームのマルチアタッチを有効にする)

Amazon EBS で Kubernetes ボリュームストレージを使用する

What is Amazon Elastic File System? (Amazon Elastic File System について)

AWS公式更新しました 9ヶ月前
コメントはありません