13년차의 서버실

서버, 인프라, 홈랩 기술 블로그

[태그:] Ceph

  • [OpenStack] OpenStack Ceph 성능 병목과 실전 해결 방안

    [OpenStack] OpenStack Ceph 성능 병목과 실전 해결 방안

    OpenStack Ceph 성능 병목과 실전 해결 방안

    OpenStack Ceph 성능 문제는 대부분 느린 디스크처럼만 보이지 않습니다

    OpenStack Ceph 성능 장애는 보통 아주 평범한 증상으로 시작합니다. 인스턴스 부팅이 길어지고, 볼륨 attach가 가끔 멈칫하고, Glance 이미지 업로드가 어느 날부터 오래 걸리죠. 사용자 입장에서는 전부 VM 디스크가 느리다고 느끼지만, 운영자 입장에서는 Ceph OSD가 느린지, OpenStack 서비스가 RBD를 제대로 쓰는지, compute node 네트워크가 막히는지, recovery/backfill이 정상적으로 자원을 쓰는지까지 같이 봐야 합니다.

    저는 OpenStack과 Ceph를 같이 볼 때 튜닝값을 먼저 만지지 않는다는 원칙을 꽤 강하게 지킵니다. 특히 운영 환경에서는 osd_max_backfills, osd_recovery_max_active, rbd_cache 같은 값을 감으로 바꾸면 일시적으로 숫자는 좋아져도 장애 반경이 넓어질 수 있거든요. 먼저 병목 위치를 좁히고, 그다음에 설정을 조정해야 합니다.

    이 글은 공식 문서식 옵션 나열이 아니라, 실제 장애 대응 순서에 가깝게 구성했습니다. 느리다는 말을 들었을 때 어떤 명령어를 먼저 치고, 어떤 로그를 같이 열고, 어떤 경우에는 Ceph가 아니라 Nova/Cinder/Glance를 의심해야 하는지에 초점을 맞춥니다.

    OpenStack Ceph 성능 분석을 위한 RBD 연동 전체 아키텍처

    OpenStack Nova, Cinder, Glance가 Ceph RBD 풀과 연결되는 구조를 한눈에 보는 개요 이미지입니다.

    OpenStack에서 Ceph 병목이 헷갈리는 이유

    OpenStack은 Ceph를 단순한 외장 스토리지처럼 쓰지 않습니다. Nova는 VM ephemeral disk를 RBD에 둘 수 있고, Cinder는 volume을 RBD image로 만들고, Glance는 base image를 Ceph pool에 저장할 수 있습니다. 이 셋이 같은 Ceph 클러스터를 쓰더라도 병목 지점은 서로 다릅니다.

    • Nova 병목: VM 생성, 부팅, live migration, libvirt secret, compute node의 RBD 접속 경로에서 드러납니다.
    • Cinder 병목: volume create/delete, snapshot, clone, flatten, attach/detach 지연으로 보입니다.
    • Glance 병목: image upload/download, image conversion, Nova의 base image clone 경로에서 나타납니다.
    • Ceph 병목: OSD latency, PG 상태, recovery/backfill, full/nearfull, 네트워크 손실, CRUSH 배치 문제로 드러납니다.

    현장에서 자주 본 실패 패턴은 HEALTH_OK니까 Ceph는 아니라고 너무 빨리 결론 내리는 경우였습니다. HEALTH_OK는 클러스터의 일관성과 위험 상태를 보는 신호에 가깝지, 모든 OSD가 빠르고 모든 클라이언트 경로가 정상이라는 보장은 아닙니다. 반대로 HEALTH_WARN이 있어도 실제 사용자 지연의 직접 원인은 libvirt secret 불일치일 수 있습니다. 그래서 Ceph와 OpenStack을 항상 나란히 봐야 합니다.

    Ceph 병목을 잡는 첫 10분: 범위를 먼저 자르세요

    처음부터 fio를 돌리거나 설정값을 바꾸지 마세요. 저는 먼저 영향을 받는 범위를 세 가지 질문으로 자릅니다.

    1. 모든 VM이 느린가, 특정 compute node의 VM만 느린가?
    2. 볼륨 작업만 느린가, 이미지 부팅과 업로드도 같이 느린가?
    3. Ceph에서 recovery/backfill/scrub 같은 내부 작업이 돌고 있는가?

    이 질문에 답하면 조사 방향이 빨라집니다. 전체 VM이 느리면 Ceph cluster, OSD, 네트워크를 봅니다. 특정 compute node만 느리면 해당 노드의 ceph.conf, keyring, libvirt secret, NIC 오류를 먼저 봅니다. 볼륨 생성만 느리면 Cinder backend와 volumes pool을 봐야지 Nova 설정부터 만지는 건 순서가 아닙니다.

    # 컨트롤러 또는 Ceph admin 노드에서 1차 확인
    ceph -s
    ceph health detail
    ceph osd tree
    ceph osd df tree
    ceph pg stat
    ceph osd perf
    ceph osd pool stats
    
    # OpenStack 관점에서 영향 범위 확인
    openstack server list --all-projects --long
    openstack volume list --all-projects --long
    openstack image list --long
    openstack hypervisor list
    openstack compute service list
    openstack volume service list
    

    ceph -s에서 recovery, backfill, degraded, undersized, peering 같은 단어가 보이면 성능 저하가 자연스럽게 따라올 수 있습니다. 이때 중요한 건 왜 그런 상태가 됐는지입니다. OSD 하나가 내려갔는지, 디스크 교체 후 재분산 중인지, full ratio에 가까운 OSD가 있는지, 네트워크가 흔들렸는지까지 연결해서 봐야 합니다.

    Ceph OSD 지연은 단독 숫자가 아니라 편차로 봅니다

    ceph osd perf는 OSD별 commit/apply latency를 보여줍니다. 여기서 가장 위험한 해석은 몇 ms 이상이면 무조건 장애처럼 외부 숫자를 그대로 가져오는 겁니다. HDD, SSD, NVMe, replication size, network, BlueStore DB/WAL 구성에 따라 정상 범위가 달라집니다. 대신 같은 장비군에서 특정 OSD만 지속적으로 튀는지, latency 상승과 iostat의 대기열 증가가 같이 움직이는지를 봐야 합니다.

    # Ceph 쪽 편차 확인
    ceph osd perf
    ceph osd df tree
    ceph osd pool stats
    
    # 특정 OSD 호스트에서만 확인합니다. admin socket이 있는 노드에서 실행해야 합니다.
    ceph daemon osd.0 perf dump | less
    
    # 운영 중 bench 명령은 부하를 만들 수 있으니 점검 창에서만 사용하세요.
    ceph tell osd.0 bench
    
    # OSD 호스트에서 디스크와 CPU 확인
    iostat -x 1
    sar -n DEV 1
    sar -u 1
    vmstat 1
    journalctl -k --since '1 hour ago'
    

    iostat -x에서는 await, aqu-sz, %util, r_await, w_await를 같이 봅니다. %util이 높고 aqu-sz가 커지면서 await도 같이 오르면 디스크 대기열이 밀리는 그림입니다. 반대로 디스크는 한가한데 Ceph latency만 높다면 네트워크, CPU, OSD 프로세스, RocksDB/WAL 장치, 또는 클라이언트 경로를 더 봐야 합니다.

    특정 OSD만 튄다면 바로 out 처리하기보다 먼저 원인을 확인하세요. 커널 로그에 I/O error가 있으면 디스크/컨트롤러 쪽 가능성이 커지고, NIC drop이 같이 보이면 네트워크 쪽입니다. OSD가 있는 호스트의 CPU steal이나 softirq가 높으면 스토리지 문제가 아니라 호스트 자원 경합일 수 있습니다.

    Ceph 병목 진단을 위해 OSD latency와 iostat 지표를 비교하는 화면

    OSD latency, iostat, 네트워크 지표를 나란히 비교하며 병목 지점을 좁히는 장면입니다.

    Nova, Cinder, Glance 설정은 같은 Ceph를 보는가부터 확인합니다

    OpenStack Ceph 연동에서 의외로 많은 문제는 Ceph 성능이 아니라 설정 일관성에서 생깁니다. Glance는 Ceph RBD에 이미지를 저장하는데 Nova는 로컬 파일 기반으로 부팅한다든지, Cinder와 Nova가 서로 다른 user/keyring을 본다든지, compute node마다 /etc/ceph/ceph.conf 내용이 다른 식입니다. 이거 진짜 자주 나옵니다.

    Cinder RBD 백엔드 예시

    [DEFAULT]
    enabled_backends = ceph
    
    [ceph]
    volume_driver = cinder.volume.drivers.rbd.RBDDriver
    volume_backend_name = ceph
    rbd_pool = volumes
    rbd_user = cinder
    rbd_ceph_conf = /etc/ceph/ceph.conf
    rbd_flatten_volume_from_snapshot = false
    rbd_max_clone_depth = 5
    rados_connect_timeout = -1
    

    rbd_flatten_volume_from_snapshot = false는 clone 기반 흐름을 살려 생성 속도를 빠르게 가져갈 수 있지만, clone depth가 깊어지면 나중에 읽기 경로가 복잡해질 수 있습니다. rbd_max_clone_depth는 그 균형점입니다. 볼륨 생성 속도가 중요하고 snapshot 계층이 잘 관리된다면 clone을 적극적으로 쓰는 편이 유리합니다. 반대로 오래된 snapshot에서 파생된 볼륨이 많이 쌓이고 삭제 정책이 느슨한 환경이라면 flatten 전략을 더 보수적으로 잡아야 합니다.

    Nova libvirt RBD 설정 예시

    [libvirt]
    images_type = rbd
    images_rbd_pool = vms
    images_rbd_ceph_conf = /etc/ceph/ceph.conf
    rbd_user = nova
    rbd_secret_uuid = 00000000-0000-0000-0000-000000000000
    
    [workarounds]
    rbd_volume_local_attach = false
    

    rbd_secret_uuid는 libvirt secret과 정확히 맞아야 합니다. 예시 UUID를 그대로 쓰면 안 됩니다. 실제 compute node에서 virsh secret-list와 virsh secret-dumpxml로 확인해야 합니다. rbd_volume_local_attach는 RBD Cinder volume을 QEMU의 native RBD 경로가 아니라 compute host의 block device로 붙이는 Nova workaround 옵션입니다. 기본값처럼 false로 두는 구성이 일반적이지만, 배포판과 암호화 볼륨 요구사항에 따라 판단해야 합니다.

    Glance RBD 저장소 예시

    [glance_store]
    stores = file,http,rbd
    default_store = rbd
    rbd_store_ceph_conf = /etc/ceph/ceph.conf
    rbd_store_user = glance
    rbd_store_pool = images
    rbd_store_chunk_size = 8
    

    Glance를 RBD에 두면 Nova가 base image를 clone하는 흐름을 만들기 쉬워집니다. 다만 이미지 변환이 필요한 포맷을 무분별하게 올리면 업로드나 부팅 경로에서 예기치 않은 지연이 생길 수 있습니다. 운영 기준으로는 Glance 이미지 포맷, Nova images_type, Cinder backend가 한 방향으로 맞아야 합니다. 이미지 저장소는 file, VM은 rbd, volume은 rbd처럼 섞인 구성이 꼭 틀린 건 아니지만, 장애 때 확인해야 할 경로가 늘어납니다.

    서비스 계정으로 직접 Ceph에 붙어보면 빠르게 걸러집니다

    운영자가 admin keyring으로 ceph -s를 쳐서 성공하는 것과 Nova/Cinder/Glance가 자기 계정으로 RBD pool에 접근하는 것은 완전히 다른 이야기입니다. 장애 대응 때는 반드시 서비스 계정으로 직접 확인해보는 편이 좋습니다.

    # compute node에서 Nova 계정 확인
    ceph -n client.nova --keyring /etc/ceph/ceph.client.nova.keyring -s
    rbd -n client.nova --keyring /etc/ceph/ceph.client.nova.keyring -p vms ls
    
    # cinder-volume 노드에서 Cinder 계정 확인
    ceph -n client.cinder --keyring /etc/ceph/ceph.client.cinder.keyring -s
    rbd -n client.cinder --keyring /etc/ceph/ceph.client.cinder.keyring -p volumes ls
    
    # glance-api 노드에서 Glance 계정 확인
    ceph -n client.glance --keyring /etc/ceph/ceph.client.glance.keyring -s
    rbd -n client.glance --keyring /etc/ceph/ceph.client.glance.keyring -p images ls
    
    # libvirt secret 확인
    virsh secret-list
    virsh secret-dumpxml 00000000-0000-0000-0000-000000000000
    

    여기서 실패하면 Ceph 튜닝은 잠시 내려놓고 인증과 권한을 봐야 합니다. 흔한 원인은 keyring 파일 경로 불일치, 파일 권한, CephX caps 부족, secret UUID 오타, 배포 자동화가 일부 노드에만 반영된 경우입니다. 특히 compute node가 여러 대일 때는 문제 없는 노드와 느린 노드의 /etc/ceph 디렉터리, Nova 설정, libvirt secret을 비교하면 빠릅니다.

    스토리지 트러블슈팅을 위한 병목 유형별 판단 기준

    아래 표는 실제 점검할 때 쓰는 분류에 가깝습니다. 한 줄짜리 정답표는 아니지만, 어디부터 볼지 정하는 데는 꽤 도움이 됩니다.

    증상 같이 볼 지표 가능성이 큰 원인 먼저 할 조치 피해야 할 대응
    전체 VM 디스크 I/O가 느림 ceph -s, ceph osd perf, iostat -x OSD 지연, recovery/backfill, 네트워크 혼잡 느린 OSD와 내부 작업 여부를 먼저 분리 Nova 설정부터 무작정 변경
    특정 compute node의 VM만 느림 sar -n DEV, journalctl -u nova-compute, virsh secret-list compute node 네트워크, keyring, libvirt secret 정상 노드와 ceph.conf/keyring/secret 비교 Ceph 클러스터 전체 재시작
    볼륨 생성·삭제가 오래 걸림 Cinder 로그, ceph osd pool stats, RBD clone depth Cinder backend 부하, snapshot/clone 누적, pool 병목 Cinder service 상태와 volumes pool I/O 확인 사용자 VM fio 테스트로만 판단
    이미지 업로드나 첫 부팅이 느림 Glance 로그, image format, Nova images_type Glance 저장소 경로, 이미지 변환, RBD clone 미사용 Glance default store와 Nova RBD 설정 일관성 확인 OSD 교체부터 검토
    평소에는 괜찮다가 특정 시간대만 느림 scrub/deep-scrub, backup, snapshot 작업 로그 예약 작업과 클라이언트 I/O 경합 작업 시간대와 Ceph 내부 작업 스케줄 조정 일시 현상으로 방치

    Ceph 최적화 튜닝값은 목적별로 다르게 접근해야 합니다

    Ceph 성능 글에서 자주 보이는 실수는 이 값을 올리면 빨라진다는 식의 단정입니다. 실제 운영에서는 값 하나가 성능, 복구 속도, 사용자 I/O 안정성을 동시에 흔듭니다. 특히 OpenStack은 사용자 VM이 계속 I/O를 내고 있으므로, 복구를 빠르게 끝내는 것과 사용자 지연을 줄이는 것 사이에서 선택해야 합니다.

    결정 지점 A를 선택할 때 B를 선택할 때 운영 판단
    recovery/backfill 속도 장애 복구를 빨리 끝내야 할 때 업무 시간 사용자 I/O를 보호해야 할 때 업무 시간에는 보수적으로, 점검 창에서는 적극적으로 조정
    Glance RBD 사용 Nova/Cinder도 Ceph를 쓰고 이미지 clone 경로를 단순화하고 싶을 때 이미지 저장소를 별도로 운영하고 Ceph 부하를 분리하고 싶을 때 Ceph 기반 OpenStack은 Glance도 RBD로 맞추면 운영이 단순해지는 경우가 많습니다
    pool 분리 images, vms, volumes의 성격과 장애 분석을 나누고 싶을 때 작은 테스트 환경이라 관리 단순성이 더 중요할 때 운영 환경에서는 최소한 images/vms/volumes는 분리하는 쪽을 권합니다
    SSD/NVMe 혼합 워크로드별 CRUSH rule과 pool을 나눌 수 있을 때 장비 수가 적고 장애 도메인이 충분하지 않을 때 빠른 디스크를 섞기만 하면 평균이 좋아지는 게 아니라 예측성이 나빠질 수 있습니다

    제가 겪은 대표 삽질: Ceph는 멀쩡한데 VM만 느린 경우

    한 번은 ceph -s가 멀쩡하고 OSD latency도 크게 튀지 않는데, 특정 compute node의 VM만 디스크가 굼뜨게 느껴진 적이 있습니다. 처음에는 Ceph 최적화 문제라고 생각했습니다. 그런데 정상 노드와 문제 노드를 비교해보니 /etc/ceph/ceph.conf 배포 시점이 달랐고, libvirt secret도 서로 맞지 않았습니다.

    이런 경우에는 Ceph dashboard만 보면 놓칩니다. Ceph는 정상인데, OpenStack 서비스 계층에서 RBD를 제대로 잡지 못하는 상태이기 때문입니다. 저는 이런 케이스 이후로 compute node 단위 문제가 나오면 아래 명령을 거의 습관처럼 칩니다.

    # 문제 compute node에서 실행
    hostname -f
    ls -l /etc/ceph/
    sha256sum /etc/ceph/ceph.conf /etc/ceph/*.keyring
    ceph -n client.nova --keyring /etc/ceph/ceph.client.nova.keyring -s
    rbd -n client.nova --keyring /etc/ceph/ceph.client.nova.keyring -p vms ls
    virsh secret-list
    journalctl -u nova-compute --since '1 hour ago'
    journalctl -u libvirtd --since '1 hour ago'
    journalctl -u virtqemud --since '1 hour ago'
    journalctl -k --since '1 hour ago'
    

    정상 노드와 문제 노드의 sha256sum이 다르면 배포 일관성부터 의심합니다. 물론 Ceph 설정 파일이 일부러 다를 수도 있지만, OpenStack compute node에서 의도치 않게 다른 MON 주소나 keyring을 보고 있다면 성능 문제가 아니라 구성 문제입니다. 이때는 튜닝보다 재배포와 서비스 재시작 순서를 차분히 잡는 게 낫습니다.

    네트워크 병목은 대역폭보다 손실과 재전송을 먼저 봅니다

    Ceph는 네트워크에 민감합니다. 그런데 운영자가 10GbE니까 괜찮겠지라고 생각하는 순간이 위험합니다. 대역폭이 충분해도 packet drop, MTU 불일치, bonding 설정 문제, 스위치 buffer 이슈가 있으면 RBD 클라이언트 입장에서는 지연으로 보입니다.

    # OSD/compute node에서 NIC 오류와 처리량 확인
    ip -s link
    netstat -s | grep -Ei 'retrans|timeout|listen|segments retransmitted'
    sar -n DEV 1
    sar -n TCP,ETCP 1
    
    # 경로와 MTU 확인
    ip route
    ip addr show
    ping -M do -s 8972 CEPH_OSD_IP
    

    MTU 9000을 쓰는 환경이라면 end-to-end로 맞아야 합니다. compute node, storage node, 스위치, bond, VLAN 어디 하나라도 다르면 큰 패킷이 깨지거나 경로에 따라 묘한 지연이 생깁니다. Jumbo frame은 제대로 맞추면 도움이 될 수 있지만, 반쯤 적용된 jumbo frame은 차라리 기본 MTU보다 나쁩니다. 저는 운영 안정성이 먼저인 환경에서는 모든 구간을 검증할 수 있을 때만 jumbo frame을 쓰는 쪽을 선호합니다.

    검증은 고쳤다가 아니라 재현 조건에서 나아졌다로 해야 합니다

    수정 후에는 단순히 HEALTH_OK만 보고 끝내지 않습니다. 같은 증상이 났던 경로를 다시 밟아야 합니다. 이미지 업로드가 문제였으면 Glance 경로를, 볼륨 attach가 문제였으면 Cinder와 Nova attach 경로를, 특정 compute node가 문제였으면 그 노드에서 새 VM을 띄워 봐야 합니다.

    # Ceph 상태 재확인
    ceph -s
    ceph health detail
    ceph osd perf
    ceph osd pool stats
    
    # RBD pool 확인
    rbd -p images ls
    rbd -p volumes ls
    rbd -p vms ls
    
    # OpenStack 리소스 흐름 확인
    openstack image list --long
    openstack volume list --all-projects --long
    openstack server list --all-projects --long
    
    # 최근 로그에서 timeout/auth/error 확인
    journalctl -u nova-compute --since '30 minutes ago' | grep -Ei 'rbd|ceph|timeout|error|auth|secret'
    journalctl -u cinder-volume --since '30 minutes ago' | grep -Ei 'rbd|ceph|timeout|error|auth'
    journalctl -u glance-api --since '30 minutes ago' | grep -Ei 'rbd|ceph|timeout|error|auth'
    

    운영 환경에서 무리한 쓰기 부하 테스트를 바로 돌리는 건 권하지 않습니다. 먼저 작은 테스트 VM과 테스트 볼륨으로 재현 경로를 확인하고, 업무 영향이 낮은 시간대에 점진적으로 부하를 올리는 편이 안전합니다. 스토리지는 한 번 흔들리면 넓게 흔들리는 영역이라서, 확인도 단계적으로 해야 합니다.

    OpenStack Ceph 성능 최적화를 위한 Nova Cinder Glance pool 매핑 구성

    Nova, Cinder, Glance 서비스가 각각 vms, volumes, images 풀을 사용하는 구성을 보여주는 이미지입니다.

    운영 체크리스트: 성능보다 먼저 무너지는 것들

    • pool 분리: 운영 환경에서는 images, vms, volumes pool을 분리해 원인 분석과 정책 적용을 쉽게 만듭니다.
    • CRUSH rule 확인: HDD, SSD, NVMe가 섞인 환경에서는 장치 class와 rule이 의도대로 적용되는지 확인합니다.
    • 시간 동기화: 모든 컨트롤러, compute, storage node에서 chrony 또는 NTP 상태를 확인합니다.
    • 네트워크 역할 분리: 가능하면 Ceph public/client traffic과 cluster replication/backfill traffic을 분리합니다.
    • 복구 작업 정책: 업무 시간과 점검 시간의 recovery/backfill 정책을 다르게 가져갈지 결정합니다.
    • 로그 보존: nova-compute, cinder-volume, glance-api, libvirt 또는 virtqemud, kernel 로그가 충분히 남도록 설정합니다.
    • 배포 일관성: ceph.conf, keyring, libvirt secret이 모든 관련 노드에 동일하게 배포되는지 검증합니다.

    여기서 제일 많이 과소평가되는 항목은 배포 일관성입니다. Ceph 자체가 아무리 튼튼해도 compute node 한 대가 오래된 ceph.conf를 보고 있으면 사용자에게는 OpenStack Ceph 성능 문제로 접수됩니다. 자동화 도구를 쓰더라도 실제 파일 checksum을 비교하는 습관이 도움이 됩니다.

    OpenStack Ceph 성능 개선 후 상태 검증 대시보드

    Ceph health, OSD latency, OpenStack 리소스 상태가 안정화된 모습을 보여주는 검증 이미지입니다.

    증상별 추천 경로: 이럴 땐 이렇게 보세요

    모든 VM이 동시에 느려졌다면 Ceph cluster 상태, OSD latency, recovery/backfill, 네트워크 손실을 먼저 봅니다. 이 경우에는 개별 VM 안에서 fio를 오래 돌리는 것보다 클러스터 전체 지표를 보는 편이 빠릅니다.

    특정 compute node의 VM만 느리다면 Ceph 전체 튜닝보다 해당 노드의 네트워크, /etc/ceph 파일, Nova 설정, libvirt secret을 먼저 비교하세요. 정상 노드와 문제 노드의 차이를 찾는 방식이 가장 빠릅니다.

    볼륨 생성·삭제·attach만 느리다면 Cinder volume 서비스와 volumes pool을 봅니다. snapshot/clone이 많이 쌓인 환경이라면 clone depth와 flatten 정책도 같이 봐야 합니다.

    이미지 업로드나 첫 부팅만 느리다면 Glance 저장소, 이미지 포맷, Nova의 RBD 사용 여부를 확인합니다. Glance와 Nova가 같은 Ceph 기반 흐름을 쓰지 않으면 불필요한 복사나 변환 경로가 끼어들 수 있습니다.

    특정 시간대만 느리다면 백업, snapshot, scrub/deep-scrub, recovery 작업 시간표를 확인하세요. 이 경우에는 하드웨어 증설보다 작업 스케줄과 우선순위 조정이 먼저일 수 있습니다.

    자주 묻는 질문

    Q. OpenStack Ceph 성능 문제는 Ceph 튜닝으로 해결되나요?

    항상 그렇지는 않습니다. 실제 현장에서는 Nova/Cinder/Glance 설정 불일치, compute node 네트워크, libvirt secret, keyring 권한 문제가 꽤 많습니다. Ceph 튜닝은 병목이 Ceph 내부에 있다는 근거를 잡은 뒤에 하는 게 안전합니다.

    Q. OSD latency가 높으면 바로 디스크 교체인가요?

    바로 교체로 가기보다는 특정 OSD만 반복적으로 튀는지, 해당 호스트의 iostat, 커널 로그, NIC 오류, recovery 상태가 같이 움직이는지 봐야 합니다. 디스크 고장일 수도 있지만 네트워크 손실이나 복구 작업 영향일 수도 있습니다.

    Q. Glance도 꼭 Ceph RBD를 써야 하나요?

    필수는 아닙니다. 다만 Nova와 Cinder가 Ceph를 쓰는 구조라면 Glance도 RBD에 두는 구성이 운영과 장애 분석 측면에서 단순해지는 경우가 많습니다. 특히 이미지 clone 경로를 활용하고 싶다면 세 서비스의 저장 경로를 함께 설계하는 편이 좋습니다.

    Q. pool을 꼭 images, vms, volumes로 나눠야 하나요?

    작은 테스트 환경에서는 하나로도 돌아갑니다. 운영 환경에서는 분리하는 쪽을 권합니다. 워크로드 성격이 다르고, 장애 분석과 용량 정책, 권한 설정, 향후 CRUSH rule 적용이 쉬워지기 때문입니다.

    관련 글로는 OpenStack Nova 트러블슈팅, Cinder 백엔드 설계, Ceph CRUSH rule 운영 가이드를 함께 연결해두면 독자가 다음 점검 단계로 이동하기 좋습니다.

    OpenStack Ceph 성능 병목 진단 흐름 요약 인포그래픽

    증상별로 Ceph, OpenStack 서비스, 네트워크, 디스크 중 어디를 먼저 확인할지 정리한 요약 이미지입니다.

    마지막 판단: 먼저 좁히고, 그다음에 바꾸세요

    OpenStack Ceph 성능 문제를 다룰 때 제 추천은 분명합니다. 전체가 느리면 Ceph cluster와 OSD부터, 특정 compute node만 느리면 해당 노드의 RBD 접속 경로부터, 볼륨만 느리면 Cinder와 volumes pool부터, 이미지 부팅만 느리면 Glance와 Nova RBD 연결부터 보세요.

    설정값 변경은 마지막 카드에 가깝습니다. ceph -s, ceph osd perf, iostat -x, 서비스 계정 RBD 접근 테스트, Nova/Cinder/Glance 로그를 통해 병목 위치를 먼저 좁히면 불필요한 튜닝을 줄일 수 있습니다. 운영에서 좋은 트러블슈팅은 멋진 한 방이 아니라, 잘못된 가능성을 빠르게 제거하는 과정에 더 가깝습니다.

  • [OpenStack] OpenStack Ceph 마이그레이션 결정 기준과 절차

    [OpenStack] OpenStack Ceph 마이그레이션 결정 기준과 절차

    OpenStack Ceph 마이그레이션 결정 기준과 절차

    OpenStack Ceph 마이그레이션을 검토할 때 저는 늘 같은 질문부터 던집니다. "지금 바꾸면 뭐가 좋아지고, 대신 무엇을 새로 운영해야 하나"라는 질문이죠. 핵심은 단순한 저장소 교체가 아니라 운영 모델의 변경입니다. Cinder 볼륨만 옮길지, Glance 이미지 저장소까지 묶을지, Nova의 에페메럴 디스크까지 Ceph RBD로 정리할지에 따라 난이도와 장애 반경이 완전히 달라지거든요. 실제 운영에서는 성능 수치보다 스케줄링 일관성, Ceph 재배치 부담, 인증 권한, 롤백 가능성이 더 자주 발목을 잡습니다.

    이 글은 OpenStack과 Ceph의 일반적인 운영 패턴을 기준으로 정리했습니다. 특정 벤더 확장 기능이나 과장된 수치 없이, 현장에서 일정 잡을 때 실제로 보는 판단 기준과 절차만 남겼습니다. 한 줄로 줄이면 이렇습니다. 기존 백엔드를 덮어쓰지 말고, 새 백엔드를 병행 등록한 뒤 신규 유입과 기존 자산 이동을 분리해서 진행하는 편이 안전합니다. 관련해서 볼륨 타입 설계나 Ceph 풀 설계 글도 함께 보시면 운영 그림이 훨씬 빨리 잡힙니다.

    OpenStack Ceph 마이그레이션 전체 아키텍처 다이어그램

    OpenStack 서비스 계층과 Ceph 풀(pool) 구조, 데이터 이동 흐름을 한눈에 보여주는 개요 이미지입니다.

    1. OpenStack Ceph 마이그레이션을 고민하는 대표적인 이유

    운영 현장에서는 보통 "Ceph가 좋아 보여서"가 아니라 아래 같은 이유로 움직입니다.

    • 풀 구조가 성장 패턴을 못 따라갈 때: 같은 풀에 서로 다른 I/O 성격의 볼륨이 섞이면 운영 판단이 흐려집니다.
    • 볼륨 타입 정책을 분리해야 할 때: 테넌트별, 워크로드별, 복제 정책별로 다른 백엔드가 필요해집니다.
    • 증설과 장애 대응의 표준화가 필요할 때: 하드웨어별 절차보다 Ceph 기준으로 운영 일관성을 맞추고 싶을 때가 많습니다.
    • 기존 백엔드가 OpenStack 스케줄러와 잘 안 맞을 때: 사용자는 타입을 골랐는데 실제 배치가 정책대로 안 되는 경우가 반복됩니다.

    제가 실무에서 특히 중요하게 보는 건 "왜 옮기느냐"보다 어디까지 옮기느냐입니다. Cinder만 옮기면 블록 스토리지 정책 문제로 한정되지만, Glance까지 함께 들어가면 이미지 캐시와 부팅 경로가 바뀝니다. Nova 에페메럴까지 손대는 순간부터는 스토리지 변경이라기보다 컴퓨트 설계 변경에 가깝습니다.

    2. OpenStack Ceph 마이그레이션 결정 기준은 성능보다 운영 책임입니다

    Ceph 도입 여부를 성능 하나로만 판단하면 나중에 꼬이기 쉽습니다. 더 정확한 질문은 이겁니다. "이 팀이 Ceph의 재배치, 권한, 풀 정책, 장애 메시지를 자기 책임으로 읽고 운영할 준비가 됐는가"예요. 이 기준이 생각보다 훨씬 현실적입니다.

    판단 항목 기존 유지가 더 나은 경우 Ceph 전환이 더 나은 경우 실무 체크 포인트
    운영 복잡도 현재 절차가 단순하고 장애 대응 경로가 고정돼 있음 확장, 복제, 장애 도메인 관리를 한 체계로 묶고 싶음 클라우드 팀이 Ceph 경고 메시지와 재배치 상태를 직접 해석할 수 있는지
    볼륨 타입 정책 사실상 단일 티어로도 충분함 테넌트/업무군별로 다른 풀과 정책이 필요함 volume_backend_name, extra_specs, 타입 명명 규칙을 먼저 설계했는지
    장애 허용 구조 외부 스토리지가 이미 안정적으로 이중화됨 CRUSH 규칙과 failure domain을 직접 설계할 가치가 있음 복제 단위가 host인지 rack인지, 기존 가용영역 설계와 충돌하지 않는지
    마이그레이션 방식 짧은 점검창도 확보하기 어려움 신규/기존을 분리하고 몇 주에 걸쳐 점진 전환 가능 붙어 있는(in-use) 볼륨의 정책 변경 허용 여부와 드라이버 지원 범위
    운영 비용 전담 인력이 없고 스토리지 운영을 단순화해야 함 학습 비용을 들여도 장기적으로 통합 운영 이득이 큼 모니터링, 알림, 장애 복구 문서가 Ceph 기준으로 이미 준비됐는지

    짧게 정리하면 이렇습니다. 볼륨 타입 분리와 점진 전환이 필요하면 Ceph 쪽이 유리하고, 운영 역량이 아직 약하면 기존 백엔드를 남겨둔 병행 운영이 맞습니다. 반대로 다운타임 제로만 바라보면서 한 번에 덮어쓰는 방식은 실무에서 꽤 위험하더라고요.

    3. OpenStack 스토리지 교체 범위를 자르면 난이도가 확 줄어듭니다

    OpenStack 스토리지 교체는 기술 문제라기보다 범위 관리 문제인 경우가 많습니다. 보통 아래 셋으로 끊습니다.

    1. Cinder 볼륨만 전환: 가장 현실적이고, 실패해도 영향 반경을 제한하기 쉽습니다.
    2. Glance 이미지까지 전환: 이미지 업로드, 캐시, 부팅 경로를 함께 봐야 합니다.
    3. Nova 에페메럴 디스크까지 전환: 성능과 일관성 이득은 크지만 컴퓨트 노드 영향이 급격히 커집니다.

    제가 추천하는 순서는 거의 같습니다. Cinder -> Glance -> Nova예요. 이유는 단순합니다. Cinder는 볼륨 타입이라는 절연층이 있지만, Nova 루트/에페메럴까지 한 번에 건드리면 인스턴스 부팅 실패가 곧바로 서비스 장애로 번지기 쉽습니다.

    실무에서 자주 보는 장면도 있습니다. 기존에는 외부 SAN을 쓰다가 "이번에 Ceph도 붙였으니 볼륨도 이미지도 같이 넘기자"고 범위를 넓히는 경우죠. 이때 Cinder 신규 볼륨은 정상 생성되는데, 부팅 지연이나 이미지 캐시 미스 때문에 운영팀이 Glance 문제를 Ceph 문제로 오해하는 일이 꽤 많습니다. 그래서 저는 첫 전환 주기에는 신규 볼륨 경로와 이미지 경로를 일부러 분리합니다. 원인 분리가 정말 편해집니다.

    4. OpenStack Ceph 마이그레이션 사전 점검

    이 단계는 체크리스트라기보다 진입 금지선에 가깝습니다. 상태가 좋지 않으면 일정부터 미루는 편이 맞습니다. 마이그레이션 자체보다, 진행 중 나타난 문제의 원인이 Ceph인지 OpenStack인지 분리하기 어려워지기 때문입니다.

    ceph -s
    ceph health detail
    ceph osd stat
    ceph osd tree
    ceph osd df tree
    ceph osd pool ls detail
    rados df
    openstack volume service list
    openstack volume type list --long
    openstack volume list --status in-use --long

    여기서는 보통 이렇게 읽습니다.

    • ceph -s: 클러스터 전체 상태와 recovery/backfill 진행 여부를 먼저 봅니다. 단순 HEALTH_WARN보다 경고 원인이 재배치인지 용량 임계치인지가 더 중요합니다.
    • ceph health detail: degraded, undersized, inactive, nearfull 계열 메시지가 보이면 이동 작업을 미룹니다.
    • ceph osd df tree: 특정 OSD만 유독 가득 찼다면 마이그레이션 중 backfill이 겹치면서 체감 성능이 흔들릴 가능성이 큽니다.
    • ceph osd pool ls detail: 새 풀의 복제 정책, CRUSH rule, autoscale 상태를 봅니다. 풀 이름만 맞고 규칙이 다르면 기대한 장애 도메인이 깨질 수 있습니다.
    • openstack volume service list: 대상 cinder-volume 서비스가 up이고 enabled인지 확인합니다.
    • openstack volume type list --long: 현재 타입과 백엔드 이름 연결이 살아 있는지 확인합니다.
    • openstack volume list --status in-use --long: 붙어 있는 볼륨 비중이 높다면 온라인 정책 변경이 가능한지부터 따져야 합니다.

    실제 실패 모드도 비슷합니다. 새 타입은 잘 만들었는데 Ceph 쪽에서 이미 backfill이 길게 돌고 있던 상황이죠. OpenStack API는 성공으로 보이는데 사용자는 I/O 지연을 바로 체감합니다. OpenStack의 성공 응답이 Ceph 내부 재배치 비용까지 끝났다는 뜻은 아니라는 점, 이 부분은 꼭 분리해서 봐야 합니다.

    OpenStack Ceph 마이그레이션 사전 점검과 볼륨 타입 매핑 이미지

    Ceph 클러스터 헬스 체크, 풀 상태, Cinder 볼륨 타입과 백엔드 이름 매핑 관계를 설명하는 이미지입니다.

    5. 백엔드 설계는 pool보다 volume type을 먼저 잡아야 합니다

    운영에서 더 오래 가는 설계는 "풀 이름 중심"이 아니라 볼륨 타입 중심입니다. 사용자는 타입을 고르고, Cinder 스케줄러는 타입의 extra_specs를 보고 백엔드를 고르거든요. 그래서 이름 규칙이 중요합니다.

    • 백엔드 섹션 이름: 운영자가 구분하기 쉬운 내부 이름
    • volume_backend_name: 타입과 연결되는 스케줄링 식별자
    • Ceph 풀 이름: 실제 데이터가 놓이는 물리적 대상

    많이 헷갈리는 지점이 하나 있습니다. [rbd-new] 같은 설정 섹션 이름과 volume_backend_name=rbd-new는 같은 개념이 아닙니다. 우연히 같게 맞출 수는 있지만, 스케줄러가 직접 참조하는 값은 섹션명이 아니라 백엔드 이름입니다. 여기 오타가 나면 타입은 멀쩡해 보여도 No valid host 오류가 나기 쉽습니다.

    5-1. OpenStack Ceph 마이그레이션용 cinder.conf 예시

    [DEFAULT]
    enabled_backends = rbd-old,rbd-new
    
    [backend_defaults]
    rbd_ceph_conf = /etc/ceph/ceph.conf
    rbd_user = cinder
    rbd_secret_uuid = 11111111-2222-3333-4444-555555555555
    volume_driver = cinder.volume.drivers.rbd.RBDDriver
    
    [rbd-old]
    volume_backend_name = rbd-old
    rbd_pool = volumes_old
    
    [rbd-new]
    volume_backend_name = rbd-new
    rbd_pool = volumes_new

    현재 Cinder 샘플 설정에서도 공통 백엔드 옵션은 [backend_defaults] 섹션을 사용합니다. 여기서 중요한 건 세 가지예요. enabled_backends에 백엔드 섹션이 모두 들어가 있는지, 각 섹션의 volume_backend_name이 타입의 extra_specs와 정확히 일치하는지, 공통 설정을 쓴다면 [backend_defaults]와 개별 섹션의 덮어쓰기 관계를 이해하고 있는지입니다.

    기존 단일 백엔드 서비스에 다중 백엔드를 붙이는 경우, Cinder 서비스 호스트명이 host에서 host@backend 형태로 바뀌는 환경도 있습니다. 이런 경우 기존 볼륨의 host 메타데이터를 갱신하지 않으면 운영이 꼬일 수 있어서, 사전에 cinder-manage volume update_host 대상 여부를 꼭 확인하는 편이 좋습니다.

    5-2. Ceph 풀과 인증 준비

    새 풀만 만들고 끝내면 안 됩니다. RBD로 쓸 풀은 초기화와 권한까지 맞아야 합니다. 저는 신규 백엔드를 붙이기 전에 아래 항목을 먼저 확인합니다.

    ceph osd pool ls detail
    rbd pool init volumes_new
    ceph auth get-or-create client.cinder \
      mon 'profile rbd' \
      osd 'profile rbd pool=volumes_new, profile rbd pool=vms, profile rbd-read-only pool=images' \
      mgr 'profile rbd pool=volumes_new, profile rbd pool=vms'
    ceph auth get-or-create client.glance \
      mon 'profile rbd' \
      osd 'profile rbd pool=images' \
      mgr 'profile rbd pool=images'

    근본 원인은 늘 비슷합니다. 풀은 만들었는데 rbd pool init이 빠졌거나, client.cinder가 새 풀에 대한 cap을 갖고 있지 않거나, Glance와 Cinder 권한을 뭉뚱그려 잡아두는 식이죠. 이런 상태에선 볼륨 생성은 되는데 attach에서 실패하거나, 이미지 기반 볼륨 생성만 유독 실패하는 식으로 증상이 갈라집니다.

    5-3. 새 볼륨 타입 생성

    openstack volume type create ceph-rbd-new
    openstack volume type set --property volume_backend_name=rbd-new ceph-rbd-new
    openstack volume type show ceph-rbd-new
    openstack volume type list --long

    운영상 의미는 명확합니다. 신규 생성 경로를 먼저 새 백엔드로 돌리고, 기존 자산 이동은 그다음에 따로 한다는 거예요. 이 분리가 되면 실패했을 때 되돌리기도 쉬워집니다.

    6. OpenStack Ceph 마이그레이션 절차: 신규 유입과 기존 자산을 분리하세요

    실무 절차는 의외로 단순합니다. 대신 순서를 어기면 비용이 바로 커집니다.

    1. 새 백엔드를 등록하고 타입을 만든다: 아직 기존 타입은 그대로 둡니다.
    2. 신규 볼륨만 새 타입으로 생성하게 유도한다: 새 데이터 유입을 먼저 분리합니다.
    3. 테스트 프로젝트에서 생성, attach, detach, 삭제까지 한 사이클을 검증한다: 생성만 확인하면 부족합니다.
    4. 저위험 볼륨부터 정책 변경 또는 마이그레이션을 시작한다: 백업성 볼륨, 비핵심 업무부터 갑니다.
    5. Ceph 재배치 상태를 보며 배치를 늘린다: API 성공률이 아니라 클러스터 안정성을 기준으로 속도를 조절합니다.
    6. 기존 타입의 신규 생성을 막는다: 잔여 볼륨만 남기고 정리 단계로 들어갑니다.

    CLI는 환경에 따라 조금씩 다르게 씁니다. 현재 openstackclient에서는 볼륨 타입 변경을 openstack volume set --type로 수행할 수 있고, 일부 운영 환경은 여전히 cinder retype를 사용합니다. 핵심은 명령 이름보다 정책 변경이 실제 데이터 이동을 유발하는지를 테스트 볼륨으로 먼저 확인하는 겁니다.

    # 현재 openstackclient 계열에서 많이 쓰는 방식
    openstack volume set \
      --type ceph-rbd-new \
      --migration-policy on-demand \
      8f1f2f0d-1111-2222-3333-444444444444
    openstack volume show 8f1f2f0d-1111-2222-3333-444444444444
    
    # 환경에 따라 여전히 사용하는 cinder client 방식
    cinder retype \
      --migration-policy on-demand \
      8f1f2f0d-1111-2222-3333-444444444444 \
      ceph-rbd-new

    관리자가 목적지를 더 강하게 통제해야 한다면 백엔드 호스트를 직접 지정하는 방식도 씁니다.

    openstack volume migrate \
      --host host01@rbd-new#volumes_new \
      8f1f2f0d-1111-2222-3333-444444444444
    openstack volume show 8f1f2f0d-1111-2222-3333-444444444444 -f yaml

    저는 보통 이렇게 고릅니다. 볼륨 타입 정책까지 함께 정리하려면 retype 계열이 낫고, 특정 백엔드 호스트나 풀을 명시적으로 통제해야 하면 migrate가 더 직접적입니다. 다만 in-use 볼륨의 재타입은 마이그레이션이 동반되면 보통 관리자 권한이 필요하고, 암호화된 in-use 볼륨은 재타입 마이그레이션이 지원되지 않는 경우가 있습니다. 이런 케이스는 무리해서 실시간 전환하지 말고 점검창을 잡는 편이 더 안전합니다.

    OpenStack Ceph 마이그레이션 절차와 데이터 이동 흐름 이미지

    신규 생성 분리, 테스트 볼륨 이동, 운영 볼륨 확장 전환 순서를 보여주는 절차형 이미지입니다.

    7. OpenStack Ceph 마이그레이션에서 자주 부딪히는 실패 모드

    증상은 비슷해 보여도 원인은 다릅니다. 저는 아래 네 가지부터 먼저 자릅니다.

    7-1. 타입은 맞는데 스케줄링이 안 됩니다

    대부분은 volume_backend_name 불일치, 백엔드 서비스 비활성화, 드라이버 초기화 실패 셋 중 하나입니다.

    grep -E 'enabled_backends|volume_backend_name|rbd_pool|rbd_user' /etc/cinder/cinder.conf
    openstack volume service list
    journalctl -u openstack-cinder-scheduler -n 200 --no-pager
    journalctl -u openstack-cinder-volume -n 200 --no-pager

    배포판에 따라 systemd 유닛명은 다를 수 있으니 서비스 이름은 현 환경 기준으로 바꿔서 보시면 됩니다. 근본 원인은 흔히 두 가지예요. 첫째, 타입은 rbd-new를 보는데 실제 백엔드는 rbd_new처럼 다른 이름으로 등록된 경우. 둘째, 드라이버가 Ceph 인증 실패로 초기화되지 않았는데 운영자가 프로세스만 살아 있다고 착각하는 경우입니다.

    7-2. Ceph 인증 문제로 생성 또는 attach가 막힙니다

    이 경우는 생성 단계와 attach 단계의 증상이 달라서 더 헷갈립니다. 새 풀에 대한 cap이 없거나, Nova와 Cinder, Glance가 참조하는 사용자명과 시크릿, 키링 경로가 어긋나 있는 경우가 많습니다. 특히 Cinder가 볼륨을 만들 수 있는 권한과 Nova/libvirt가 그 볼륨을 실제로 매핑할 수 있는 권한은 완전히 같은 문제가 아닐 수 있습니다.

    7-3. 이동은 됐는데 체감 성능이 흔들립니다

    이건 마이그레이션 명령의 성공 여부보다 Ceph 내부 상태를 먼저 봐야 합니다. recovery, backfill, nearfull 경고가 길게 이어지면 배치를 줄이거나 윈도우를 다시 잡는 편이 맞습니다. 현장에서 자주 보는 패턴은 이렇습니다. 낮 시간대에 작은 볼륨 몇 개는 멀쩡해서 속도를 올렸는데, 저녁 배치에서 대용량 볼륨과 Ceph 재배치가 겹치며 지연이 튀는 거죠. 이거 진짜 자주 나옵니다.

    7-4. 소스 풀에 고아 이미지가 남습니다

    실패한 이동, 중단된 작업, 관리자의 수동 정리 이력 때문에 원본 풀에 RBD 이미지가 남을 수 있습니다. 그렇다고 바로 지우면 안 됩니다. 먼저 OpenStack DB가 가리키는 위치와 실제 풀 위치가 일치하는지 확인해야 합니다. 저는 최소 하루 이상 운영 검증을 둔 뒤 정리합니다.

    8. 검증은 보이는지보다 원하는 위치에서 실제로 쓰는지 봐야 합니다

    마이그레이션 후 검증은 세 겹으로 합니다. OpenStack 상태, Ceph 실체, 워크로드 체감입니다.

    1. 볼륨 메타데이터 확인: 타입, 상태, migration 관련 필드 확인
    2. 대상 풀의 실제 RBD 이미지 확인: 새 풀에 이미지가 생겼는지 확인
    3. attach 후 읽기/쓰기 확인: 실제 인스턴스에서 I/O 검증
    4. 소스 풀 잔존물 확인: 즉시 삭제하지 말고 정리 후보만 분리
    openstack volume show 8f1f2f0d-1111-2222-3333-444444444444
    rbd ls volumes_new
    rbd info volumes_new/volume-8f1f2f0d-1111-2222-3333-444444444444
    rbd ls volumes_old

    저는 운영 확인을 여기서 끝내지 않습니다. 인스턴스에 붙여 파일 생성, 재마운트, 재부팅 후 재연결까지 확인합니다. 볼륨이 새 풀에 존재하는 것과, 서비스가 그 볼륨을 문제없이 소비하는 것은 다른 검증이거든요. 여기까지 봐야 마음이 놓입니다.

    OpenStack Ceph 마이그레이션 완료 검증 대시보드 이미지

    볼륨 상태 확인, 대상 풀의 RBD 이미지 존재 여부, 운영 검증 체크리스트를 보여주는 결과 이미지입니다.

    9. 언제 Ceph 스토리지 전환을 고르고, 언제 병행 운영을 고를까

    현장 추천은 꽤 분명합니다.

    • 다운타임이 거의 없고 운영 안정성이 최우선이다: 기존 백엔드를 유지한 병행 운영 후, 새 타입으로 신규를 먼저 분리하고 기존은 점진적으로 옮기세요.
    • 목표가 스토리지 통합 운영과 볼륨 정책 세분화다: Ceph 백엔드를 붙이되, 처음 범위는 Cinder로 제한하세요.
    • 팀이 Ceph 장애 메시지와 재배치를 아직 익숙하게 다루지 못한다: 바로 전면 전환하지 말고 신규 볼륨만 새 백엔드로 보내며 운영 감각부터 쌓는 편이 낫습니다.
    • 이미 Ceph를 쓰고 있고 풀 구조만 재정비하고 싶다: 풀 직접 교체보다 새 백엔드와 새 타입을 따로 만들고 정책 전환으로 정리하는 편이 안전합니다.
    • Nova 에페메럴까지 한 번에 바꾸고 싶다: 말리고 싶습니다. Cinder 경로가 안정화된 뒤 별도 프로젝트로 다루는 편이 훨씬 덜 아픕니다.

    여러 번 겪어보면 결국 덜 아픈 방법은 비슷합니다. 새 백엔드를 먼저 붙이고, 신규 생성 경로를 갈라놓고, 기존 볼륨은 업무 중요도와 Ceph 상태를 보면서 천천히 옮기는 방식이죠. 빠른 전환보다 되돌릴 수 있는 전환이 훨씬 값집니다.

    FAQ

    Q. retype와 migrate 중 무엇을 먼저 고려하면 될까요?

    볼륨 타입 정책 자체를 바꾸는 게 목적이면 retype 계열이 더 자연스럽습니다. 특정 목적지 호스트와 풀을 명시적으로 통제해야 하면 migrate가 더 직접적입니다. 다만 둘 다 실제 데이터 복사 여부는 현재 배치와 드라이버 동작에 좌우되니, 테스트 볼륨 검증부터 해보는 게 맞습니다.

    Q. 기존 백엔드는 언제 제거하는 게 좋을까요?

    신규 생성이 완전히 차단되고, 잔여 볼륨과 소스 풀의 정리 후보가 분리되고, 운영 검증 기간을 지난 뒤가 적절합니다. 저는 최소 한 템포 두고 소스 풀을 정리합니다.

    Q. Ceph가 항상 정답인가요?

    아닙니다. Ceph의 장점은 기능 자체보다 운영 일관성에 있습니다. 팀이 그 일관성을 감당할 준비가 안 돼 있다면, Ceph 도입은 기술 선택이 아니라 운영 부채가 될 수도 있습니다.

    OpenStack Ceph 마이그레이션 결정 기준 요약 이미지

    어떤 상황에서 병행 운영, 점진 전환, 즉시 전환 중 무엇을 고를지 요약한 마무리 인포그래픽입니다.

  • [스토리지] OpenStack Swift vs Ceph 선택 기준 심층 비교

    [스토리지] OpenStack Swift vs Ceph 선택 기준 심층 비교

    [스토리지] OpenStack Swift vs Ceph 선택 기준 심층 비교

    대규모 객체 스토리지(Object Storage) 이야기를 하다 보면 결국 많이 나오는 조합이 있습니다. 바로 OpenStack Swift Ceph 비교죠. 저도 처음엔 둘 다 그냥 “오브젝트 스토리지니까 비슷한 거 아닌가?” 싶었는데, 실제로 설계하고 운영해보니 성격이 꽤 다르더라고요. 특히 객체 스토리지 솔루션을 새로 도입하려는 팀, 혹은 프라이빗 클라우드(private cloud)를 운영하는 팀이라면 여기서 방향을 잘못 잡으면 나중에 운영 복잡도가 확 올라갑니다.

    제가 13년 정도 인프라 쪽에서 일하면서 느낀 건, 스토리지는 벤더 브로셔보다 운영팀의 현실이 더 중요하다는 점입니다. 성능 숫자 몇 개보다도, 장애 났을 때 복구 흐름이 명확한지, 팀이 감당할 수 있는 아키텍처인지, 기존 클라우드 스택과 얼마나 잘 붙는지가 훨씬 중요했거든요. 이번 글에서는 OpenStack Swift와 Ceph를 기능 나열식이 아니라, 실제 선택 기준 중심으로 풀어보겠습니다.

    OpenStack Swift Ceph 비교 전체 아키텍처 다이어그램

    Swift의 프록시 기반 구조와 Ceph의 클러스터형 구조를 한눈에 보여주는 비교 이미지입니다.

    1. 왜 OpenStack Swift vs Ceph 비교가 계속 나올까요?

    쉽게 말해 둘 다 분산 스토리지(Distributed Storage)이고, 둘 다 대규모 확장을 염두에 둔 설계거든요. 근데 접근 방식이 다릅니다. Swift는 오브젝트 스토리지에 좀 더 집중된 구조이고, Ceph는 오브젝트(Object), 블록(Block), 파일(File)을 함께 다룰 수 있는 범용 분산 스토리지에 가깝습니다.

    현장에서 이 차이가 바로 드러나는 순간이 있어요. 예를 들어 개발팀은 S3 호환 API만 있으면 된다고 말하는데, 플랫폼팀은 나중에 가상머신 디스크나 Kubernetes 스토리지까지 같이 보고 싶어 합니다. 이럴 때 Swift는 “오브젝트 저장소를 깔끔하게 운영”하는 쪽으로 강점이 있고, Ceph는 “스토리지 플랫폼을 하나로 통합”하는 쪽으로 무게가 실립니다.

    • Swift: 오브젝트 스토리지 중심, OpenStack 친화적
    • Ceph: 오브젝트, 블록, 파일을 아우르는 통합형
    • 선택 포인트: 기능 수보다 운영 목적과 팀 역량이 더 중요

    혹시 이런 경험 있으신가요? 처음엔 백업 저장소로 시작했는데, 나중엔 이미지 저장, 로그 아카이브, VM 디스크, 컨테이너 볼륨까지 다 얹히는 경우요. 저도 몇 번 겪었는데, 그때 초기 선택이 발목을 잡기도 했습니다.

    2. 핵심 개념 설명: Swift와 Ceph를 쉽게 풀어보면

    2-1. OpenStack Swift란?

    OpenStack Swift는 OpenStack 생태계에서 나온 오브젝트 스토리지입니다. 데이터는 Account / Container / Object 구조로 관리되고, 프록시(proxy)와 스토리지 노드(storage node), 그리고 링(ring) 기반 데이터 배치 개념이 핵심이거든요. 저도 처음 링 파일 개념을 봤을 때는 “이걸 왜 이렇게까지 나눴지?” 싶었는데, 실제로는 대규모 노드 분산과 재배치 관점에서 꽤 실용적이더라고요.

    2-2. Ceph란?

    Ceph는 객체 스토리지로만 보면 RADOS Gateway(RGW)를 통해 S3/Swift 스타일 API를 제공할 수 있고, 내부적으로는 RADOS라는 분산 객체 계층 위에 RBD(Block Device), CephFS(File System) 같은 서비스가 올라갑니다. 핵심은 CRUSH 알고리즘 기반의 데이터 배치와, 모니터(MON), 매니저(MGR), OSD(Object Storage Daemon) 조합이거든요.

    2-3. 한 줄 차이

    제가 실무에서 멘토링할 때 자주 하는 설명이 있습니다. Swift는 목적형 오브젝트 스토리지, Ceph는 스토리지 플랫폼입니다. 이 한 줄이 생각보다 많은 걸 정리해주더라고요.

    항목 OpenStack Swift Ceph
    주 용도 객체 스토리지 중심 객체, 블록, 파일 통합
    아키텍처 성격 역할 분리형, 링 기반 클러스터형, CRUSH 기반
    OpenStack 연계 친화적 Cinder, Glance, Manila 등과 폭넓게 연동
    운영 포인트 오브젝트 워크로드 최적화 통합 스토리지 운영 복잡도 관리

    3. 클라우드 스토리지 선택 기준: 무엇을 먼저 봐야 할까요?

    클라우드 스토리지 선택에서 가장 흔한 실수가 “성능이 더 좋다더라”만 보고 결정하는 거거든요. 근데 여기서 중요한 포인트! 객체 스토리지는 단순 벤치마크보다 워크로드 특성이 훨씬 중요합니다.

    1. 워크로드 유형 확인
      백업, 로그 아카이브, 미디어 저장, VM 이미지, 컨테이너 볼륨 중 무엇이 주력인지 먼저 정리합니다.
    2. API 요구사항 확인
      S3 호환성이 중요한지, OpenStack 네이티브 연동이 중요한지 봅니다.
    3. 운영팀 역량 평가
      장애 분석, 리밸런싱(rebalancing), 확장 작업을 누가 얼마나 자주 할지 생각해야 합니다.
    4. 확장 단위 확인
      단순 용량 확장인지, 멀티 서비스 확장인지에 따라 선택이 갈립니다.
    5. 장애 도메인 설계
      랙(rack), 호스트(host), 존(zone), 리전(region) 단위 복제 전략을 어떻게 가져갈지 정해야 합니다.

    제 경험상 아래처럼 정리하면 판단이 빨라졌어요.

    • 오브젝트 저장이 핵심이고 OpenStack 친화성이 중요하다: Swift 우선 검토
    • 향후 블록/파일까지 통합할 가능성이 높다: Ceph 우선 검토
    • 운영팀이 분산 스토리지 튜닝 경험이 많지 않다: 단순한 운영 모델을 먼저 고려
    • 대규모 자동화와 장기 확장을 노린다: 배치 정책과 장애 복구 절차를 먼저 설계

    4. 실전 구현: Swift와 Ceph를 어떻게 검증해보면 좋을까요?

    여기서는 “당장 프로덕션에 올리는 설치 가이드”보다는, 비교 검증용 랩(lab) 환경을 어떻게 잡으면 좋은지 중심으로 말씀드릴게요. 홈랩에서도 축소형으로 충분히 감을 잡을 수 있습니다. 저도 처음엔 큰 장비 없이 VM 몇 대로 감을 익혔어요. 삽질 좀 했습니다 ㅎㅎ

    4-1. Swift 검증 포인트

    Swift는 프록시 노드와 스토리지 노드 역할을 나누고, 링 파일을 통해 데이터 배치를 정의합니다. 실제 검증에서는 다음을 꼭 봅니다.

    • 프록시를 통해 PUT/GET 지연이 어떻게 나오는지
    • 리플리케이션(replication) 이후 데이터 일관성 흐름
    • 노드 추가 시 링 재배포 절차 난이도
    # 예시: Swift ring-builder 기본 흐름
    swift-ring-builder account.builder create 18 3 1
    swift-ring-builder container.builder create 18 3 1
    swift-ring-builder object.builder create 18 3 1
    
    swift-ring-builder account.builder add r1z1-10.0.0.11:6202/d1 100
    swift-ring-builder container.builder add r1z1-10.0.0.11:6201/d1 100
    swift-ring-builder object.builder add r1z1-10.0.0.11:6200/d1 100
    
    swift-ring-builder account.builder rebalance
    swift-ring-builder container.builder rebalance
    swift-ring-builder object.builder rebalance

    이 명령 흐름에서 중요한 건 숫자 외우는 게 아닙니다. 파티션(partition) 수, 복제 수, 장애 도메인 배치가 운영 철학을 반영한다는 점이거든요. 실제로 써보니까 여기 설계를 대충 하면 나중에 증설할 때 정말 피곤해지더라고요.

    4-2. Ceph 검증 포인트

    Ceph는 최소한 MON, MGR, OSD 구조를 이해하고 들어가야 합니다. 오브젝트 스토리지만 보더라도 결국 내부 건강 상태는 OSD 분포와 PG(Placement Group) 균형에서 드러나거든요.

    # 예시: Ceph 상태 확인과 풀(pool) 생성 흐름
    ceph -s
    ceph osd tree
    ceph health detail
    
    radosgw-admin user create --uid=testuser --display-name="Test User"
    ceph osd pool create object-test 32
    rados ls -p object-test

    여기서 초반에 꼭 확인할 건 클러스터 헬스(cluster health)입니다. API 붙이기 전에 저장 계층이 안정적인지부터 봐야 해요. 이 순서를 거꾸로 하면 문제 원인 추적이 정말 힘들어지더라고요.

    OpenStack Swift Ceph 비교를 위한 분산 구조 구성도

    Swift의 링 기반 분산과 Ceph의 CRUSH 기반 분산 개념을 비교하는 구성도입니다.

    4-3. S3 호환성과 테스트 업로드

    실전에서는 결국 애플리케이션이 붙어야 하니 간단한 업로드 테스트를 같이 봅니다.

    # 예시: S3 API 엔드포인트 검증용 aws cli 테스트
    aws --endpoint-url http://rgw.example.local s3 mb s3://lab-bucket
    aws --endpoint-url http://rgw.example.local s3 cp sample.log s3://lab-bucket/
    aws --endpoint-url http://rgw.example.local s3 ls s3://lab-bucket/

    Swift도 미들웨어(middleware)나 호환 계층을 어떻게 둘지에 따라 접근 방식이 달라집니다. 그래서 단순 기능 체크보다 현재 애플리케이션이 어떤 API를 기대하는지 먼저 보는 게 맞습니다.

    5. Swift Ceph 성능, 숫자보다 더 중요한 운영 특성

    Swift Ceph 성능 이야기를 할 때 조심해야 할 게 있습니다. 동일한 하드웨어, 동일한 네트워크, 동일한 복제 정책이 아니면 숫자 비교 자체가 큰 의미가 없거든요. 그래서 저는 성능을 볼 때 아래처럼 나눠서 봅니다.

    • 소형 객체 처리: 메타데이터 부담, API 처리량
    • 대용량 스트림: 순차 업로드/다운로드 안정성
    • 복구 중 성능: 장애 이후 리밸런싱 시 서비스 영향
    • 확장 후 균형: 노드 추가 뒤 데이터 재배치 비용

    Swift는 오브젝트 스토리지에 맞춘 단순성과 분리가 장점으로 느껴질 때가 있습니다. 반면 Ceph는 잘 구성하면 매우 유연하지만, 그만큼 봐야 할 지표와 튜닝 포인트가 더 많아요. 저도 초반에는 Ceph가 만능처럼 보여서 무조건 좋은 줄 알았는데, 작은 팀에서는 그 유연성이 오히려 운영 부담으로 돌아오더라고요.

    비교 기준 Swift에서 볼 점 Ceph에서 볼 점
    확장성 링 재배치 운영 절차 OSD 추가 후 데이터 재균형
    장애 복구 복제/재동기화 흐름 클러스터 헬스와 백필(backfill) 영향
    운영 복잡도 역할 구분이 명확 기능이 많은 만큼 관리 포인트 증가
    API 활용 오브젝트 중심 설계 RGW 기반 S3/Swift 스타일 접근

    6. ⚠️ 실제 운영에서 자주 만나는 문제와 트러블슈팅

    여기부터가 진짜 중요합니다. 비교표는 다들 잘 만드는데, 실제 문제는 운영 중에 나오거든요.

    6-1. Swift에서 겪기 쉬운 문제

    • 링 변경 후 기대와 다른 분산
      원인: 초기 장비 가중치(weight) 설계가 부정확했거나 증설 정책이 일관되지 않은 경우가 많습니다.
    • 프록시 병목
      원인: 백엔드 디스크보다 앞단 프록시 처리량이 먼저 막히는 경우가 있습니다.
    • 운영자 이해도 편차
      원인: 링, 존, 디바이스 매핑 개념을 팀 전체가 공유하지 않으면 장애 대응 속도가 확 떨어집니다.

    6-2. Ceph에서 겪기 쉬운 문제

    • HEALTH_WARN 장기 지속
      원인: PG 불균형, OSD out/in 반복, 복구 작업 장기화 같은 문제가 숨어 있는 경우가 많습니다.
    • 기능은 많은데 운영이 복잡함
      원인: 블록, 파일, 오브젝트를 한 번에 다 열면 초반 운영 난도가 급격히 올라갑니다.
    • 성능 이슈 원인 파악 난이도
      원인: 네트워크, 디스크, PG 상태, 복제 정책 등 봐야 할 층이 많습니다.

    제가 직접 해보니 공통 해법은 비슷했어요.

    1. 처음부터 모든 기능을 열지 않습니다.
    2. 장애 도메인과 확장 정책을 문서로 먼저 고정합니다.
    3. 성능 테스트보다 복구 테스트를 먼저 합니다.
    4. 운영팀이 매일 보는 대시보드 항목을 표준화합니다.
    Swift Ceph 성능 및 복구 상태를 보여주는 운영 대시보드 이미지

    복구 중인 클러스터 상태, 용량 분포, 경고 지표를 시각화한 운영 관점 이미지입니다.

    7. 검증과 결과: 어떤 팀에 무엇이 더 맞았나

    랩과 운영 경험을 합쳐보면, 저는 보통 이렇게 정리합니다.

    • Swift가 잘 맞는 경우: 대용량 오브젝트 저장이 주력이고, OpenStack와 자연스럽게 붙여 쓰려는 경우
    • Ceph가 잘 맞는 경우: 오브젝트 외에 블록 스토리지와 파일 스토리지까지 함께 설계하려는 경우
    • 작은 팀의 현실: 기능 많음이 항상 장점은 아닙니다. 운영 가능성이 더 중요해요.

    특히 OpenStack Swift Ceph 비교에서 빠지면 안 되는 결론이 하나 있습니다. 무엇이 더 우월한가가 아니라, 우리 조직에 무엇이 덜 위험한가를 봐야 한다는 점이거든요. 이거 진짜 중요합니다.

    검증할 때는 아래 체크리스트를 남겨두면 좋습니다.

    # 공통 검증 체크 예시
    # 1. 업로드/다운로드 정상 여부
    # 2. 노드 1대 장애 시 접근 가능 여부
    # 3. 복구 중 응답 지연 변화
    # 4. 증설 후 재배치 시간과 영향도
    # 5. 모니터링 지표 수집 가능 여부

    이전 글에서 다뤘던 모니터링 스택과 연결하면 더 좋고, 다음 글에서는 Prometheus(프로메테우스)와 Grafana(그라파나) 기준으로 분산 스토리지 지표를 어떻게 봐야 하는지도 다뤄볼 만하겠네요.

    8. 정리: 대규모 객체 스토리지 선택, 이렇게 가져가시면 됩니다

    마무리해보겠습니다. 객체 스토리지 솔루션을 고를 때 Swift와 Ceph는 둘 다 훌륭한 선택지가 될 수 있습니다. 다만 성격이 다르거든요. Swift는 오브젝트 스토리지에 집중한 구조, Ceph는 더 넓은 범위를 아우르는 스토리지 플랫폼입니다.

    저도 처음엔 기능이 많은 쪽이 무조건 정답인 줄 알았는데, 실제로 운영해보니까 그렇지 않더라고요. 팀이 이해하고, 장애를 감당하고, 확장을 반복할 수 있어야 비로소 좋은 선택이 됩니다. 드디어 됐다! 싶은 순간은 설치 완료가 아니라, 장애 한 번 겪고도 팀이 침착하게 복구할 수 있을 때 오더라고요.

    • 오브젝트 중심 + OpenStack 친화성: Swift 쪽이 더 자연스러울 수 있습니다.
    • 통합형 분산 스토리지 전략: Ceph 쪽이 더 유리할 수 있습니다.
    • 성능보다 중요한 것: 운영 복잡도, 장애 복구, 증설 절차입니다.
    클라우드 스토리지 선택을 위한 OpenStack Swift Ceph 비교 인포그래픽

    워크로드, 운영 난이도, 확장성 기준으로 Swift와 Ceph를 요약 비교한 인포그래픽입니다.

    혹시 지금 프라이빗 클라우드나 백업 스토리지 때문에 고민 중이시라면, 먼저 “우리 팀이 실제로 운영 가능한 구조인가”부터 체크해보세요. 그다음에야 아키텍처가 선명해집니다. 다음 글에서는 클라우드 스토리지 선택 관점에서 S3 호환 오브젝트 스토리지 검증 항목을 더 실무적으로 정리해보겠습니다. ✅

  • [OpenStack] OpenStack Cinder 볼륨 생성 실패? 흔한 원인과 해결책

    [OpenStack] OpenStack Cinder 볼륨 생성 실패? 흔한 원인과 해결책

    OpenStack Cinder 볼륨 생성 실패? 흔한 원인과 해결책

    OpenStack Cinder 오류 때문에 볼륨이 안 만들어지는 상황, 운영하다 보면 한 번쯤은 꼭 겪게 됩니다. 인스턴스는 잘 뜨는데 스토리지 쪽에서 갑자기 발목을 잡으면 진짜 답답하거든요. 저도 홈랩과 실서비스 비슷한 테스트 환경에서 Cinder 볼륨 생성이 계속 실패해서 한참 삽질했었습니다. 처음엔 Nova(컴퓨트 서비스) 문제인가 싶었는데, 실제로 파고 들어가 보니 메시지는 비슷해도 원인은 꽤 다양하더라고요.

    이번 글에서는 OpenStack Cinder 오류가 났을 때 어디부터 봐야 하는지, 어떤 로그를 먼저 열어야 하는지, 그리고 OpenStack 스토리지 문제를 어떻게 단계적으로 좁혀 가는지 제 경험 기준으로 정리해보겠습니다. 특히 막연하게 재시도만 하는 대신, Cinder 디버깅 관점에서 원인을 빠르게 찾는 흐름에 집중해볼게요.

    OpenStack 환경에서 Cinder, Nova, 백엔드 스토리지가 어떻게 연결되는지 보여주는 개요 이미지입니다.

    1. OpenStack Cinder 오류는 왜 그렇게 자주 터질까요?

    쉽게 말해 Cinder(블록 스토리지 서비스)는 단순히 디스크 파일 하나 만드는 역할이 아닙니다. API 요청을 받고, 스케줄러가 적절한 백엔드로 보내고, 실제 스토리지 드라이버가 LVM(Logical Volume Manager)이나 Ceph(분산 스토리지) 같은 백엔드에 볼륨을 생성하는 구조거든요. 중간 단계가 많다 보니 어디 한 군데만 어긋나도 사용자 입장에서는 그냥 볼륨 생성 실패로 보입니다.

    제가 직접 해보니 특히 아래 네 군데에서 많이 막혔습니다.

    • 서비스 상태 이상: cinder-api, cinder-scheduler, cinder-volume 중 하나가 비정상
    • 백엔드 설정 오류: volume_backend_name, target_helper, 드라이버 옵션 불일치
    • 권한/연결 문제: iSCSI, RBD, LVM 명령 실행 실패
    • 용량 부족: 실제 디스크 또는 풀(pool) 여유 공간 부족

    여기서 중요한 포인트! 에러 메시지 한 줄만 보고 판단하면 거의 항상 돌아갑니다. 요청 경로를 따라가면서 Cinder 디버깅을 체계적으로 진행해야 합니다.

    2. Cinder 볼륨 생성 흐름을 먼저 이해해보겠습니다

    저도 처음엔 헷갈렸는데, 구조를 이해하면 로그 보는 순서가 훨씬 쉬워집니다.

    1. 사용자가 Horizon(대시보드) 또는 CLI로 볼륨 생성 요청
    2. cinder-api가 요청을 받음
    3. cinder-scheduler가 어떤 백엔드에 생성할지 결정
    4. cinder-volume이 실제 스토리지 드라이버 호출
    5. LVM, Ceph RBD, NFS 같은 백엔드에서 실제 볼륨 생성

    즉, 볼륨이 안 만들어지면 API, 스케줄링, 백엔드 실행까지 모두 후보입니다. 그래서 저는 늘 서비스 상태 확인 → 볼륨 상태 확인 → 로그 확인 → 백엔드 직접 점검 순서로 갑니다. 이 흐름이 제일 덜 꼬였습니다.

    3. 기본 점검: 가장 먼저 확인할 사항

    솔직히 여기서 끝나는 경우도 꽤 많습니다. 너무 복잡하게 보기 전에 기본 체크부터 해보세요.

    3-1. Cinder 서비스 상태 확인

    openstack volume service list
    systemctl status openstack-cinder-api
    systemctl status openstack-cinder-scheduler
    systemctl status openstack-cinder-volume

    서비스 목록에서 enabled/up 상태인지 먼저 봅니다. 특히 cinder-volume이 down이면 백엔드까지 요청이 안 내려갑니다. 실제로 써보니까 API는 살아 있는데 volume 서비스만 죽어 있는 케이스가 은근 많더라고요.

    3-2. 실패한 볼륨 상태 확인

    openstack volume list
    openstack volume show <VOLUME_ID>

    error, error_deleting, creating에서 멈췄는지 봐야 합니다. creating 상태가 오래 유지되면 백엔드 작업이 걸렸거나 스케줄링 이후 후속 처리가 멈췄을 가능성이 있습니다.

    3-3. quota(쿼터, 자원 할당량) 확인

    openstack quota show <PROJECT_ID>

    의외로 단순한 프로젝트 quota 초과 때문에 OpenStack Cinder 오류처럼 보일 때도 있습니다. 특히 테스트 환경에서는 이것 때문에 시간을 꽤 쓰게 되네요.

    OpenStack Cinder 오류 점검을 위한 서비스 상태와 볼륨 확인 이미지

    초기 점검 단계에서 서비스 상태와 볼륨 상태를 어떻게 확인하는지 보여주는 이미지입니다.

    4. Cinder 디버깅의 핵심: 로그를 요청 흐름대로 읽기

    이제부터는 본격적인 문제 해결입니다. 여기서는 로그를 한 군데만 보는 게 아니라 요청 흐름대로 나눠서 보는 게 Cinder 디버깅의 핵심입니다.

    4-1. API와 스케줄러 로그 확인

    journalctl -u openstack-cinder-api -n 200 --no-pager
    journalctl -u openstack-cinder-scheduler -n 200 --no-pager

    여기서 보는 포인트는 두 가지입니다. 첫째, 요청이 정상적으로 들어왔는지. 둘째, 스케줄러가 백엔드를 찾지 못했는지입니다. 만약 No valid backend 같은 메시지가 보이면 백엔드 이름 불일치나 capacity 정보 수집 실패를 의심해볼 수 있습니다.

    4-2. cinder-volume 로그로 근본 원인 찾기

    journalctl -u openstack-cinder-volume -n 300 --no-pager

    볼륨 생성 실패 원인은 대부분 여기서 실마리가 나옵니다. 드라이버 예외, 인증 실패, 디바이스 생성 실패, 명령 실행 오류가 다 이쪽에 남습니다. 처음엔 이게 뭔가 싶었는데, 에러 한 줄보다 바로 위아래 문맥이 더 중요하더라고요.

    4-3. 백엔드 직접 확인하기

    LVM 백엔드라면 볼륨 그룹이 실제로 보이는지 확인합니다.

    vgs
    lvs
    pvs

    Ceph RBD 백엔드라면 풀 접근이 되는지, 인증이 맞는지 확인합니다.

    ceph -s
    rbd ls <POOL_NAME>

    여기서 막히면 Cinder 문제가 아니라 사실상 백엔드 스토리지 문제인 경우가 많습니다. 이럴 때는 접근 방향을 바꿔야 합니다.

    5. 흔한 원인과 해결책: 빠르게 참고할 표

    제가 자주 봤던 패턴을 표로 정리해보겠습니다. 운영 중이면 이 표만 보고도 대략 감이 올 때가 있습니다.

    증상 가능한 원인 확인 포인트 해결 방향
    볼륨이 계속 creating 상태 백엔드 응답 지연 또는 작업 멈춤 cinder-volume 로그, 백엔드 상태 백엔드 연결 확인, stuck 작업 정리
    즉시 error 상태로 전환 드라이버 설정 오류 cinder.conf, volume_backend_name 설정값 정합성 수정 후 서비스 재시작
    No valid backend 스케줄러가 사용 가능한 백엔드 없음 scheduler 로그, capacity 보고값 backend 등록 상태와 용량 정보 점검
    권한 관련 오류 스토리지 인증 또는 OS 권한 부족 Ceph keyring, LVM 실행 권한 자격 증명과 실행 계정 권한 수정
    간헐적 실패 네트워크 또는 메시지 큐 지연 MQ, DB, 관리 네트워크 지연 인프라 레이어 상태 함께 점검

    5-1. 설정 파일에서 자주 실수하는 부분

    [DEFAULT]
    enabled_backends = lvm
    
    [lvm]
    volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
    volume_group = cinder-volumes
    volume_backend_name = LVM
    target_helper = tgtadm

    여기서 enabled_backends와 섹션 이름, volume_backend_name이 꼬이면 스케줄러가 백엔드를 인식하지 못합니다. 저는 예전에 섹션 이름은 lvm인데 다른 쪽 설정에서 백엔드 이름을 다르게 참조해둬서 몇 시간을 날렸습니다. 정말 삽질했네요.

    수정 후에는 보통 관련 서비스를 다시 올려줘야 합니다.

    systemctl restart openstack-cinder-volume
    systemctl restart openstack-cinder-scheduler
    Cinder 볼륨 생성 설정과 백엔드 매핑을 설명하는 이미지

    enabled_backends, 섹션 이름, volume_backend_name 관계를 이해하기 쉽게 보여주는 구성 이미지입니다.

    6. ⚠️ OpenStack 스토리지 운영에서 자주 놓치는 부분

    여기부터는 경험상 체감 비중이 높았던 항목입니다.

    6-1. 디스크 용량은 남았는데도 실패하는 경우

    겉으로는 스토리지 여유가 있어 보여도, thin provisioning(씬 프로비저닝) 설정이나 reserved space(예약 공간) 때문에 실제 할당 가능 용량이 부족할 수 있습니다. 특히 LVM thin pool을 쓰면 숫자만 보고 안심했다가 나중에 뒤통수 맞기 쉽습니다.

    6-2. 메시지 큐와 데이터베이스 지연

    Cinder만 보는 게 아니라 RabbitMQ(메시지 브로커)나 MariaDB/MySQL 같은 공통 인프라 레이어도 함께 봐야 합니다. 요청은 들어갔는데 상태 갱신이 늦거나 작업 분배가 밀리면 사용자 눈에는 그냥 실패처럼 보이거든요.

    6-3. 멀티백엔드 환경의 우선순위 문제

    백엔드가 여러 개면 특정 volume type(볼륨 타입)이 어느 백엔드로 가는지 꼭 확인해야 합니다. volume type과 extra specs(추가 속성)가 맞지 않으면 엉뚱한 백엔드로 가거나 스케줄링에 실패할 수 있습니다.

    openstack volume type list
    openstack volume type show <VOLUME_TYPE>

    혹시 이런 경험 있으신가요? 분명 Ceph로 보내야 하는데 기본 타입 때문에 LVM으로 가고 있던 상황이요. 이거 생각보다 자주 나옵니다.

    7. 해결책 검증하기: 실제로 동작하는지 확인

    원인을 수정했다면 반드시 재현 테스트를 해봐야 합니다. 저는 아래 순서대로 확인합니다.

    1. 테스트용 소형 볼륨 생성
    2. 상태가 available로 바뀌는지 확인
    3. 인스턴스에 attach(연결) 테스트
    4. OS 내부에서 블록 디바이스 인식 확인
    openstack volume create --size 1 test-volume
    openstack volume list
    openstack server add volume <SERVER_ID> <VOLUME_ID>

    인스턴스 내부에서는 보통 아래처럼 확인합니다.

    lsblk
    sudo fdisk -l

    여기까지 정상이라면 일단 급한 불은 껐다고 봐도 됩니다. 드디어 됐다! 하는 순간이 오긴 오더라고요.

    OpenStack Cinder 오류 해결 후 볼륨 생성과 attach 검증 이미지

    문제 해결 후 볼륨 상태가 정상으로 바뀌고 인스턴스에 연결된 결과를 보여주는 검증 이미지입니다.

    8. 자주 묻는 질문 정리

    Q1. Cinder 디버깅은 로그를 어디부터 봐야 하나요?

    openstack volume show로 상태를 보고, 그다음 cinder-scheduler, cinder-volume 순으로 보시면 됩니다. 백엔드 생성 실패는 보통 cinder-volume에 단서가 많습니다.

    Q2. Horizon에서는 실패라고만 나오는데요?

    그럴 때는 CLI가 훨씬 낫습니다. Horizon은 요약 메시지만 보여주는 경우가 많아서요. 실제 현장에서는 CLI와 journalctl 조합이 훨씬 빠릅니다.

    Q3. OpenStack Cinder 오류가 간헐적으로만 발생합니다

    이 경우는 설정 오류보다 인프라 지연, 네트워크 흔들림, 메시지 큐 병목 같은 문제일 가능성이 높습니다. 그래서 애플리케이션 로그만 보지 말고 아래도 함께 봐야 합니다.

    • 관리 네트워크 지연
    • 메시지 큐 적체
    • DB 응답 시간
    • 백엔드 스토리지 클러스터 상태

    9. 마무리: Cinder 볼륨 생성 실패는 체계적으로 접근하세요

    Cinder 볼륨 생성 실패는 겉보기엔 단순하지만, 실제로는 API, 스케줄러, 볼륨 서비스, 백엔드 스토리지까지 다 연결된 문제입니다. 그래서 OpenStack Cinder 오류를 빨리 잡으려면 감으로 접근하면 안 되고, 요청 흐름 기준으로 차근차근 좁혀 가야 합니다. Cinder 디버깅의 원칙만 지켜도 복구 시간이 꽤 줄었습니다.

    정리하면 이렇습니다.

    • 서비스 상태부터 확인합니다
    • 볼륨 상태와 로그를 함께 봅니다
    • 백엔드 스토리지를 직접 검증합니다
    • quota, volume type, 멀티백엔드 매핑도 놓치지 않습니다

    다음 글에서는 Cinder와 Ceph RBD 조합에서 자주 만나는 장애 포인트를 따로 정리해볼 예정입니다. OpenStack Cinder 오류 해결에 필요한 Nova attach 흐름도 함께 보시면 전체 그림 이해에 도움이 됩니다.

    OpenStack Cinder 오류 점검 순서를 정리한 요약 인포그래픽

    서비스, 로그, 백엔드, 검증 순서로 이어지는 Cinder 트러블슈팅 체크리스트 요약 이미지입니다.

  • [Proxmox] HA 클러스터 구축 전 고려사항: 스토리지 복제 vs 공유 스토리지

    [Proxmox] HA 클러스터 구축 전 고려사항: 스토리지 복제 vs 공유 스토리지

    [Proxmox] HA 클러스터 구축 전 고려사항: 스토리지 복제 vs 공유 스토리지

    Proxmox HA 스토리지 비교를 제대로 안 하고 클러스터부터 묶어버리면, 나중에 장애가 났을 때 생각보다 당황하게 됩니다. 저도 처음엔 "노드만 3대면 Proxmox 고가용성은 끝난 거 아닌가?" 싶었거든요. 근데 실제로 써보니까 HA(High Availability, 고가용성)는 단순히 노드 수만으로 완성되지 않더라고요. 결국 핵심은 스토리지를 어떻게 둘 것인가였습니다. 특히 스토리지 복제와 공유 스토리지는 겉보기엔 비슷해 보여도, 장애 시 동작 방식이 꽤 다릅니다.

    이번 글에서는 홈랩과 실서비스에 가까운 테스트 환경에서 제가 직접 부딪히며 정리한 기준으로, Proxmox HA 스토리지 비교를 해보겠습니다. 무엇이 더 좋다고 단정하기보다는, 어떤 상황에서 무엇이 덜 후회가 남는지 쪽으로 설명드릴게요. 혹시 클러스터 구성은 끝냈는데 스토리지 선택에서 막히셨다면, 여기서 중요한 포인트만 잡아가셔도 꽤 도움이 되실 겁니다.

    Proxmox HA 스토리지 비교를 위한 클러스터 구조 개요 이미지

    3노드 Proxmox 클러스터에서 스토리지 복제와 공유 스토리지의 흐름을 한눈에 보여주는 개요 이미지입니다.

    1. 왜 Proxmox HA 스토리지 비교가 중요한가

    쉽게 말해 HA는 장애가 나도 서비스가 다시 올라오는 구조를 만드는 일입니다. 그런데 VM(가상머신)이나 CT(Container, 컨테이너)의 디스크가 어느 위치에 있느냐에 따라, 장애 이후의 복구 속도와 방식이 완전히 달라집니다.

    • 공유 스토리지: 여러 노드가 같은 디스크 자원을 봅니다.
    • 스토리지 복제: 각 노드가 자기 디스크를 갖고 있고, 데이터를 주기적으로 복제합니다.

    둘 다 장애 대응이 가능하지만 결이 다릅니다. 공유 스토리지는 운영이 잘 되면 마이그레이션(Migration, 이전)이 편하고 구조가 직관적입니다. 반면 스토리지 복제는 노드별 독립성이 있어서 비용이나 확장성 면에서 매력적일 때가 있더라고요. 다만 복제 시점과 장애 시점 사이에 생기는 차이를 반드시 이해하셔야 합니다.

    2. 개념부터 정리: 스토리지 복제 vs 공유 스토리지

    스토리지 복제(Replication, 복제)란?

    제가 처음엔 이게 백업(Backup, 백업)이랑 비슷한 줄 알았는데, 실제로는 목적이 다릅니다. Proxmox에서 많이 이야기하는 복제는 보통 ZFS Replication(제트에프에스 복제) 기반으로, 특정 VM 디스크를 다른 노드로 주기적으로 보내는 방식입니다.

    즉, 원본 VM은 A 노드에서 돌고 있고, 일정 주기로 B 노드에 디스크 상태가 복제됩니다. 장애가 나면 B 노드에서 최신 복제본 기준으로 다시 시작하는 그림이죠.

    • 장점: 노드마다 로컬 디스크 성능을 살리기 좋습니다.
    • 장점: 별도 외부 스토리지 없이 시작하기 쉽습니다.
    • 주의: 복제는 실시간 동기화와 다릅니다.
    • 주의: 장애 순간 직전의 마지막 쓰기 데이터는 반영되지 않을 수 있습니다.

    공유 스토리지(Shared Storage, 공유 저장소)란?

    공유 스토리지는 여러 Proxmox 노드가 같은 스토리지에 접근하는 방식입니다. 대표적으로 NFS(Network File System), iSCSI, FC(Fibre Channel), Ceph 같은 구성이 여기에 들어갑니다. 다만 Ceph는 단순 외부 공유 스토리지라기보다 분산 스토리지 성격이 강해서, 설계 포인트가 조금 다르긴 합니다.

    이 구조의 핵심은 디스크가 노드에 묶여 있지 않다는 점입니다. 그래서 정상 상태에서의 라이브 마이그레이션(Live Migration, 무중단 이전)이나 HA 재시작 시 흐름이 상대적으로 자연스럽습니다.

    • 장점: 노드 이동이 편합니다.
    • 장점: VM 디스크를 모든 노드가 바로 볼 수 있습니다.
    • 주의: 스토리지 자체의 이중화가 안 되면 병목이나 단일 장애점(SPOF, Single Point of Failure)이 됩니다.
    • 주의: 네트워크 설계가 부실하면 성능 문제가 바로 드러납니다.

    3. 어떤 환경에 뭐가 맞는지 먼저 판단해보세요

    실제로 써보니까 선택 기준은 생각보다 단순했습니다. 아래 표처럼 보시면 감이 좀 빨리 오실 거예요.

    비교 항목 스토리지 복제 공유 스토리지
    초기 구축 난이도 상대적으로 단순 스토리지 설계까지 필요
    장애 직후 복구 방식 복제본 기준 재시작 같은 디스크로 다른 노드에서 재시작
    데이터 최신성 복제 주기에 영향 공유 저장소 상태 기준
    라이브 마이그레이션 편의성 제약이 있을 수 있음 대체로 유리
    외부 스토리지 의존도 낮음 높음
    확장성 노드별 설계에 따라 다름 스토리지 구조에 따라 크게 좌우
    대표 리스크 복제 시점 차이 공유 스토리지 장애

    제가 멘토링할 때 자주 드리는 기준은 이렇습니다.

    1. 예산이 제한적이고 홈랩 성격이 강하다면 스토리지 복제로 시작해도 괜찮습니다.
    2. 운영 편의성과 이동성이 중요하면 공유 스토리지가 더 낫습니다.
    3. 장애 시 데이터 시점 일관성이 매우 중요하면 복제 주기와 애플리케이션 특성을 꼭 같이 봐야 합니다.
    4. 스토리지 자체를 HA로 만들 수 있느냐가 사실상 최종 결정 포인트입니다.

    4. 실전 구현 1: Proxmox 클러스터 기본 구성

    여기서는 예시로 3노드 클러스터를 가정하겠습니다. 버전별 화면은 조금 다를 수 있지만 흐름은 비슷합니다. 제가 보통 테스트할 때도 먼저 쿼럼(Quorum, 정족수) 상태부터 확인합니다. 이거 안 보고 넘어가면 나중에 삽질 좀 합니다 ㅎㅎ

    # 첫 번째 노드에서 클러스터 생성
    pvecm create homelab-cluster
    
    # 두 번째, 세 번째 노드에서 클러스터 참여
    pvecm add 192.168.10.11
    
    # 클러스터 상태 확인
    pvecm status

    여기서 확인할 건 많지 않습니다.

    • 노드 수가 정상인지
    • Quorate 상태인지
    • 통신 네트워크가 안정적인지

    특히 HA는 네트워크 품질에 꽤 민감합니다. 관리망(Management Network, 관리 네트워크)과 스토리지망을 가능하면 분리하는 편이 좋습니다. 처음엔 한 NIC(Network Interface Card, 네트워크 인터페이스 카드)로 다 몰아도 될 것 같았는데, 실제로 복제나 스토리지 IO가 겹치면 금방 티가 나더라고요.

    Proxmox 고가용성 환경에서 네트워크를 분리한 구성도

    관리망과 스토리지망을 분리한 3노드 Proxmox 클러스터 예시 구성입니다.

    5. 실전 구현 2: 스토리지 복제 구성 예시

    스토리지 복제를 쓰려면 로컬 ZFS 스토리지를 먼저 준비해둬야 하더라고요. Proxmox에서 복제는 VM 디스크를 대상 노드로 정기적으로 보내는 방식입니다. 아래 예시는 개념 확인용으로 보시면 됩니다.

    # VM 101을 node2로 15분마다 복제
    pvesr create 101 node2 --schedule "*/15"
    
    # 복제 작업 확인
    pvesr list
    
    # ZFS 상태 확인
    zpool status

    제가 직접 해보니 여기서 중요한 건 복제 주기입니다. 1분으로 너무 촘촘하게 잡으면 스토리지와 네트워크에 부담이 갑니다. 반대로 너무 길게 잡으면 장애 시 복구본이 오래된 상태일 수 있죠. 결국 서비스 성격에 따라 조정해야 합니다.

    HA 자원 등록은 이런 식으로 진행합니다.

    # VM 101을 HA 자원으로 등록
    ha-manager add vm:101
    
    # HA 상태 확인
    ha-manager status

    이 구성을 쓰면 노드 장애 시 복제되어 있던 대상 노드에서 VM이 다시 시작될 수 있습니다. 다만 여기서 포인트! 공유 스토리지처럼 동일 디스크를 즉시 이어받는 개념은 아닙니다. 마지막 복제 시점 기준이라는 점, 꼭 기억하셔야 합니다.

    6. 실전 구현 3: 공유 스토리지 구성 예시

    공유 스토리지는 방식이 여러 가지지만, 홈랩에서는 NFS가 접근성이 좋고, 조금 더 본격적으로 가면 iSCSI나 Ceph를 고려하게 됩니다. 아래는 NFS 기반 공유 스토리지 등록 흐름 예시입니다.

    # Proxmox 노드에서 NFS 저장소 추가 예시
    pvesm add nfs shared-nfs \
      --server 192.168.20.10 \
      --export /srv/proxmox \
      --content images,iso,backup
    
    # 스토리지 목록 확인
    pvesm status

    공유 스토리지를 올렸다면, VM 디스크를 해당 저장소에 두고 HA를 연결합니다. 이렇게 되면 특정 노드가 내려가더라도 다른 노드가 같은 디스크를 바라보며 기동할 수 있습니다.

    # HA 등록 예시
    ha-manager add vm:201
    ha-manager status

    실제로 써보니까 운영은 훨씬 편했습니다. 특히 유지보수 때문에 VM을 다른 노드로 옮길 때 체감 차이가 큽니다. 다만 스토리지 서버가 흔들리면 클러스터 전체가 동시에 영향을 받을 수 있어서, 공유 스토리지 자체의 안정성을 절대 가볍게 보면 안 됩니다.

    Proxmox HA 스토리지 비교를 위한 설정 화면 이미지

    복제 작업 구성과 공유 스토리지 등록 흐름을 비교해 보여주는 설정 예시 이미지입니다.

    7. ⚠️ 제가 실제로 겪었던 주의사항과 트러블슈팅

    이 섹션은 좀 현실적인 얘기입니다. 문서만 보면 금방 될 것 같은데, 막상 해보면 여기서 자주 막힙니다.

    1) 복제는 백업이 아닙니다

    이거 진짜 중요합니다. 스토리지 복제는 운영 편의를 위한 복제이지, 장기 보관용 백업 전략을 대체하지 않습니다. 삭제나 손상이 복제 타이밍에 따라 같이 전파될 수 있거든요. 저는 복제를 켜놓고 마음이 편했었는데, 나중에 보니 그건 착각이었습니다.

    2) 공유 스토리지 하나만 믿으면 위험합니다

    공유 스토리지 덕분에 HA가 깔끔해 보이지만, 그 스토리지가 사실상 단일 장애점이면 말짱 도루묵입니다. NFS 서버 한 대만 두고 HA라고 부르기엔 좀 민망하더라고요. 가능하면 이중화된 NAS, 이중 컨트롤러 SAN, 또는 분산 스토리지 구조를 고민하셔야 합니다.

    3) 쿼럼 문제는 생각보다 자주 나옵니다

    특히 2노드 비슷하게 운영하거나, 관리망이 불안정하면 쿼럼 이슈로 HA가 기대대로 움직이지 않을 수 있습니다. 여기서 중요한 포인트는 노드 수보다 통신 안정성입니다.

    # 클러스터 상태와 쿼럼 확인
    pvecm status
    
    # HA 리소스 상태 확인
    ha-manager status

    4) 복제망과 서비스망이 섞이면 병목이 납니다

    처음엔 그냥 한 스위치에 몰아넣고 테스트했었는데, 복제 작업이 도는 시간대에 VM 응답성이 떨어지는 걸 봤습니다. 특히 스냅샷(Snapshot, 시점 저장) 기반 작업이 겹치면 체감이 납니다. 가능하면 VLAN이나 물리 NIC 분리를 권장드립니다.

    5) 파일시스템과 스토리지 특성을 같이 봐야 합니다

    ZFS는 정말 강력하지만 메모리 사용 특성과 운영 습관이 맞아야 합니다. 반대로 외부 공유 스토리지는 백엔드 장비 성능이 약하면 Proxmox 노드를 늘려도 체감 개선이 안 되더라고요. 결국 병목은 가장 약한 스토리지 구간에서 생깁니다.

    8. 검증 방법과 결과 확인

    구성만 했다고 끝이 아닙니다. 저는 항상 테스트 장애를 일부러 만들어봅니다. 물론 운영 장비에서는 점검 창을 잡고 조심해서 해야겠죠.

    1. 테스트 VM을 하나 준비합니다.
    2. HA 자원으로 등록합니다.
    3. 복제 또는 공유 스토리지 상태를 확인합니다.
    4. 원본 노드를 재부팅하거나 격리해봅니다.
    5. 다른 노드에서 VM이 어떻게 올라오는지 확인합니다.
    # HA 상태 확인
    ha-manager status
    
    # 스토리지 상태 확인
    pvesm status
    
    # 복제 작업이 있다면 확인
    pvesr list

    스토리지 복제 방식에서는 보통 마지막 복제본 기준으로 재시작되는지를 봐야 하고, 공유 스토리지 방식에서는 디스크 접근이 끊기지 않고 다른 노드에서 정상 기동하는지를 확인하면 됩니다.

    제가 테스트했을 때 체감상 차이는 이랬습니다.

    • 스토리지 복제: 구조가 깔끔하고 비용 부담이 덜했지만, 장애 시점과 복제 시점 차이를 항상 의식해야 했습니다.
    • 공유 스토리지: 운영은 편했지만, 스토리지 품질이 전체 경험을 좌우했습니다.
    Proxmox 클러스터 장애 복구 결과를 보여주는 대시보드 이미지

    노드 장애 이후 다른 노드에서 HA 자원이 재기동된 상태를 보여주는 결과 검증 이미지입니다.

    9. 정리: 어떤 선택이 덜 후회가 남는가

    결론부터 말씀드리면, Proxmox HA 스토리지 비교에서 정답은 하나가 아닙니다. 대신 우선순위는 분명합니다.

    • 예산과 단순한 시작이 중요하면 스토리지 복제가 현실적입니다.
    • 운영 편의성과 이동성이 중요하면 공유 스토리지가 유리합니다.
    • 데이터 시점 손실 허용 범위를 먼저 정해야 합니다.
    • 스토리지 자체를 얼마나 신뢰할 수 있느냐가 최종 승부처입니다.

    저도 처음엔 무조건 공유 스토리지가 상위 개념인 줄 알았는데, 실제로 써보니까 꼭 그렇진 않았습니다. 홈랩이나 소규모 환경에서는 스토리지 복제가 오히려 관리 포인트가 적을 때도 있었거든요. 반대로 운영 자동화와 유지보수 편의성을 끌어올리려면 공유 스토리지가 확실히 매력적입니다.

    혹시 지금 Proxmox 고가용성 구성을 고민 중이시라면, 먼저 이렇게 자문해보세요. "장애가 났을 때 나는 무엇을 잃어도 되는가?" 이 질문에 답이 나오면, 스토리지 구조도 꽤 명확해집니다.

    다음 글에서는 Ceph를 포함한 분산 스토리지 관점에서 Proxmox 클러스터를 어떻게 볼지 이어서 다뤄볼 예정입니다. 이전 글에서 다뤘던 백업 전략과 함께 보시면, 복제와 백업을 분리해서 이해하는 데 훨씬 도움이 되실 겁니다.

    Proxmox HA 스토리지 비교 선택 기준 요약 이미지

    예산, 운영 편의성, 장애 대응 기준으로 두 방식을 요약한 비교 인포그래픽입니다.

    자주 묻는 질문

    Q1. Proxmox HA에서 스토리지 복제만으로 충분한가요?

    환경에 따라 가능합니다. 다만 복제는 마지막 동기화 시점 차이가 있으니, 데이터 최신성이 중요한 서비스라면 그 부분을 먼저 검토하셔야 합니다.

    Q2. 공유 스토리지가 있으면 무조건 더 좋은가요?

    꼭 그렇진 않습니다. 운영은 편하지만, 공유 스토리지 자체가 약하면 전체 클러스터가 같이 흔들립니다.

    Q3. 백업과 복제는 왜 따로 봐야 하나요?

    복제는 가용성 향상에 가깝고, 백업은 시점 보존과 복구 전략에 가깝기 때문입니다. 둘은 목적이 다릅니다.

    Q4. 홈랩에서는 어떤 방식이 시작하기 좋나요?

    제 경험상 홈랩은 스토리지 복제로 개념을 익히고, 이후 공유 스토리지나 Ceph로 넘어가는 흐름이 부담이 덜했습니다. 단계적으로 가는 게 훨씬 덜 헷갈리더라고요.

  • [k8s] Kubernetes 스토리지: Longhorn vs Rook-Ceph 성능 벤치마크

    [k8s] Kubernetes 스토리지: Longhorn vs Rook-Ceph 성능 벤치마크

    안녕하세요, 13년차 서버실 지킴이입니다. 🤓

    Kubernetes(쿠버네티스) 환경에서 애플리케이션을 운영하다 보면, 영구 스토리지(Persistent Storage)의 중요성을 정말 뼈저리게 느끼게 됩니다. Pod(파드)가 재시작되거나 다른 노드로 옮겨가도 데이터는 안전하게 보존되어야 하니까요. 특히 저처럼 홈랩(Homelab)에서 이것저것 실험하며 삽질을 즐기는 사람이라면, 안정적이고 성능 좋은 스토리지를 찾는 데 꽤 많은 시간을 투자하게 되죠. 저도 그랬거든요! 🤔

    오늘은 제가 직접 홈랩에서 Longhorn(롱혼)과 Rook-Ceph(룩-세프) 두 가지 Kubernetes 영구 스토리지 솔루션을 설치하고, FIO(Flexible I/O Tester) 벤치마크 툴로 성능을 비교해본 경험을 공유해드리려고 합니다. 과연 어떤 녀석이 제 환경에 더 적합했을까요? 저의 삽질 여정을 따라오시면서 여러분의 Kubernetes 스토리지 선택에 도움이 되시길 바랍니다!

    왜 영구 스토리지가 필요할까요?

    Kubernetes는 기본적으로 컨테이너화된 애플리케이션을 배포하고 관리하는 데 최적화되어 있어요. 그런데 컨테이너는 휘발성(ephemeral)이라는 특징을 가지고 있거든요. 즉, 컨테이너가 죽거나 재시작되면 그 안에 저장된 데이터는 사라져 버린다는 뜻이죠. 데이터베이스나 파일 서버처럼 데이터를 영구적으로 보관해야 하는 애플리케이션에는 치명적일 수 있습니다.

    이런 문제를 해결하기 위해 Kubernetes에서는 영구 볼륨(Persistent Volume, PV)과 영구 볼륨 클레임(Persistent Volume Claim, PVC)이라는 개념을 도입했어요. 쉽게 말해, 스토리지 시스템으로부터 저장 공간을 할당받아 Pod가 데이터를 안정적으로 쓰고 읽을 수 있게 해주는 기능이라고 보시면 됩니다. 그리고 이런 영구 볼륨을 동적으로 프로비저닝(provisioning)해주는 역할을 하는 것이 바로 CSI(Container Storage Interface) 드라이버를 기반으로 하는 분산 스토리지 솔루션들이죠. 오늘 다룰 Longhorn과 Rook-Ceph가 바로 그런 친구들입니다.

    Kubernetes 영구 스토리지 아키텍처 개요

    Kubernetes 클러스터에서 영구 스토리지가 어떻게 작동하는지 대략적인 아키텍처를 그려봤어요. Pod가 PVC를 요청하면, CSI 드라이버가 백엔드 스토리지 시스템에 PV를 생성하고 Pod에 연결해주는 방식이죠. 이 과정에서 Longhorn이나 Rook-Ceph 같은 분산 스토리지 솔루션이 그 백엔드 역할을 하는 겁니다.

    Longhorn과 Rook-Ceph, 넌 누구니?

    본격적인 벤치마크에 앞서, 두 솔루션에 대해 간략하게 알아볼까요? 저도 처음엔 이름만 듣고 뭐가 뭔지 헷갈렸거든요. 😅

    Longhorn (롱혼)

    • 특징: Rancher Labs에서 개발한 오픈소스 분산 블록 스토리지 솔루션이에요. Kubernetes 위에서 컨테이너 형태로 동작하며, 각 노드의 로컬 스토리지를 모아 분산 볼륨을 생성합니다. CSI 드라이버를 기본으로 제공해서 Kubernetes와 통합이 정말 쉬워요. 제가 직접 써보니, 설치도 비교적 간단하고 웹 UI가 직관적이어서 관리하기 편하더라고요. 홈랩이나 소규모 환경에 많이 추천되는 이유를 알겠더군요.
    • 장점: 가벼움, 설치 및 관리 용이, 스냅샷/백업/복원 기능 내장, DR(재해 복구) 지원.

    Rook-Ceph (룩-세프)

    • 특징: Rook는 Kubernetes 네이티브 스토리지 오케스트레이터이고, Ceph(세프)는 강력하고 성숙한 오픈소스 분산 스토리지 시스템이에요. Rook는 Ceph를 Kubernetes 클러스터 위에 배포하고 관리하는 오퍼레이터(Operator) 역할을 합니다. 오브젝트 스토리지(Object Storage), 블록 스토리지(Block Storage), 파일 스토리지(File Storage)를 모두 지원하는 만능 재주꾼이죠. 다만, Ceph 자체가 워낙 복잡한 시스템이라 Rook를 통해 배포해도 초기 설정과 관리에 공수가 좀 들어가는 편이에요. 대규모 프로덕션 환경에서 많이 사용됩니다.
    • 장점: 뛰어난 확장성, 높은 가용성, 다양한 스토리지 타입 지원, 강력한 성능(하드웨어에 따라).

    두 솔루션의 주요 특징을 표로 정리해봤어요.

    구분 Longhorn Rook-Ceph
    개발사/기반 Rancher Labs / 분산 블록 스토리지 Rook (오퍼레이터) + Ceph (분산 스토리지)
    스토리지 타입 블록 스토리지 블록, 오브젝트, 파일 스토리지
    설치 난이도 쉬움 (Helm) 중간 ~ 어려움 (kubectl apply)
    관리 UI 직관적인 웹 UI Ceph Dashboard (별도 설치), Grafana 연동
    확장성 중간 (수십 TB 규모) 매우 높음 (페타바이트 규모)
    주요 사용처 홈랩, 소규모 개발/테스트, 엣지 컴퓨팅 대규모 프로덕션, 클라우드 인프라

    벤치마크 환경 구축하기

    저의 홈랩 환경은 다음과 같았습니다. 실제 벤치마크 결과는 하드웨어 스펙, 네트워크 환경, Kubernetes 설정 등에 따라 크게 달라질 수 있다는 점을 미리 말씀드려요! ⚠️

    • Kubernetes Cluster: 3 Node (1 Master, 2 Worker)
    • OS: Ubuntu Server 22.04 LTS
    • CPU: Intel i5-10400 (각 노드당 6코어 12스레드)
    • RAM: 32GB (각 노드당)
    • Storage: NVMe SSD 500GB (각 노드당, 스토리지용으로 할당)
    • Network: 1Gbps Ethernet

    벤치마크 툴로는 FIO (Flexible I/O Tester)를 사용했어요. FIO는 디스크 I/O 성능을 측정하는 데 널리 사용되는 강력한 도구예요. 순차 읽기/쓰기, 랜덤 읽기/쓰기 등 다양한 패턴으로 I/O를 발생시켜 실제 워크로드와 유사한 환경을 만들 수 있거든요.

    Longhorn 설치 및 설정

    Longhorn은 Helm(헬름) 차트를 이용하면 정말 쉽게 설치할 수 있어요. 저도 처음엔 혹시나 복잡할까 봐 걱정했는데, 생각보다 너무 간단해서 놀랐어요. 🎉

    1. Helm Repository 추가:
      helm repo add longhorn https://charts.longhorn.io
      helm repo update
      
    2. Longhorn 설치: (기본 설정으로 설치했습니다)
      helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace
      
    3. Longhorn UI 접속:

      설치가 완료되면, Longhorn UI에 접속할 수 있도록 Ingress(인그레스, 외부 트래픽 진입점)나 NodePort(노드포트)를 설정해줘요. 저는 간단하게 NodePort로 열어서 접속했어요.

      kubectl -n longhorn-system get svc longhorn-frontend
      # 출력되는 NodePort를 확인하여 접속
      
    4. StorageClass 확인 및 볼륨 생성:

      Longhorn이 설치되면 기본적으로 longhorn이라는 StorageClass(스토리지클래스)가 생성돼요. 이걸 이용해서 PVC를 생성하고 Pod에 마운트하면 끝입니다.

      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: longhorn-pvc
      spec:
        accessModes:
          - ReadWriteOnce
        storageClassName: longhorn
        resources:
          requests:
            storage: 10Gi
      

    Longhorn 웹 UI에 접속하면 현재 클러스터의 스토리지 상태, 노드별 디스크 사용량, 볼륨 목록 등을 한눈에 확인할 수 있어요. 시각적으로 깔끔하고 직관적이라서 관리하기 정말 편하더라고요. 💡

    Longhorn 웹 UI 대시보드 화면

    Longhorn 대시보드 화면이에요. 생성된 볼륨, 노드의 스토리지 상태 등을 쉽게 확인할 수 있어요.

    Rook-Ceph 설치 및 설정

    Rook-Ceph는 Longhorn보다 설정할 부분이 많아서, 처음엔 “이게 다 뭔가…” 싶었어요. 하지만 공식 문서(Official Documentation)를 차근차근 따라가면 충분히 설치할 수 있어요. 저는 helm 대신 kubectl apply -f 방식으로 진행했습니다.

    1. Rook Operator 배포:

      먼저 Rook Operator를 배포해요. 이 오퍼레이터가 Ceph 클러스터를 관리하는 역할을 합니다.

      git clone --single-branch --branch v1.11.x https://github.com/rook/rook.git
      cd rook/deploy/examples
      kubectl create -f crds.yaml -f common.yaml -f operator.yaml
      
    2. Ceph Cluster 배포:

      Ceph 클러스터를 배포해요. 이 과정에서 어떤 디스크를 Ceph 스토리지로 사용할지 지정해줘야 해요. 저는 각 워커 노드의 NVMe SSD를 사용하도록 설정했습니다.

      kubectl create -f cluster.yaml
      

      cluster.yaml 파일에서 storage 섹션에 useAllNodes: true와 useAllDevices: true를 설정하여 모든 노드의 모든 디바이스를 사용하도록 했어요. 실제 운영 환경에서는 특정 디스크만 사용하도록 명시하는 것이 좋습니다.

    3. Ceph Block Pool 및 StorageClass 생성:

      Ceph 클러스터가 안정화되면, 블록 스토리지를 위한 CephBlockPool(세프 블록 풀)과 StorageClass를 생성해요.

      kubectl create -f csi/rbd/storageclass.yaml
      

      storageclass.yaml 파일은 다음과 비슷하게 생겼을 겁니다.

      apiVersion: ceph.rook.io/v1
      kind: CephBlockPool
      metadata:
        name: replicapool
        namespace: rook-ceph
      spec:
        failureDomain: host
        replicated:
          size: 3 # 데이터 복제본 수
      ---
      apiVersion: storage.k8s.io/v1
      kind: StorageClass
      metadata:
        name: rook-ceph-block
      provisioner: rook-ceph.rbd.csi.ceph.com
      parameters:
        clusterID: rook-ceph
        pool: replicapool
        imageFormat: "2"
        imageFeatures: "layering"
        csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
        csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
        csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
        csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
      reclaimPolicy: Delete
      allowVolumeExpansion: true
      mountOptions:
        - discard
      
    4. PVC 생성:

      Longhorn과 마찬가지로, 생성된 rook-ceph-block StorageClass를 이용해 PVC를 생성해요.

      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: rook-ceph-pvc
      spec:
        accessModes:
          - ReadWriteOnce
        storageClassName: rook-ceph-block
        resources:
          requests:
            storage: 10Gi
      
    Rook-Ceph on Kubernetes 클러스터 구성도

    Rook-Ceph 클러스터의 내부 구성도예요. Ceph의 여러 구성요소(MON, OSD, MGR)가 Pod 형태로 Kubernetes 클러스터 위에서 동작하는 것을 볼 수 있어요.

    FIO 벤치마크 실행 및 결과 분석

    두 스토리지 솔루션의 PVC를 각각 생성한 후, FIO를 실행할 Pod를 띄워 벤치마크를 진행했어요. 저는 주로 랜덤 읽기/쓰기(Random Read/Write)와 순차 읽기/쓰기(Sequential Read/Write) 성능을 중점적으로 살펴봤습니다. 블록 크기(Block Size)는 4KB와 1MB로 다양하게 테스트해봤거든요.

    FIO Pod를 위한 YAML 예시예요. 이 Pod가 PVC를 마운트하여 FIO 테스트를 수행합니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: fio-test-pod
    spec:
      restartPolicy: Never
      containers:
      - name: fio-container
        image: ghcr.io/fio/fio:latest # FIO 이미지를 사용합니다.
        command: ["/bin/bash", "-c"]
        args:
          - |
            mkdir -p /mnt/data
            fio --name=random-write --ioengine=libaio --iodepth=64 --rw=randwrite --bs=4k --size=1G --numjobs=1 --runtime=60 --group_reporting --filename=/mnt/data/testfile
            fio --name=random-read --ioengine=libaio --iodepth=64 --rw=randread --bs=4k --size=1G --numjobs=1 --runtime=60 --group_reporting --filename=/mnt/data/testfile
            fio --name=sequential-write --ioengine=libaio --iodepth=16 --rw=write --bs=1M --size=2G --numjobs=1 --runtime=60 --group_reporting --filename=/mnt/data/testfile_seq
            fio --name=sequential-read --ioengine=libaio --iodepth=16 --rw=read --bs=1M --size=2G --numjobs=1 --runtime=60 --group_reporting --filename=/mnt/data/testfile_seq
        volumeMounts:
        - name: test-volume
          mountPath: /mnt/data
      volumes:
      - name: test-volume
        persistentVolumeClaim:
          claimName: longhorn-pvc # 또는 rook-ceph-pvc
    

    여러 번의 테스트를 통해 제가 관찰한 결과는 대략 이랬어요. (⚠️ 이 수치는 제 특정 홈랩 환경에서 얻은 결과이며, 환경에 따라 크게 달라질 수 있음을 다시 한번 강조합니다!)

    테스트 항목 (4KB BS) Longhorn (평균) Rook-Ceph (평균) 비고
    랜덤 쓰기 IOPS 약 1,500 ~ 2,500 약 3,000 ~ 5,000 Rook-Ceph가 우위
    랜덤 쓰기 대역폭 (MB/s) 약 6 ~ 10 약 12 ~ 20 Rook-Ceph가 우위
    랜덤 읽기 IOPS 약 2,000 ~ 3,500 약 4,000 ~ 6,500 Rook-Ceph가 우위
    랜덤 읽기 대역폭 (MB/s) 약 8 ~ 14 약 16 ~ 26 Rook-Ceph가 우위
    테스트 항목 (1MB BS) Longhorn (평균) Rook-Ceph (평균) 비고
    순차 쓰기 대역폭 (MB/s) 약 80 ~ 120 약 150 ~ 250 Rook-Ceph가 우위
    순차 읽기 대역폭 (MB/s) 약 100 ~ 150 약 200 ~ 300 Rook-Ceph가 우위

    결과를 보면, 제 홈랩 환경에서는 Rook-Ceph가 전반적으로 Longhorn보다 더 높은 IOPS와 대역폭 성능을 보여줬어요. 특히 작은 블록 크기의 랜덤 I/O에서 Ceph의 강점이 두드러지더라고요. Longhorn은 복제본(replica) 수가 늘어날수록 성능 하락이 좀 더 눈에 띄는 경향이 있었고, Ceph는 안정적으로 성능을 유지했습니다.

    Longhorn과 Rook-Ceph FIO 벤치마크 결과 비교 그래프

    Longhorn과 Rook-Ceph의 FIO 벤치마크 결과를 시각적으로 비교한 그래프예요. Rook-Ceph가 전반적으로 높은 성능을 보였습니다.

    삽질 경험과 트러블슈팅 ⚠️

    솔직히 말씀드리면, 순조롭게만 진행된 건 아니었어요. 삽질 좀 했습니다 ㅎㅎ. 몇 가지 기억에 남는 경험을 공유해볼게요.

    • Longhorn: 네트워크 대역폭과 복제본 수
      처음 Longhorn을 설치하고 테스트했을 때, 생각보다 성능이 안 나와서 당황했어요. 알고 보니, Longhorn은 네트워크를 통해 볼륨 데이터를 복제(replication)하기 때문에, 노드 간 네트워크 대역폭이 정말 중요하더라고요. 제 1Gbps 네트워크 환경에서는 복제본 수를 3개로 설정했을 때 쓰기 성능이 꽤 많이 떨어지는 것을 확인했어요. 복제본 수가 늘어날수록 안정성은 높아지지만, 그만큼 네트워크 오버헤드(overhead)가 커져서 성능에 영향을 미친다는 점! 홈랩에서는 2개로 줄여서 사용하니 훨씬 나아졌습니다.
    • Rook-Ceph: OSD 인식 문제와 초기 설정
      Rook-Ceph는 초기 설정이 Longhorn보다 훨씬 복잡했어요. 특히 OSD(Object Storage Daemon)가 디스크를 제대로 인식하지 못해서 한참을 헤맸거든요. 디스크가 이미 파티셔닝(partitioning)되어 있거나, 이전에 다른 용도로 사용된 흔적이 남아있으면 Rook-Ceph가 제대로 디스크를 잡지 못하는 경우가 있더라고요. ceph-volume lvm zap --destroy /dev/sdX 같은 명령어로 디스크를 완전히 초기화해주거나, lsblk -f 명령어로 디스크의 파일 시스템(filesystem) 정보를 꼼꼼히 확인해서 해결했어요. Ceph의 CRD(Custom Resource Definition)와 설정 파일에 대한 이해가 필요하다는 것을 다시 한번 깨달았습니다.

    결론 및 선택 가이드

    제 홈랩 벤치마크 경험을 바탕으로 Longhorn과 Rook-Ceph에 대한 저의 생각을 정리해봤어요.

    솔루션 장점 단점 추천 시나리오
    Longhorn
    • 설치 및 관리가 매우 쉬움
    • 직관적인 웹 UI 제공
    • 스냅샷, 백업, 재해 복구 기능 내장
    • 가벼운 리소스 사용
    • 네트워크 대역폭에 민감 (복제본 수 증가 시)
    • Rook-Ceph 대비 낮은 최대 성능
    • 블록 스토리지에 한정
    • 홈랩, 개발/테스트 환경
    • 소규모 프로덕션 (수십 TB 이하)
    • 간편한 관리와 사용성을 중시할 때
    Rook-Ceph
    • 최고 수준의 성능 (적절한 하드웨어 시)
    • 뛰어난 확장성 (페타바이트 규모)
    • 블록, 오브젝트, 파일 스토리지 모두 지원
    • 엔터프라이즈급 안정성과 기능
    • 설치 및 설정 난이도가 높음
    • 초기 학습 곡선이 김
    • 상대적으로 많은 리소스 사용
    • 문제 발생 시 트러블슈팅 복잡
    • 대규모 프로덕션 환경
    • 고성능, 고가용성이 필수적인 경우
    • 다양한 스토리지 타입이 필요한 경우

    제 홈랩에서는 아무래도 설치 및 관리의 용이성 때문에 Longhorn에 손이 더 자주 가더라고요. 하지만 성능 자체만 놓고 본다면 Rook-Ceph가 확실히 우위를 점했어요. 결국 어떤 Kubernetes 스토리지 솔루션을 선택할지는 여러분의 환경과 요구사항에 따라 달라진다는 것이 저의 결론입니다.

    여러분도 직접 설치해보시고, 여러분의 워크로드에 맞는 벤치마크를 수행해보시면 좋은 인사이트를 얻으실 수 있을 거예요. 저의 삽질 경험이 여러분의 시행착오를 조금이나마 줄여줄 수 있다면 좋겠습니다! 😊

    다음 글에서는 Kubernetes에서 Grafana(그라파나)와 Prometheus(프로메테우스)를 이용해 스토리지 성능을 모니터링하는 방법에 대해 다뤄볼 예정이에요. 기대해주세요!

    Longhorn과 Rook-Ceph 중 어떤 솔루션이 당신에게 맞을지 요약한 인포그래픽입니다.

  • [Proxmox] Proxmox VE & Ceph 분산 스토리지 1년 회고: 안정성, 성능, 교훈

    [Proxmox] Proxmox VE & Ceph 분산 스토리지 1년 회고: 안정성, 성능, 교훈

    Proxmox VE & Ceph 분산 스토리지 1년 회고: 안정성, 성능, 교훈

    안녕하세요, 13년차의 서버실 주인장입니다. 오랜만에 홈랩(HomeLab) 이야기를 들고 왔네요. 오늘은 제가 지난 1년간 Proxmox VE와 Ceph를 조합해서 분산 스토리지를 구축하고 운영했던 경험을 회고해보려고 합니다. Proxmox Ceph 조합은 홈랩에서 강력한 스토리지 솔루션을 구축하려는 분들께 정말 매력적인 선택지인데요, 저 역시 안정성과 성능 두 마리 토끼를 잡고 싶어서 이 조합에 도전했었죠. 결과는 어땠을까요? 기대했던 만큼의 성과를 얻었을까요, 아니면 삽질의 연속이었을까요? 솔직한 제 경험담을 지금부터 풀어보겠습니다.

    혹시 여러분도 저처럼 늘어나는 가상 머신(VM, Virtual Machine)과 컨테이너(Container) 때문에 스토리지 확장에 대한 고민이 많으셨나요? 단일 서버의 저장 공간으로는 한계가 있고, 그렇다고 비싼 네트워크 스토리지(NAS, Network Attached Storage)를 여러 대 들이자니 배보다 배꼽이 더 커지는 상황. 저도 그랬습니다. 그래서 저렴한 하드웨어로 고가용성(High Availability)과 확장성(Scalability)을 동시에 잡을 수 있는 방법을 찾다가 분산 스토리지(Distributed Storage) 솔루션인 Ceph를 Proxmox VE 클러스터 위에 얹어보기로 마음먹었죠.

    왜 Proxmox VE와 Ceph를 선택했을까요? (컨셉 설명)

    제가 Proxmox VE와 Ceph 조합에 끌렸던 가장 큰 이유는 바로 시너지 효과 때문입니다. 쉽게 말해, Proxmox VE는 강력한 가상화 플랫폼이고, Ceph는 데이터를 여러 서버에 나눠 저장하면서 안정성과 성능을 높이는 시스템이거든요. 이 둘이 만나면 어떤 일이 벌어질까요?

    • Proxmox VE (프록스목스 VE): 리눅스 기반의 오픈소스 가상화 플랫폼입니다. VM과 컨테이너를 쉽게 관리할 수 있고, 여러 Proxmox 서버를 묶어 클러스터(Cluster)를 구성하면 VM을 서버 간에 자유롭게 이동시키거나(Live Migration, 라이브 마이그레이션), 한 서버에 문제가 생겨도 다른 서버에서 자동으로 VM을 재시작하는 고가용성 기능을 구현할 수 있습니다.
    • Ceph (쎄프): 역시 오픈소스 분산 스토리지 시스템입니다. 데이터를 여러 노드에 분산해서 저장하기 때문에 한두 개의 저장 장치에 문제가 생겨도 데이터가 손실될 염려가 적고, 여러 노드의 자원을 활용해서 높은 입출력 성능(IOPS, Input/Output Operations Per Second)을 낼 수 있습니다. 오브젝트 스토리지(Object Storage), 블록 스토리지(Block Storage), 파일 시스템(File System)까지 다양한 인터페이스를 제공하죠.

    이 둘을 함께 사용하면 Proxmox VE 클러스터를 구성하는 서버들의 로컬 디스크를 묶어서 하나의 거대한 Ceph 스토리지 풀(Storage Pool)로 만들 수 있습니다. 그렇게 되면 VM 디스크 이미지를 이 Ceph 스토리지에 저장하고, 어떤 Proxmox 서버에서든 해당 VM을 실행할 수 있게 되는 거죠. 한 서버에 문제가 생겨도 다른 서버가 Ceph 스토리지에 접근해서 VM을 바로 가져다 쓸 수 있으니, 고가용성(High Availability) 측면에서 정말 매력적이었어요.

    Proxmox VE와 Ceph 분산 스토리지 클러스터의 전체 아키텍처 다이어그램

    Proxmox VE 서버 3대와 Ceph 클러스터가 통합된 홈랩 아키텍처 다이어그램입니다. 각 Proxmox 노드가 Ceph OSD를 호스팅하며, VM들이 이 분산 스토리지 위에 위치합니다.

    제 홈랩에 Ceph 클러스터 구축하기: 삽질의 시작과 과정

    솔직히 처음엔 “오픈소스니까 뭐, 설치하면 되겠지!” 하는 안일한 생각도 좀 있었습니다. 13년차 엔지니어라도 새로운 기술 앞에서는 겸손해야 한다는 걸 다시 한번 깨달았죠. 😅

    하드웨어 구성: 어떤 장비로 시작했을까?

    저는 최소 3개의 노드(Node)로 구성된 클러스터를 목표로 했습니다. Ceph는 복제(Replication)를 통해 데이터 안정성을 확보하는데, 보통 3-복제(3-replication)를 많이 쓰거든요. 그래서 3대의 미니 PC를 준비했습니다. 각 PC는 인텔 NUC 같은 저전력 모델에 16GB RAM, 그리고 데이터를 저장할 SSD를 여러 개 장착했어요. 처음에는 1GbE(기가비트 이더넷) 네트워크로 시작했지만, 나중에는 10GbE(텐 기가비트 이더넷)로 업그레이드했습니다. Ceph는 네트워크 대역폭을 정말 많이 쓰는 친구거든요!

    Proxmox VE 설치 및 클러스터 구성

    Proxmox VE 설치는 생각보다 간단합니다. ISO 이미지를 USB에 구워서 각 노드에 설치하고, 웹 UI에 접속해서 몇 번의 클릭만으로 Proxmox 클러스터를 구성할 수 있죠. 이때 쿼럼(Quorum) 유지를 위해 최소 3개 이상의 노드가 안정적이라는 점을 꼭 기억해야 합니다. (홀수 노드가 좋습니다.)

    # 첫 번째 노드에서 클러스터 생성
    pvecm create home-ceph-cluster
    
    # 다른 노드에서 클러스터에 조인 (첫 번째 노드 IP와 패스워드 필요)
    pvecm add 192.168.1.10 --token <토큰_값>
    

    이 과정 자체는 매끄러웠습니다. Proxmox의 클러스터 관리 기능은 정말 잘 되어 있더라고요.

    Ceph 설치 및 OSD 추가: Proxmox Ceph 통합의 시작!

    이제 대망의 Ceph 차례입니다. Proxmox VE는 Ceph 통합 기능이 워낙 잘 되어 있어서 CLI(Command Line Interface)나 웹 UI에서 몇 번의 명령으로 Ceph를 설치하고 OSD(Object Storage Device)를 추가할 수 있습니다.

    # 각 Proxmox 노드에서 Ceph 설치
    pveceph install
    
    # Ceph Monitor(모니터) 설치 (클러스터 노드 중 최소 3개에 설치 권장)
    pveceph createmon
    
    # OSD 추가 (각 노드의 사용 가능한 디스크를 OSD로 지정)
    # 예: /dev/sdb 디스크를 OSD로 추가하고, NVMe SSD를 DB/WAL로 사용
    pveceph createosd /dev/sdb --db-device /dev/nvme0n1 --wal-device /dev/nvme0n1
    

    처음에는 단순히 `pveceph createosd /dev/sdb` 이런 식으로 HDD를 OSD로 추가했는데, 성능이 영 시원찮았습니다. Ceph의 BlueStore(블루스토어) 백엔드는 메타데이터를 빠르게 처리하는 것이 중요한데, HDD만으로는 한계가 명확하더라고요. 그래서 나중에는 NVMe SSD를 DB/WAL(데이터베이스/쓰기Ahead로그) 용도로 할당해서 성능을 끌어올렸습니다. 이 부분이 Ceph 성능 튜닝의 핵심 중 하나라는 걸 몸소 깨달았죠. 💡

    Proxmox VE 웹 UI에서 활성화된 Ceph OSD 목록을 보여주는 화면

    Proxmox VE 웹 UI의 Ceph 섹션입니다. 각 노드의 OSD 목록과 상태(UP/IN)를 한눈에 확인할 수 있습니다. 저 많은 OSD들이 제 소중한 데이터를 분산해서 저장하고 있죠.

    1년간 Proxmox Ceph를 운영하며 겪은 안정성 및 성능 이야기

    1년이라는 시간은 Ceph 클러스터의 진정한 가치를 시험하기에 충분했습니다. 정말 많은 것을 배우고 느꼈네요.

    안정성 (Stability) 회고: 역시 분산 스토리지!

    Ceph의 가장 큰 장점 중 하나는 데이터 안정성(Data Durability)입니다. 저도 OSD 하나가 갑자기 죽는 경험을 몇 번 했습니다. 그때마다 심장이 덜컥 내려앉았지만, Ceph는 3-복제 덕분에 자동으로 데이터 복구(Self-healing)를 시작하더라고요. 물론 복구 시간 동안 클러스터 성능이 저하되긴 했지만, 데이터 손실 없이 무사히 복구를 완료하는 모습을 보면서 “이래서 Proxmox Ceph 조합을 쓰는구나!” 하고 감탄했습니다. 👏

    Proxmox VE의 HA (High Availability, 고가용성) 기능도 빛을 발했습니다. 특정 Proxmox 노드가 재부팅되거나 문제가 생겼을 때, 해당 노드에서 실행 중이던 VM들이 다른 노드에서 자동으로 재시작되는 것을 여러 번 확인했습니다. Ceph 스토리지 덕분에 VM 디스크에 대한 접근성이 보장되었기 때문에 가능한 일이었죠. 물론 순간적인 서비스 중단은 있었지만, 시스템 전체의 가용성을 크게 높여주었습니다.

    성능 (Performance) 회고: 기대와 현실 사이

    초기에는 HDD OSD만으로 Ceph를 구성했더니, VM의 디스크 I/O가 심하게 느려지는 문제가 있었습니다. 특히 여러 VM이 동시에 디스크 작업을 할 때는 확연히 체감될 정도였죠. 웹 서버나 데이터베이스 서버를 돌리는데 응답 속도가 느려지니 답답하더라고요.

    이 문제를 해결하기 위해 NVMe SSD를 DB/WAL 디바이스로 추가하는 튜닝을 진행했습니다. 결과는 드라마틱한 성능 향상이었습니다! 특히 작은 파일 I/O나 랜덤 읽기/쓰기 성능이 눈에 띄게 좋아졌습니다. 💡 또한, 클러스터 내부 통신(Ceph Private Network)을 10GbE 스위치로 분리하고 업그레이드하면서 네트워크 병목 현상도 크게 줄였습니다. Ceph는 데이터를 복제하고 노드 간에 통신해야 하므로, 빠른 네트워크는 필수라는 걸 다시 한번 깨달았죠.

    Ceph 클러스터의 1년 간 성능(IOPS, 처리량, 지연 시간) 및 스토리지 사용량을 보여주는 Grafana 대시보드

    지난 1년간 Ceph 클러스터의 주요 성능 지표(IOPS, 처리량, 지연 시간)와 스토리지 사용량을 보여주는 Grafana 대시보드입니다. NVMe 캐시 추가 이후 I/O 성능이 크게 개선된 것을 볼 수 있습니다.

    제가 배운 교훈과 놓치지 말아야 할 포인트들 (주의사항 및 트러블슈팅)

    1년간의 여정은 순탄치만은 않았습니다. 수많은 삽질과 시행착오를 겪으며 얻은 교훈들을 공유합니다.

    1. 네트워크의 중요성 ⚠️: Ceph는 엄청난 양의 데이터를 노드 간에 주고받습니다. 특히 데이터 복제(Replication)와 리밸런싱(Rebalancing) 시에는 네트워크 대역폭을 거의 다 써버리기도 해요. 저는 1GbE로 시작했다가 병목 현상에 시달렸고, 결국 10GbE Private Network(프라이빗 네트워크)를 구성하면서 안정적인 성능을 확보했습니다. 반드시 Ceph 전용 네트워크를 분리하고, 가능한 한 빠른 대역폭을 확보하는 것이 좋습니다.
    2. OSD 디스크 선택 및 구성: HDD만으로 OSD를 구성하면 성능 한계가 명확합니다. 가능하다면 SSD나 NVMe SSD를 DB/WAL 디바이스로 활용하여 BlueStore의 메타데이터 처리 속도를 높이세요. 저는 OSD 구성 시 디스크 성능과 용량을 신중하게 고려하지 않아서 나중에 재구성하는 삽질을 좀 했습니다.
    3. 모니터링의 생활화: Ceph 클러스터는 생각보다 복잡합니다. `ceph -s` 명령으로 클러스터 상태를 주기적으로 확인하고, Proxmox VE 자체 모니터링 외에 Prometheus와 Grafana를 연동하여 세밀한 모니터링 대시보드를 구축하는 것이 좋습니다. OSD의 상태, 네트워크 트래픽, 스토리지 사용량 등을 실시간으로 확인해야 문제 발생 시 빠르게 대응할 수 있습니다.
    4. CRUSH Map (크러시 맵) 이해: Ceph는 CRUSH Map이라는 알고리즘을 사용해서 데이터를 어디에 저장하고 어떻게 복제할지 결정합니다. 이 CRUSH Map을 이해하면 데이터가 어떻게 분산되는지, 장애 시 복구가 어떻게 이루어지는지 파악하는 데 큰 도움이 됩니다. 홈랩에서는 기본 설정으로도 충분하지만, 좀 더 최적화된 구성을 원한다면 깊이 파고들어 볼 가치가 있습니다.
    5. 업그레이드 및 패치: Proxmox VE와 Ceph는 꾸준히 업데이트됩니다. 새로운 기능과 버그 수정이 포함된 업데이트는 중요하지만, 항상 사전에 충분히 테스트하고 백업 전략을 세운 후 진행해야 합니다. 저는 한 번 업데이트 후에 특정 OSD가 Unhealthy 상태가 되어 클러스터 재시작 후 복구하는 경험도 있었습니다.
    # Ceph 클러스터 상태 확인 (가장 기본적인 명령)
    ceph -s
    
    # OSD 디스크 트리 확인 (어떤 디스크가 OSD로 사용되는지, 상태는 어떤지)
    ceph osd tree
    
    # Ceph 로그 확인
    tail -f /var/log/ceph/ceph.log
    

    이런 명령들을 꾸준히 사용하며 클러스터의 “건강”을 체크하는 것이 중요합니다.

    결론 및 다음 단계

    Proxmox VE와 Ceph를 활용한 분산 스토리지 구축은 제 홈랩에 강력한 고가용성 스토리지를 선물해주었습니다. 물론 초기 설정의 복잡성, 그리고 10GbE 네트워크나 NVMe SSD 같은 추가적인 하드웨어 투자 비용은 무시할 수 없었지만, 그만큼 안정성과 성능이라는 큰 보상을 얻을 수 있었습니다. 특히 OSD 하나가 죽어도 데이터가 안전하고, VM이 자동으로 다른 노드에서 재시작되는 경험은 정말 든든하더라고요. 홈랩에서 중요한 서비스를 운영하거나, 미래의 스케일업(Scale-up)을 염두에 두고 있다면 Proxmox Ceph 조합은 충분히 고려해볼 만한 가치가 있습니다.

    물론 Ceph가 모든 상황에 완벽한 솔루션은 아닙니다. 작은 규모에서는 오히려 오버헤드가 더 클 수도 있고, 특정 워크로드(예: 매우 높은 단일 VM IOPS)에서는 최적화가 필요할 때도 있습니다. 하지만 저렴한 비용으로 엔터프라이즈급 스토리지의 맛을 볼 수 있다는 점은 홈랩 엔지니어에게는 정말 큰 매력이라고 생각합니다.

    다음 단계로는 현재 운영 중인 Ceph 클러스터의 성능을 좀 더 면밀히 분석하고, 특정 VM에 대한 스토리지 I/O 최적화 방안을 모색해보려고 합니다. 또한, CephFS(쎄프 파일 시스템)를 활용하여 파일 공유 시스템을 구축해보는 것도 재미있는 도전이 될 것 같네요. 혹시 여러분도 Proxmox Ceph에 대한 궁금한 점이나 공유하고 싶은 경험이 있다면 언제든지 댓글로 남겨주세요!

    Proxmox VE와 Ceph 분산 스토리지의 장점과 단점을 비교하는 인포그래픽

    Proxmox VE와 Ceph 분산 스토리지 조합의 주요 장점과 고려해야 할 단점을 요약한 인포그래픽입니다. 홈랩 환경에서의 활용 가치를 한눈에 파악할 수 있습니다.

    다음에 더 유익한 정보로 찾아뵙겠습니다. 13년차의 서버실이었습니다!