Comment puis-je utiliser Amazon EBS Multi-Attach pour attacher le même volume sur plusieurs charges de travail dans Amazon EKS ?

Lecture de 6 minute(s)
0

Je souhaite utiliser Amazon Elastic Block Store (Amazon EBS) Multi-Attach en vue de gérer plusieurs charges de travail sur différents clusters dans Amazon Elastic Kubernetes Service (Amazon EKS).

Brève description

Lorsque vous créez une charges de travail grâce à des fonctionnalités comme la mémoire persistante dans Amazon EKS à l’aide du stockage Amazon EBS, le type de volume par défaut est gp2. Amazon EBS Multi-Attach vous permet d’attacher un volume SSD IOPS provisionnés (io1 ou io2) sur plusieurs instances dans la même zone de disponibilité.

Amazon EBS Multi-Attach n’est pas pris en charge sur les volumes SSD à usage général tels que gp2 et gp3. Le pilote Amazon EBS CSI ne prend pas en charge l’attachement simultané de plusieurs volumes sur des charges de travail s’exécutant sur différents nœuds d’un même cluster.

Pour attacher le même stockage persistant Amazon EBS à plusieurs charges de travail sur différents clusters, utilisez des volumes SSD IOPS provisionnés. Assurez-vous que les pods s’exécutent sur des nœuds de travail situés dans la même zone de disponibilité (AZ) entre les clusters.

Remarque : si vos charges de travail se trouvent dans plusieurs zones de disponibilité dans le même cluster ou dans des clusters différents, utilisez Amazon Elastic File System (Amazon EFS). Pour plus d’informations, consultez Create an Amazon EFS file system for Amazon EKS sur le site Web de GitHub.

Résolution

Avant de commencer, assurez-vous que le pilote Amazon EBS CSI est installé dans les clusters Amazon EKS requis.
Remarque : les volumes compatibles Multi-Attach peuvent être attachés sur un maximum de 16 instances Linux créées sur le système Nitro et situées dans la même zone de disponibilité.

Pour utiliser Amazon EBS Multi-Attach afin d'attacher un volume sur plusieurs charges de travail dans plusieurs clusters, procédez comme suit.

Provisionner un volume Amazon EBS

Pour provisionner un volume Amazon EBS, procédez comme suit :

  1. Provisionnez un volume de manière statique :
    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}]'
    Remarque : remplacez**<example-region>** par la région AWS requise. Remplacez <example-az> par la zone de disponibilité requise.
  2. Si vous disposez déjà d’une charge de travail ayant un volume gp2 ou gp3, il convient tout d’abord de créer un instantané du volume. Créez ensuite un volume io2 à partir de cet instantané. 
    Remarque : Amazon EBS Multi-Attach ne peut pas être activé pour les volumes io1 une fois qu'ils ont été créés. Amazon EBS Multi-Attach peut être activé pour les volumes io2 après leur création s’ils ne sont pas attachés à des instances. Pour l’approvisionnement dynamique du stockage io2 dans Amazon EKS, spécifiez le mode immédiat pour approvisionner le volume sans le pod, afin de créer la classe de stockage. Assurez-vous d’activer Amazon EBS Multi-Attach avant de créer le pod.

Récupérer l’ID du volume

Récupérez l’ID du volume qui a été approvisionné pour la charge de travail :

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

Remarque : remplacez exemple-region par la région AWS requise.

Approvisionner une charge de travail persistante dans un cluster existant à l’aide de l’ID du volume précédent

  1. Créez le manifeste suivant nommé 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>

    Remarque : remplacez toutes les chaînes exemple de la commande suivante par les valeurs requises. Assurez-vous que la valeur du paramètre storageClassName est définie sur des chaînes "" vides.

  2. Changez le contexte kubectl en cluster A, puis lancez la charge de travail :

    kubectl config use-context <example-clusterA-context>  
    kubectl apply -f workloadA.yml

Utiliser l’ID du volume précédent pour créer une autre charge de travail dans un autre cluster

  1. Créez et déployez le manifeste suivant nommé 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

    Remarque : veillez à remplacer toutes les chaînes exemple par les valeurs requises. Assurez-vous que la valeur du paramètre storageClassName est définie sur des chaînes "" vides.

  2. Changez le contexte kubectl en cluster B, puis lancez la charge de travail :

    kubectl config use-context <example-clusterB-context>
    kubectl apply -f workloadB.ym

    Remarque : remplacez exemple-clusterB-context par votre contexte.

Vérifier que les pods fonctionnent et ont le même contenu

  1. Identifiez-vous sur les différents clusters et exécutez la commande suivante :

    kubectl get pods

    Exemple de sortie pour le cluster A :

    NAME                          READY   STATUS    RESTARTS   AGE
    example-pod-a                 1/1     Running   0          18m  

    Exemple de sortie pour le cluster B :

    NAME                          READY   STATUS    RESTARTS   AGE
    example-pod-b                 1/1     Running   0          3m13s
  2. Pour exemple-pod-a, exécutez la commande suivante, afin d’afficher le contenu écrit dans le stockage :

    kubectl exec -it <example-pod-a> -- cat /data/out.txt

    Exemple de sortie :

    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
  3. Pour exemple-pod-b, exécutez la commande suivante, afin de lire le contenu écrit dans le même stockage que exemple-pod-a :

    kubectl logs -f <example-pod-b>

    Exemple de sortie :

    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

Remarque : les systèmes de fichiers standard tels que XFS et EXT4 ne sont pas accessibles simultanément sur plusieurs serveurs. Pour plus d’informations, consultez la section Considérations et limites.

Informations connexes

Qu’est-ce qu’Amazon Elastic File System ?

AWS OFFICIEL
AWS OFFICIELA mis à jour il y a 8 mois