-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Enhancement of External Snapshot Management using Go and Libvirt
0. 배경지식
클릭하여 상세 내용 확인
0.1 QCOW2와 CoW 메커니즘
- QCOW2 (QEMU Copy On Write)
- QEMU/KVM 환경의 표준 디스크 이미지 포맷이다.
- 데이터가 실제로 기록될 때만 저장 공간을 할당하는 Thin Provisioning을 지원하며, 스냅샷, 압축, 암호화 기능을 내장하고 있다.
- CoW (Copy-on-Write)
- 데이터를 수정할 때 원본을 덮어쓰지 않고, 변경된 데이터(Delta)만 새로운 공간(또는 파일)에 기록하는 방식이다.
- 이 방식을 통해 원본 데이터(Base Image)를 보존하면서도 스토리지 공간을 효율적으로 사용할 수 있다.
0.2 내부 스냅샷(Internal Snapshot)
[Figure 1] 내부 스냅샷 구조도 (Internal Snapshot Chain Structure)
- 정의
- 별도의 파일 생성 없이, 단일 QCOW2 파일 내부에 스냅샷 데이터를 저장하는 방식이다
- 작동 원리 (Reference Counting)
- 스냅샷 생성 시, 현재 시점의 메타데이터(L1/L2 Table)를 파일 내 별도 공간(Snapshot Table)에 복제한다.
- 데이터 블록(Cluster) 자체를 복사하지 않고, 해당 블록의 참조 카운트(Reference Count)를 증가시켜 “이 데이터는 스냅샷이 사용 중임”을 표시한다.
- 구조적 특징 (Flat Structure)
- 외부 스냅샷과 달리 부모-자식 간의 물리적 파일 의존성이 없는 플랫(Flat) 구조이다
- 각 스냅샷은 독립적인 체크포인트로 관리되므로, 중간 시점의 스냅샷을 삭제해도 다른 스냅샷에 영향을 주지 않는다
- 한계
- 모든 데이터가 단일 파일에 누적되므로 파일 크기가 비대해지며, 특정 시점의 데이터만 외부로 추출(Export)하기 어렵다.
- -> 내부 스냅샷 자체는 libvirt 자체에서 관리되고 유지가 가능하기 때문에 크게 건들일 내용이 없음.
0.3 외부 스냅샷(External Snapshot)
[Figure 2] 외부 스냅샷 체인 구조도 (External Snapshot Chain Structure)
- 정의
- 스냅샷 데이터를 원본 파일 내부에 저장하지 않고, 물리적으로 분리된 별도의 파일(File)에 저장하는 방식이다.
- 작동 원리
- 스냅샷을 생성하는 순간, 현재까지 쓰기 작업을 수행하던 파일을 읽기 전용(Read-Only) 상태의 ’Backing File’로 전환한다.
- 동시에 새로운 빈 파일(Overlay)을 생성하여 현재의 쓰기 작업(Active Layer)을 이어받는다.
- 특징 (File Separation)
- 단일 파일 내에서 블록을 관리하는 내부 스냅샷과 달리, 스냅샷 시점마다 새로운 파일(.qcow2)이 생성되므로 파일 시스템 레벨에서 명확히 구분이 가능하다.
- 이로 인해 Live Snapshot(중단 없는 스냅샷) 구현이 가능해진다.
0.4 스냅샷 체인 구조 (Backing Chain Structure)
외부 스냅샷은 여러 개의 QCOW2 파일이 부모-자식 관계(Parent-Child Relationship)로 연결된 체인 구조를 형성한다.
- Backing File (Base Image):
- 특정 시점의 데이터를 담고 있는 부모 파일이다.
- 체인 구조가 형성되면, Backing File은 절대 수정되어서는 안 되는 읽기 전용(Read-Only) 상태로 잠긴다.
- Overlay File (현재 작업위치):
- Backing File을 참조하고 있는 자식 파일이다.
- 부모 파일 생성 이후의 변경사항만을 저장한다. VM은 항상 체인의 최상단에 있는 이 파일(Snap2.qcow2)에만 데이터를 쓴다.
1. 요약
본 제안서는 기존 **내부 스냅샷(Internal Snapshot)**의 구조적 한계를 극복하기 위해, CoW 기반 외부 스냅샷 체인(External Snapshot Chain) 구조를 설계하고 구현하는 것을 목표로 합니다.
- 핵심 기법: 원본 디스크와 분리된 오버레이(Overlay) 파일 생성 및 계층적 관리
- 기대 효과: VM 중단 시간(Downtime) 최소화 및 스토리지 효율성 제고
- 확장성: 향후 오브젝트 스토리지 연계 내보내기(Export) 및 **재해 복구(DR)**의 핵심 기반 기술로 활용
2 동기 및 배경
2.1 현재 시스템의 문제점
현재 구현된 내부 스냅샷(Internal Snapshot) 기능은 초기 단계의 요구사항은 충족했으나, 서비스 확장을 위해 다음과 같은 구조적 한계에 직면해 있다.
- 서비스 중단 리스크 (Service Latency): 기존 방식은 스냅샷 생성 시 디스크 전체에 대한 처리가 필요하거나, 긴 시간 동안 VM을 일시 정지(Pause)시켜야 한다. 이는 실시간 서비스를 저하시키는 요인이 된다.
- 데이터 격리의 부재: 스냅샷 데이터가 원본 볼륨 이미지 내부에 종속되어 있다. 이로 인해 스냅샷만 별도로 추출하여 백업하거나, 다른 스토리지로 마이그레이션 하는 것이 현재 기술적으로 불가능하다.
- 스토리지 비효율성: 변경된 데이터만 관리하는 체계가 미비하여, 스냅샷이 누적될수록 스토리지 용량 낭비가 심화될 우려가 있다.
2.2 개선의 필요성
위 문제들을 해결하고 안정적인 클라우드 스토리지 서비스를 제공하기 위해 외부 스냅샷 체인(Backing Chain) 도입이 필수적이다.
- Live Snapshot 구현: CoW 방식을 통해 스냅샷 생성 시점에 새로운 파일만 생성하고 즉시 I/O를 재개하므로, 사용자 입장에서는 ‘중단 없는 백업’ 경험을 제공할 수 있다.
- 확장 가능한 아키텍처: 각 스냅샷이 독립적인 파일(예: QCOW2)로 존재하므로, 추후 특정 시점의 스냅샷 파일을 내보내기(Export) 하거나 복제하는 기능을 유연하게 구현할 수 있다.
- 데이터 관리의 유연성: 부모-자식 관계의 체인 구조를 통해, 오래된 스냅샷을 병합(Merge/Commit)하거나 특정 시점으로 되돌리는(Revert) 등의 고급 스토리지 기능을 효율적으로 수행할 수 있다.
2.3 기대 효과
- 기술적 이점: Go 언어와 Libvirt/QEMU 기술 스택을 활용하여 표준화된 이미지 체인 관리 로직을 내재화하고, 스토리지 운영의 안정성을 확보한다.
3. 상세 설계 (Detailed Design)
3.1 기대 How(어떻게) 구현할 것인가?
본 시스템은 Libvirt의 disk-only 외부 스냅샷을 사용한다. 데이터 정합성과 운영 편의성을 위해 다음 제약을 둔다.
- 스냅샷 대상: QCOW2 포맷의 파일 기반 디스크로 한정한다.
- 저장 경로: 스냅샷 파일 경로는 libvirt가 결정한다.
- -> 저장 경로에 대한 논의도 필요할 것으로 보임. 일단 지금은 /etc/lib/kws/name/snapshots에 있음.
3.2 아키텍처 변경 사항
기존 Snapshot Service의 역할을 확장하여 Libvirt 제어와 파일 시스템 관리를 통합 수행한다.
3.3 데이터 모델 변경 (DB 스키마, API 명세 등)
- API 명세서 추가만 있을 예정.
3.4 주요 알고리즘 또는 로직 흐름
3.4.1 구현되어 있는 사항
- CreateExternalSnapshot
- 도메인 XML에서 QCOW2 file 디스크 추출
<disk snapshot="external">기반 snapshot XML 생성- DISK_ONLY(+옵션 LIVE, QUIESCE, ATOMIC)로 생성
- 메타 레지스트리 기록
- ListExternalSnapshots
- libvirt snapshot 목록 조회
- XML에서 snapshot=”external” 필터링
- 이름 리스트 반환
- RevertExternalSnapshot
- VM이 꺼져 있는지 확인 -> 꺼져 있을 때만 수행되어야 오류가 없음
- snapshot 존재/외부 여부 확인
- 도메인 XML에서 backingStore를 읽어 source를 원본으로 교체
- UpdateDeviceFlags(CONFIG)로 영구 XML 반영
- 결과적으로 체인의 한 단계 되돌림 수행
- -> 원하는 스냅샷으로 되돌릴 수 있도록 보완이 필요함.
- -> 지금은 xml의 source를 수정하는 방식인데, 해당 방법말고 다른 것이 있는지도 찾아봐야 볼 예정.
3.4.2 추가 구현 예정 알고리즘
- 체인 커밋/병합(Commit/Merge)
- 외부 스냅샷 체인은 시간이 지날수록 길어지므로, 주기적으로 block commit을 수행하여 변경분을 베이스 디스크로 병합하는 기능.
- 특정 스냅샷으로 점프 복구
- 현재 복구는 backingStore 기준 “한 단계씩” 이동이다. 향후에는 스냅샷 이름을 지정하면 해당 스냅샷 레벨로 직접 복구하도록 확장한다.
- 정리/GC(가비지 컬렉션)
- 스냅샷 삭제/커밋 후 남는 주체를 잃은 overlay나 불일치 메타를 정리한다.
- -> 운체 때, 배우는 고아 프로세스를 지운다고 보면 이해가 쉬울 듯?
3.5 에러 처리 전략
3.5.1 모니터링 및 관측 가능성 (Observability)
운영 중 장애를 감지해야 할 필요가 있다.
- 로그/메트릭: 스냅샷 생성 시간, 병합(Block Commit) 소요 시간, 현재 체인 깊이(Chain Depth) 등의 메트릭을 수집하여 Prometheus 등으로 모니터링 필요 -> 기존 로그처리 방식에 포함하여 snapshot 칸을 유지해야하나?
3.5.2 보안 고려사항(Security Consideration)
스냅샷 파일은 VM의 모든 데이터를 담고 있으므로 보안에 대한 고려가 필요하다.
libvirt 자체가 정해진 경로 외에서 관리를 하려고 하면 보안, 권한 이슈롤 접근을 못하게 한다. 해당 기능을 담당하는 모듈이 apparmor이다. 보통 허용하는 경로가 [/var/lib/libvirt/images]이나 우리가 사용하는 경로는 [/var/lib/kws] 이기 때문에 사용자정의 코드에 추가하였다.
-> 우선 동작을 위해 아래와 같은 처리를 해두었으나 해당 사항을 어떻게 처리할지 논의가 필요
- AppArmor 관련 수정 파일 (1)
- Libvirt의 보안 조력자인 virt-aa-helper가 /var/lib/kws/ 경로의 파일들을 검사할 수 있도록 허용하였다.
- /var/lib/kws/ r, 및 /var/lib/kws/** rwk, 를 추가하였음.
- 경로: (/etc/apparmor.d/local/usr.lib.libvirt.virt-aa-helper)
- AppArmor 관련 수정 파일 (2)
- 프로필 내부 중괄호({ }) 안에 /var/lib/kws/ r, 및 /var/lib/kws/** rwk, 를 추가하였음.
- 경로: (/etc/apparmor.d/libvirt/TEMPLATE.qemu)
- 수정된 사항
3.6 스냅샷 생명주기 및 보관 정책
스토리지 효율성과 VM I/O 성능(Chain Depth)을 유지하기 위해, 생성된 스냅샷의 보관 기간 및 개수를 제한하는 자동화 정책을 적용할 필요가 있다.
3.6.1 보관 정책 기준
- 개수 기반 제한 (Max Count Limit):
- 정의: 하나의 VM이 가질 수 있는 최대 스냅샷 개수를 제한
- 동작: 새로운 스냅샷 생성 요청 시, 한도(N)를 초과하면 가장 오래된 스냅샷을 자동으로 병합(Merge) 및 삭제 후 신규 생성을 진행한다.
- 목적: QCOW2 Backing Chain 깊이(Depth)가 너무 깊어져 읽기 성능이 저하되는 것을 방지.
- 기간 기반 제한 (Time-based TTL):
- 정의: 생성된 지 특정 기간이 지난 스냅샷을 만료 처리.
- 동작: 백그라운드 스케줄러가 주기적으로 만료된 스냅샷을 탐색하여 정리.
- 목적: 불필요한 과거 데이터가 점유하는 스토리지 공간 회수.
- -> 정책에 대한 논의가 필요함.
3.6.2 자동 병합 프로세스
보관 기한이 지났거나 개수를 초과한 스냅샷을 정리할 때, 단순히 파일을 지우는 것이 아니라 체인 연결을 유지하며 병합하는 과정이 필수적이다.
예시) base <- snap1 (old) <- snap2 (new)에서 snap1이 만료된 상황
- 필요한 처리 로직 (Block Commit): 시스템은 snap2의 데이터 중 snap1에 의존하는 부분을 base로 밀어 넣거나(Commit), snap2 자체를 base 위로 재배치(Rebase)한다.
- 데이터 이동이 완료되면 snap1 파일을 안전하게 삭제한다.
- 체인 구조는 base <- snap2 형태로 단축된다.
4. 하위 호환성(Backward Compatibility)
이 변경으로 인해 기존 기능이 깨질 위험이 있는가?
- 4.1 스냅샷 Backing File 내 내부 스냅샷 동결
- 동작: 외부 스냅샷 생성 시, 기존 파일 내의 내부 스냅샷은 그대로 둔다. 단, 이 파일은 이제 Read-Only이므로 내부 스냅샷을 추가/삭제/복구(Revert) 하는 작업은 차단된다.
- 4.2 마이그레이션(Migration) 계획은 무엇인가? – 모름
- 4.3 API 버전 관리 전략은 어떻게 되는가? – 모름
5. 대안 고려 (Alternatives Considered)
6. 테스트 및 배포계획
7. 향후 진행해야 할 사항
7.1 오브젝트 스토리지 통합(Object Storage Integration)
현재 로컬 파일 시스템(Local Filesystem)에 의존적인 이미지 관리 방식을 탈피하여, S3 호환(S3-Compatible) 오브젝트 스토리지를 중심으로 하는 중앙 집중형 이미지 관리 시스템을 구축할 필요가 있음.
- Base Image Repository: 모든 컴퓨트 노드가 공유하는 OS 기본 이미지(Base Image)를 오브젝트 스토리지에서 중앙 관리하고, 필요 시 각 노드로 캐싱(Caching) 하는 구조 도입.
- Snapshot Repository: 개별 스냅샷 파일(.qcow2)을 오브젝트 단위로 저장하여 관리.
+) 활용가능한 오픈소스 찾아보기

