Come posso ripristinare, ridimensionare o creare uno snapshot dello spazio di archiviazione persistente EBS in Amazon EKS per il ripristino di emergenza o quando viene superata la velocità di modifica di EBS?

Ultimo aggiornamento: 09/11/2022

Desidero utilizzare uno snapshot dello spazio di archiviazione persistente di Amazon Elastic Block Store (Amazon EBS) in Amazon Elastic Kubernetes Service (Amazon EKS) per il ripristino di emergenza. Come posso creare, ridimensionare o ripristinare uno snapshot di questo tipo? Oppure, ho superato la mia percentuale di modifiche di Amazon EBS. Tuttavia, devo comunque ridimensionare, ripristinare o creare un'istantanea del mio storage persistente Amazon EBS in Amazon EKS.

Breve descrizione

Stai modificando il tuo spazio di archiviazione persistente Amazon EBS in Amazon EKS e ricevi il seguente errore:

Codice di errore: Client.VolumeModificationRateExceeded
Messaggio di errore: Hai raggiunto il limite massimo di velocità di modifica per volume. Attendi almeno 6 ore tra le modifiche per volume EBS

Dopo aver modificato un volume, è necessario attendere almeno sei ore prima di poterlo modificare di nuovo. Prima di modificarlo nuovamente, assicurati che il volume sia in uso o disponibile.

La tua organizzazione potrebbe avere un obiettivo di ripristino di emergenza (DR) con un obiettivo del tempo di ripristino (RTO) inferiore a sei ore. Per gli RTO che durano meno di sei ore, crea uno snapshot e ripristina il volume utilizzando il driver Amazon EBS Container Storage Interface (CSI).

Risoluzione

Nota: se ricevi messaggi di errore durante l'esecuzione dei comandi dell'interfaccia della linea di comando AWS (AWS CLI), assicurati di utilizzare la versione più recente di AWS CLI.

Usa il driver Amazon EBS CSI e il programma di creazione di snapshot esterno per effettuare le seguenti operazioni:

  1. Crea uno snapshot Amazon EBS di PersistentVolumeClaim.
  2. Ripristina il PersistentVolumeClaim.
  3. Associa PersistentVolumeClaim al carico di lavoro.

Prerequisiti:

Installa il driver Amazon EBS CSI con il programma di creazione snapshot esterno

1.    Controlla se disponi di un provider IAM OpenID Connect (OIDC) esistente per il cluster:

% cluster_name=ebs
% oidc_id=$(aws eks describe-cluster --name cluster_name --query "cluster.identity.oidc.issuer" --output text | cut -d '/' -f 5)
% aws iam list-open-id-connect-providers | grep $oidc_id

Nota: sostituisci cluster_name con il nome del cluster.

Output di esempio:

"Arn": "arn:aws:iam::XXXXXXXXXX:oidc-provider/oidc.eks.eu-west-1.amazonaws.com/id/B7E2BC2980D17C9A5A3889998CB22B23"

Nota: se non disponi di un provider IAM OIDC, creane uno per il tuo cluster.

2.    Installa il programma di creazione snapshot esterno.
Nota: devi installare il programma di creazione snapshot esterno prima di installare il componente aggiuntivo Amazon EBS CSI. Inoltre, dovrai installare i componenti del programma di creazione snapshot esterno nel seguente ordine:

CustomResourceDefinition (CRD) per volumesnapshotclasses, volumesnapshots e volumesnapshotcontents

mkdir crd
cd crd
wget https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/kustomization.yaml
wget https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
wget https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml
wget https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml
kubectl apply -k ../crd

RBAC, ad esempio ClusterRole e ClusterRoleBinding

kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml

Implementazione del controller

kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml

3.    Crea il ruolo IAM del tuo plug-in Amazon EBS CSI usando eksctl:

eksctl create iamserviceaccount \
  --name ebs-csi-controller-sa \
  --namespace kube-system \
  --cluster cluster_name \
  --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
  --approve \
  --role-only \
  --role-name AmazonEKS_EBS_CSI_DriverRole

4.    Aggiungi il componente aggiuntivo Amazon EBS CSI utilizzando eksctl:

eksctl create addon --name aws-ebs-csi-driver --cluster cluster_name --service-account-role-arn arn:aws:iam::account_id:role/AmazonEKS_EBS_CSI_DriverRole --force

Nota: sostituisci account_id con il tuo ID account AWS.

5.    Verifica che il driver Amazon EBS CSI e i pod del programma di creazione snapshot esterno siano in esecuzione:

% kubectl get pods -A | egrep "csi|snapshot"

Crea uno StatefulSet con lo spazio di archiviazione persistente di Amazon EBS

1.    Scarica i manifesti dal sito Web di GitHub.

2.    Crea StorageClass e VolumeSnapshotClass:

