재해 복구를 위해 또는 EBS 수정률을 초과한 경우 Amazon EKS에서 EBS 영구 스토리지 스냅샷을 복원, 크기 조정 또는 생성하려면 어떻게 해야 하나요?

6분 분량
0

재해 복구에 Amazon Elastic Kubernetes Service(Amazon EKS)의 Amazon Elastic Block Store(Amazon EBS) 영구 스토리지 스냅샷을 사용하고 싶습니다. 이러한 스냅샷을 생성, 크기 조정 또는 복원하려면 어떻게 해야 하나요? 또는 Amazon EBS 수정률을 초과했습니다. 하지만 여전히 Amazon EKS에 있는 Amazon EBS 영구 스토리지의 크기를 조정하거나 복원하거나 스냅샷을 생성해야 합니다.

간략한 설명

Amazon EKS에서 Amazon EBS 영구 스토리지를 수정하고 있는데 다음과 같은 오류가 발생합니다.

errorCode: Client.VolumeModificationRateExceeded
errorMessage: 볼륨 제한당 최대 수정률에 도달했습니다. EBS 볼륨당 수정 간격으로 최소 6시간 이상 기다리세요

볼륨을 수정한 후에는 최소 6시간 이상 기다려야 계속해서 볼륨을 수정할 수 있습니다. 볼륨을 다시 수정하기 전에 볼륨이 사용 중(in-use) 또는 사용 가능(available) 상태인지 확인하세요.

조직이 Recovery Time Objective(RTO)가 6시간 미만인 재해 복구(DR) 목표를 가지고 있을 수 있습니다. 6시간 미만인 RTO의 경우 Amazon EBS Container Storage Interface(CSI) 드라이버를 사용하여 스냅샷을 생성하고 볼륨을 복원하세요.

해결 방법

참고: AWS Command Line Interface(AWS CLI) 명령을 실행할 때 오류가 발생할 경우 최신 AWS CLI 버전을 사용하고 있는지 확인하세요.

Amazon EBS CSI 드라이버 및 외부 스냅샷을 사용하여 다음 작업을 수행하세요.

  1. PersistentVolumeClaim의 Amazon EBS 스냅샷을 생성합니다.
  2. PersistentVolumeClaim을 복원합니다.
  3. PersistentVolumeClaim을 워크로드에 바인딩합니다.

사전 조건:

외부 스냅샷과 함께 아마존 EBS CSI 드라이버 설치를 설치하세요.

1.    클러스터에 대한 기존 IAM OpenID Connect(OIDC) 공급자가 있는지 확인하세요.

% 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

참고: cluster_name을 클러스터 이름으로 바꿉니다.

출력 예시:

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

참고: IAM OIDC 공급자가 없는 경우 클러스터용 공급자를 하나 생성하세요.

2.    외부 스냅샷을 설치하세요.
참고: Amazon EBS CSI 추가 기능을 설치하기 전에 외부 스냅샷을 설치해야 합니다. 또한 외부 스냅샷 구성 요소를 다음 순서로 설치해야 합니다.

volumesnapshotclasses, volumesnapshots, 및 volumesnapshotcontents에 대한 CustomResourceDefinition(CRD)

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

ClusterRoleClusterRoleBinding과 같은 RBAC

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

컨트롤러 배포

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

3.    eksctl을 사용하여 아마존 EBS CSI 플러그인 IAM 역할을 생성하세요.

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.    eksctl을 사용하여 Amazon EBS CSI 추가 기능을 추가합니다.

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

참고: account_id를 AWS 사용자 계정 ID로 바꿉니다.

5.    Amazon EBS CSI 드라이버 및 외부 스냅샷 포드가 실행 중인지 확인하세요.

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

Amazon EBS 영구 스토리지로 StatefulSet 생성

1.    GitHub 웹사이트에서 매니페스트를 다운로드하세요.

2.    StorageClassVolumeSnapshotClass를 생성하세요.

% kubectl apply -f manifests/classes/

출력 예시:

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

3.    StatefulSet을 PersistentVolumeClaim과 함께 클러스터에 배포하세요.

% kubectl apply -f manifests/app/

출력 예시:

