재해 복구를 위해 또는 EBS 수정률을 초과한 경우 Amazon EKS에서 EBS 영구 스토리지 스냅샷을 복원, 크기 조정 또는 생성하려면 어떻게 해야 하나요?
최종 업데이트 날짜: 2022년 11월 9일
재해 복구에 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 드라이버 및 외부 스냅샷을 사용하여 다음 작업을 수행하세요.
- PersistentVolumeClaim의 Amazon EBS 스냅샷을 생성합니다.
- PersistentVolumeClaim을 복원합니다.
- PersistentVolumeClaim을 워크로드에 바인딩합니다.
사전 조건:
- 워커 노드가 있는 기존 Amazon EKS 클러스터. Amazon EKS 클러스터가 없는 경우 Amazon EKS 클러스터를 생성하세요.
- AWS CLI, eksctl 및 kubectl가 최신 버전입니다.
- 서비스 계정을 위한 Amazon EBS CSI 드라이버 AWS 자격 증명 및 액세스 관리(IAM) 역할.
외부 스냅샷과 함께 아마존 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
ClusterRole 및 ClusterRoleBinding과 같은 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. StorageClass 및 VolumeSnapshotClass를 생성하세요.
% 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. PersistenVolumeClaim이 PersisentVolume에 바인딩 되었는지 확인하세요.
% 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을 재생성하면 PersistentVolumeClaim이 PersistentVolume을 동적으로 프로비저닝하고 스테이트풀셋 포드에 자동으로 바인딩됩니다. 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