% kubectl apply -f manifests/classes/

Output di esempio:

volumesnapshotclass.snapshot.storage.k8s.io/csi-aws-vsc created
storageclass.storage.k8s.io/ebs-sc created

3.    Distribuisci lo StatefulSet sul tuo cluster insieme a PersistentVolumeClaim:

% kubectl apply -f manifests/app/

Output di esempio:

service/cassandra created
StatefulSet.apps/cassandra created

4.    Controlla se i pod si trovano nello stato Running (In esecuzione):

% kubectl get pods

Output di esempio:

NAME         READY  STATUS   RESTARTS  AGE
cassandra-0  1/1    Running  0         33m
cassandra-1  1/1    Running  0         32m
cassandra-2  1/1    Running  0         30m

5.    Verifica che il PersistenVolumeClaim sia associato al tuo PersisentVolume:

% kubectl get pvc

Output di esempio:

NAME                                              STATUS  VOLUME                                    CAPACITY ACCESS MODES STORAGECLASS  AGE

persistentvolumeclaim/cassandra-data-cassandra-0  Bound   pvc-b3ab4971-37dd-48d8-9f59-8c64bb65b2c8  2Gi      RWO          ebs-sc        28m
persistentvolumeclaim/cassandra-data-cassandra-1  Bound   pvc-6d68170e-2e51-40f4-be52-430790684e51  2Gi      RWO          ebs-sc        28m
persistentvolumeclaim/cassandra-data-cassandra-2  Bound   pvc-d0403adb-1a6f-44b0-9e7f-a367ad7b7353  2Gi      RWO          ebs-sc        26m
...

Nota: prendi nota dei nomi di ogni PersistentVolumeClaim da confrontare con i nomi di PersistentVolumeClaim nel manifesto dello snapshot.

6.    Per testare lo StatefulSet, scrivi il contenuto su PersistentVolumeClaim:

for i in {0..2}; do kubectl exec "cassandra-$i" -- sh -c 'echo "$(hostname)" > /cassandra_data/data/file.txt'; done

Crea uno snapshot

Il persistentVolumeClaimName nel manifesto dello snapshot deve corrispondere al nome del PersistentVolumeClaim creato per ogni pod nello StatefulSet. Ad esempio:

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: cassandra-data-snapshot-0
spec:
  volumeSnapshotClassName: csi-aws-vsc
  source:
    persistentVolumeClaimName: cassandra-data-cassandra-0

1.    Crea uno snapshot da ogni PersistenVolumeClaim:

% kubectl apply -f manifests/snapshot/

Output di esempio:

volumesnapshot.snapshot.storage.k8s.io/cassandra-data-snapshot-0 created
volumesnapshot.snapshot.storage.k8s.io/cassandra-data-snapshot-1 created
volumesnapshot.snapshot.storage.k8s.io/cassandra-data-snapshot-2 created

2.    Una volta che lo stato è Completed (Completato), verifica che gli snapshot siano disponibili sulla console Amazon Elastic Compute Cloud (Amazon EC2):

aws ec2 describe-snapshots --filters "Name=tag-key,Values=*ebs*" --query 'Snapshots[*].{VOL_ID:VolumeId,SnapshotID:SnapshotId,State:State,Size:VolumeSize,Name:[Tags[?Key==`Name`].Value] [0][0]}' --output table
---------------------------------------------------------------------------------------------------------------------------------------
|                                                          DescribeSnapshots                                                          |
+------------------------------------------------------------+-------+-------------------------+------------+-------------------------+
|                            Name                            | Size  |       SnapshotID        |   State    |         VOL_ID          |
+------------------------------------------------------------+-------+-------------------------+------------+-------------------------+
|  ebs-dynamic-snapshot-c6c9cb3c-2dab-4833-9124-40a0abde170d |  2    |  snap-057c5e2de3957d855 |  pending   |  vol-01edf53ee26a615f5  |
|  ebs-dynamic-snapshot-1c1ad0c5-a93a-468f-ab54-576db5d630d4 |  2    |  snap-02bf49a3b78ebf194 |  completed |  vol-0289efe54525dca4a  |
|  ebs-dynamic-snapshot-760c48e7-33ff-4b83-a6fb-6ef13b8d31b7 |  2    |  snap-0101c3d2efa40af19 |  completed |  vol-0fe68c9ac2f6375a4  |
+------------------------------------------------------------+-------+-------------------------+------------+-------------------------+

Ripristina lo snapshot

Puoi ripristinare un PersistentVolumeClaim da uno snapshot creato da un PersistentVolumeClaim esistente utilizzando lo stesso nome di PersistentVolumeClaim. Quando crei nuovamente lo StatefulSet, PersistentVolumeClaim fornisce dinamicamente un PersistentVolume e viene automaticamente associato ai pod StatefulSet. Il formato del nome di PersistenVolumeClaim per StatefulSet è: `PVC_TEMPLATE_NAME-STATEFULSET_NAME-REPLICA_INDEX`.