service/cassandra created
StatefulSet.apps/cassandra created

4.    포드가 실행 중(Running) 상태인지 확인하세요.

% kubectl get pods

출력 예시:

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.    PersistenVolumeClaimPersisentVolume에 바인딩 되었는지 확인하세요.

% kubectl get pvc

출력 예시:

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

참고: 스냅샷 매니페스트의PersistentVolumeClaim의 이름과 비교할 각 PersistentVolumeClaim의 이름을 기록해 두어야 합니다.

6.    StatefulSet을 테스트하려면 PersistentVolumeClaim에 콘텐츠를 작성하세요.

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

스냅샷 생성

스냅샷 매니페스트의 persistentVolumeClaimName은 StatefulSet의 각 포드에 대해 생성한 PersistentVolumeClaim의 이름과 일치해야 합니다. 예시:

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.    각 PersistenVolumeClaim 스냅샷을 생성합니다.

% kubectl apply -f manifests/snapshot/

출력 예시:

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.    상태가 완료되면 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  |
+------------------------------------------------------------+-------+-------------------------+------------+-------------------------+

스냅샷 복원

PersistentVolumeClaim과 동일한 이름을 사용하여 기존PersistentVolumeClaim에서 생성된 스냅샷에서PersistentVolumeClaim을 복원할 수 있습니다. StatefulSet을 재생성하면 PersistentVolumeClaimPersistentVolume을 동적으로 프로비저닝하고 스테이트풀셋 포드에 자동으로 바인딩됩니다. StatefulSet PersistenVolumeClaim 이름 형식은 'PVC_TEMPLATE_NAME-STATEFULSET_NAME-REPLICA_INDEX' 입니다.

스냅샷을 복원하려면 다음 단계를 따르세요.

1.    기존 스테이트풀셋 워크로드를 삭제하세요.

kubectl delete -f manifests/app/Cassandra_statefulset.yaml

참고: 워크로드를 삭제하면 StatefulSet 포드도 삭제됩니다. 생성한 스냅샷은 백업 역할을 합니다.

출력 예시:

statefulset.apps "cassandra" deleted

2.    PersistentVolumeClaim을 강제로 삭제하세요.

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

참고: PersistentVolumeClaim을 삭제하면 PersistentVolume도 삭제됩니다.

3.    생성한 PersistentVolumeClaim과 동일한 이름을 사용하여 스냅샷에서 PersistentVolumeClaim을 복원하세요.

kubectl apply -f manifests/snapshot-restore/

출력 예시:

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

4.    각 PersistentVolumeClaim보류 중(Pending) 상태인지 확인하세요.

kubectl get pvc

출력 예시:

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.    원본 매니페스트를 사용하여 StatefulSet을 재생성하세요.

kubectl apply -f manifests/app-restore/

참고: 스토리지의 크기를 조정하려면 StatefulSet을 새 스토리지 크기로 정의하세요.

출력 예시:

StatefulSet.apps/cassandra created

6.    Amazon EBS 스토리지의 콘텐츠를 확인하여 스냅샷 및 복원이 제대로 작동하는지 확인하세요.

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

PersistentVolumeClaim 크기를 조정하세요

StatefulSet 매니페스트에 정의한 크기를 자동으로 반영하도록 PersistentVolumeClaim.spec.resources.requests.storage를 수정할 수 있습니다.

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

참고: 4Gi는 예시 스토리지 크기입니다. 사용 사례에 적합한 스토리지 크기를 정의하세요.

새 스토리지 크기가 Amazon EC2 콘솔과 포드에 반영되는지 확인하세요.

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

다음 kubectl 커맨드를 실행하여 StatefulSet을 정리하세요.

StatefulSet용으로 생성한 리소스를 삭제하려면 다음 kubectl 명령어를 실행하세요.

앱-복원

kubectl delete -f manifests/app-restore

스냅샷-복원

kubectl delete -f manifests/snapshot-restore

스냅샷

kubectl delete -f manifests/snapshot

classes

kubectl delete -f manifests/classes

Cassandra

kubectl delete -f manifests/app/Cassandra_service.yaml

관련 정보

ModifyVolume

AWS 공식
AWS 공식업데이트됨 일 년 전