Como é possível restaurar, redimensionar ou criar um snapshot de armazenamento persistente do EBS no Amazon EKS para recuperação de desastres ou quando a taxa de modificação do EBS é excedida?

Data da última atualização: 9/11/2022

Quero usar um snapshot de armazenamento persistente do Amazon Elastic Block Store (Amazon EBS) no Amazon Elastic Kubernetes Service (Amazon EKS) para fins de recuperação de desastres. Como faço para criar, redimensionar ou restaurar esse snapshot? Ou excedi minha taxa de modificação do Amazon EBS. Mas ainda preciso redimensionar, restaurar ou criar um snapshot do meu armazenamento persistente do Amazon EBS no Amazon EKS.

Breve descrição

Você está modificando seu armazenamento persistente do Amazon EBS no Amazon EKS e recebe o seguinte erro:

errorCode: Client.VolumeModificationRateExceeded
errorMessage: Você atingiu a taxa máxima de modificação por limite de volume. Aguarde pelo menos 6 horas entre as modificações por volume do EBS

Depois de modificar um volume, você deve esperar pelo menos seis horas antes de continuar essa modificação. Certifique-se de que o volume esteja no estado em uso ou disponível antes de modificá-lo novamente.

Sua organização pode ter um objetivo de recuperação de desastres (DR) com um objetivo de tempo de recuperação (RTO) de menos de seis horas. Para RTOs com menos de seis horas, crie um snapshot e restaure seu volume usando o driver Container Storage Interface (CSI) do Amazon EBS.

Resolução

Observação: se receber erros ao executar comandos da AWS Command Line Interface (AWS CLI), verifique se está usando a versão mais recente da AWS CLI.

Use o driver CSI do Amazon EBS e o snapshotter externo para fazer o seguinte:

  1. Criar um snapshot do Amazon EBS do PersistentVolumeClaim.
  2. Restaure PersistentVolumeClaim.
  3. Vincule PersistentVolumeClaim à workload.

Pré-requisitos:

Instalar o driver CSI do Amazon EBS com o snapshotter externo

1.    Verifique se você já tem um provedor IAM OpenID Connect (OIDC) para seu 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

Observação: substitua cluster-name pelo nome do seu cluster.

Exemplo de saída:

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

Observação: se você não tiver um provedor IAM OIDC, crie um para o seu cluster.

2.    Instale o snapshotter externo.
Observação: você deve instalar o snapshotter externo antes de instalar o complemento CSI do Amazon EBS. Além disso, você deve instalar os componentes externos do snapshotter na seguinte ordem:

CustomResourceDefinition (CRD) para 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, como ClusterRole e ClusterRoleBinding

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

Implantação do controlador

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

3.    Crie seu perfil do IAM do plugin CSI do Amazon EBS 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.    Adicione o complemento CSI do Amazon EBS usando 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

Observação: substitua account_id pelo ID da sua conta da AWS.

5.    Confirme se o driver CSI do Amazon EBS e os pods externos do snapshotter estão em execução:

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

Criar um StatefulSet com o armazenamento persistente do Amazon EBS

1.    Baixe os manifestos do site do GitHub.

2.    Crie StorageClass e VolumeSnapshotClass:

% kubectl apply -f manifests/classes/

Exemplo de saída:

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

3.    Implante StatefulSet no seu cluster junto com PersistentVolumeClaim:

% kubectl apply -f manifests/app/

Exemplo de saída:

service/cassandra created
StatefulSet.apps/cassandra created

4.    Verifique se os pods estão no status Running (Em execução):

% kubectl get pods

Exemplo de saída:

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.    Verifique se PersistentVolumeClaim está vinculado a PersisentVolume:

% kubectl get pvc

Exemplo de saída:

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
...

Observação: observe os nomes de cada PersistentVolumeClaim para comparar com os nomes de PersistentVolumeClaim no manifesto do snapshot.

6.    Para testar StatefulSet, grave o conteúdo em PersistentVolumeClaim:

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

Criar um snapshot

persistentVolumeClaimName no manifesto do snapshot deve corresponder ao nome de PersistentVolumeClaim que você criou para cada pod em StatefulSet. Por exemplo:

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.    Crie um snapshot de cada PersistenVolumeClaim:

% kubectl apply -f manifests/snapshot/

Exemplo de saída:

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.    Depois que o estado for concluído, verifique se os snapshots estão disponíveis no console do 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  |
+------------------------------------------------------------+-------+-------------------------+------------+-------------------------+

Restaurar o snapshot

Você pode restaurar um PersistentVolumeClaim a partir de um snapshot criado de um PersistentVolumeClaim existente usando o mesmo nome de PersistentVolumeClaim. Quando você recria StatefulSet, PersistentVolumeClaim provisiona dinamicamente um PersistentVolume e é automaticamente vinculado aos pods StatefulSet. O formato do nome PersistenVolumeClaim de StatefulSet é: `PVC_TEMPLATE_NAME-STATEFULSET_NAME-REPLICA_INDEX`.

Para restaurar um snapshot, siga estas etapas:

1.    Exclua a workload existente do StatefulSet:

kubectl delete -f manifests/app/Cassandra_statefulset.yaml

Observação: a exclusão da workload também exclui os pods StatefulSet. O snapshot que você criou atua como um backup.

Exemplo de saída:

statefulset.apps "cassandra" deleted

2.    Exclua PersistentVolumeClaim à força:

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

Observação: excluir PersistentVolumeClaim também exclui PersistentVolume.

3.    Restaure PersistentVolumeClaim do snapshot usando o mesmo nome de PersistentVolumeClaim que você criou:

kubectl apply -f manifests/snapshot-restore/

Exemplo de saída:

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

4.    Verifique se cada PersistentVolumeClaim está no status Pending (Pendente):

kubectl get pvc

Exemplo de saída:

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.    Recrie StatefulSet com o manifesto original:

kubectl apply -f manifests/app-restore/

Observação: para redimensionar o armazenamento, defina StatefulSet com um novo tamanho de armazenamento.

Exemplo de saída:

StatefulSet.apps/cassandra created

6.    Verifique o conteúdo do armazenamento do Amazon EBS para confirmar se o snapshot e a restauração funcionam:

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

Redimensionar PersistentVolumeClaim

Você pode modificar .spec.resources.requests.storage de PersistentVolumeClaim para refletir automaticamente o tamanho definido no 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

Observação: 4Gi é um exemplo de tamanho de armazenamento. Defina um tamanho de armazenamento adequado ao seu caso de uso.

Confirme se o novo tamanho do armazenamento está refletido no console do Amazon EC2 e nos pods:

% 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...

Execute os seguintes comandos Kubectl para limpar StatefulSet

Para excluir os recursos criados para StatefulSet, execute os seguintes comandos 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

Este artigo ajudou?


Precisa de ajuda com faturamento ou suporte técnico?