Per ripristinare uno snapshot, completa questi passaggi:

1.    Elimina il carico di lavoro StatefulSet esistente:

kubectl delete -f manifests/app/Cassandra_statefulset.yaml

Nota: l'eliminazione del carico di lavoro elimina anche i pod StatefulSet. Lo snapshot che hai creato fungerà da backup.

Output di esempio:

statefulset.apps "cassandra" deleted

2.    Elimina forzatamente il PersistentVolumeClaim:

for i in {0..2}
do
  kubectl delete pvc cassandra-data-cassandra-$i --force
done

Nota: l'eliminazione di PersistentVolumeClaim elimina anche PersistentVolume.

3.    Ripristina PersistentVolumeClaim dallo snapshot utilizzando lo stesso nome del PersistentVolumeClaim creato:

kubectl apply -f manifests/snapshot-restore/

Output di esempio:

persistentvolumeclaim/cassandra-data-cassandra-0 created
persistentvolumeclaim/cassandra-data-cassandra-1 created
persistentvolumeclaim/cassandra-data-cassandra-2 created

4.    Verifica che ogni PersistentVolumeClaim sia nello stato Pending (In sospeso):

kubectl get pvc

Output di esempio:

NAME                         STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
cassandra-data-cassandra-0   Pending                                      ebs-sc         24s
cassandra-data-cassandra-1   Pending                                      ebs-sc         23s
cassandra-data-cassandra-2   Pending                                      ebs-sc         22s

5.    Crea nuovamente lo StatefulSet con il manifesto originale:

kubectl apply -f manifests/app-restore/

Nota: per ridimensionare lo spazio di archiviazione, definisci lo StatefulSet con una nuova dimensione di archiviazione.

Output di esempio:

StatefulSet.apps/cassandra created

6.    Controlla il contenuto dello spazio di archiviazione di Amazon EBS per confermare che lo snapshot e il ripristino funzionino:

for i in {0..2}; do kubectl exec "cassandra-$i" -- sh -c 'cat /cassandra_data/data/file.txt'; done
cassandra-0
cassandra-1
cassandra-2

Ridimensiona PersistentVolumeClaim

Puoi modificare il file .spec.resources.requests.storage di PersistentVolumeClaim per riflettere automaticamente la dimensione definita nel manifesto StatefulSet:

for i in {0..2}
do
  echo "Resizing cassandra-$i"
  kubectl patch pvc cassandra-data-cassandra-$i -p '{ "spec": { "resources": { "requests": { "storage": "4Gi" }}}}'
done

Nota: 4Gi è un esempio di dimensione di archiviazione. Definisci una dimensione di archiviazione adatta al tuo caso d'uso.

Verifica che le nuove dimensioni di archiviazione siano visualizzate nella console Amazon EC2 e nei pod:

% aws ec2 describe-volumes --filters "Name=tag-key,Values=*pvc*" --query 'Volumes[*].{ID:VolumeId,Size:Size,Name:[Tags[?Key==`Name`].Value] [0][0]}' --output table
-------------------------------------------------------------------------------------------
|                                     DescribeVolumes                                     |
+------------------------+--------------------------------------------------------+-------+
|           ID           |                         Name                           | Size  |
+------------------------+--------------------------------------------------------+-------+
|  vol-01266a5f1f8453e06 |  ebs-dynamic-pvc-359a87f6-b584-49fa-8dd9-e724596b2b43  |  4    |
|  vol-01b63a941450342d9 |  ebs-dynamic-pvc-bcc6f2cd-383d-429d-b75f-846e341d6ab2  |  4    |
|  vol-041486ec92d4640af |  ebs-dynamic-pvc-fa99a595-84b7-49ad-b9c2-1be296e7f1ce  |  4    |
+------------------------+--------------------------------------------------------+-------+

% for i in {0..2}
do
  echo "Inspecting cassandra-$i"
  kubectl exec -it cassandra-$i -- lsblk
  kubectl exec -it cassandra-$i -- df -h
done...

Emetti i seguenti comandi Kubectl per ripulire il tuo StatefulSet

Per eliminare le risorse che hai creato per il tuo StatefulSet, emetti i seguenti comandi kubectl:

app-restore

kubectl delete -f manifests/app-restore

snapshot-restore

kubectl delete -f manifests/snapshot-restore

snapshot

kubectl delete -f manifests/snapshot

classes

kubectl delete -f manifests/classes

Cassandra

kubectl delete -f manifests/app/Cassandra_service.yaml

Questo articolo è stato utile?


Benötigen Sie Hilfe zur Fakturierung oder technischen Support?