OpenStack을 공부하다 보면 결국 openstack 명령어와 친해져야 합니다. Horizon(웹 대시보드)도 좋지만, 실무·자동화는 CLI가 기본이거든요. DevStack 실습에서 실제로 쓴 명령들을 바탕으로, 입문자가 꼭 알아야 할 openstack CLI를 정리합니다.
1. 인증부터 — openrc
모든 명령은 인증 토큰이 필요합니다. DevStack은 openrc 스크립트를 주는데, 이걸 source하면 환경변수로 로그인 정보가 들어갑니다.
# 관리자(admin) 자격으로 환경 설정
source /opt/stack/devstack/openrc admin admin
# 토큰 확인(로그인 됐나)
openstack token issue -f value -c id | head -c 20; echo
자원(server·network·image·flavor·subnet…)만 바꾸면 되니, list/create/show/delete 네 동작으로 대부분을 합니다.
3. 상태 점검 3종 세트
클라우드가 정상인지 볼 때 제가 가장 먼저 치는 명령들입니다.
# 카탈로그에 서비스가 다 떴나
openstack service list
# 컴퓨트 노드(하이퍼바이저)가 살아있나
openstack hypervisor list
# 컴퓨트 서비스 상태(up/down)
openstack compute service list
실제로 DevStack 디버깅 때 hypervisor list가 비어 있어서 “컴퓨트 미등록”을 바로 알아챘습니다. CLI가 문제를 가장 빨리 보여줍니다.
4. 인스턴스 하나 띄우는 전체 흐름
이미지·플레이버·네트워크를 조합해 VM을 만듭니다.
# 재료 확인
openstack image list # OS 이미지
openstack flavor list # 사양(vCPU/RAM/디스크)
openstack network list # 네트워크
# 인스턴스 생성 (이미지+플레이버+네트워크)
openstack server create myvm \
--image cirros --flavor m1.nano --network testnet --wait
# 결과 확인
openstack server list
openstack console log show myvm # 부팅 로그(진짜 떴나)
--wait는 생성이 끝날 때까지 기다려 줍니다. 실패하면 openstack server show myvm -f value -c fault로 원인을 봅니다(저는 이걸로 “No valid host”를 확인했습니다).
5. 출력 다루기 — 자동화의 시작
CLI의 진짜 힘은 출력을 가공할 수 있다는 점입니다.
# 특정 값만 뽑기 (스크립트에 유용)
NET_ID=$(openstack network create testnet -f value -c id)
# 표 형식 / JSON 형식
openstack server list -f table
openstack server list -f json
-f value -c <컬럼>으로 ID만 뽑아 변수에 담으면, 그대로 쉘 스크립트 자동화로 이어집니다.
6. 정리
openstack CLI는 ①openrc로 인증 → ②자원 동작 패턴 → ③-f value -c로 값 추출 이 세 가지만 잡으면 끝입니다. 웹 대시보드로 감을 잡되, 반복·자동화는 CLI로 가세요. 클라우드 엔지니어의 실력은 결국 이 명령어들이 손에 붙는 데서 나옵니다.
지난 편까지 DevStack을 홈랩에 올리며 CPU·Neutron·Glance·Placement에서 연달아 부딪히고 하나씩 해결했습니다. 이번 편은 그 여정의 솔직한 후기와 교훈입니다. 결과를 미화하지 않고, 홈랩에서 DevStack에 도전할 분께 실질적인 지도를 남기려 합니다.
1. 어디까지 됐고, 무엇이 남았나
정직하게 말하면 “완벽한 원클릭 성공”은 아니었습니다.
✅ 코어 서비스 전부 기동(Keystone·Glance·Nova·Neutron·Cinder·Placement)
✅ geneve 테넌트 네트워크 생성 성공, 하이퍼바이저 등록, 이미지 업로드, 플레이버 확인
❌ 인스턴스 최종 부팅은 placement 자원 클래스 누락으로 막힘 — 여러 번의 부분 설치가 누적돼 생긴 불일치가 근본 원인
즉 OpenStack의 뼈대는 다 세웠지만, 마지막 조립이 어긋난 상태였습니다. 그리고 그 어긋남의 원인까지 정확히 짚었다는 게 이 도전의 진짜 소득입니다.
2. 가장 큰 교훈 — “깨끗한 상태에서 한 번에”
이번 삽질의 뿌리는 하나였습니다: 중간에 실패한 설치 위에 계속 재시도한 것. DevStack은 실행 때마다 여러 서비스의 DB를 다시 만들고 마무리 단계를 수행하는데, 앞 단계에서 죽으면 뒷 단계가 통째로 생략됩니다. 그 위에 또 돌리면 서로 다른 실행의 잔재가 뒤섞여 새로운 증상이 끝없이 나옵니다.
다음엔 실패하면 미련 없이 ./clean.sh로 초기화하고, 모든 수정을 local.conf에 미리 반영한 뒤 깨끗한 상태에서 한 번에 완주시키겠습니다.
3. 홈랩 DevStack 체크리스트 (다음 도전용)
항목
이유
OS는 Ubuntu (22.04/24.04)
DevStack 공식 지원
VM CPU 타입 = host
x86-64-v2 미노출 시 NumPy 크래시
RAM 12GB+ / 디스크 40GB+
올인원 최소선
local.conf에 geneve 명시
테넌트 네트워크 할당 실패 방지
실패 시 clean.sh 후 재시작
부분 설치 누적 방지(가장 중요)
완주 후에도 서비스 재시작 점검
엔드포인트/동기화 지연 대응
4. DevStack에 대한 현실 감각
DevStack은 “개발/학습용”입니다. 운영용이 아니고, 재부팅하면 상태가 깨지기도 합니다. 공부하고 부수고 다시 까는 용도로 쓰세요.
무겁습니다. 올인원도 12~16GB를 먹고, 설치에 수십 분이 걸립니다. 홈랩에선 “쓸 때만 켜는 랩”이 현실적입니다.
그럼에도 배움은 큽니다. 이 과정에서 CPU 가상화(x86-64-v2), Neutron의 geneve, placement의 자원 모델, 서비스 간 의존성을 에러를 통해 몸으로 익혔습니다. 매끄러운 성공보다 이 삽질에서 더 많이 배웠습니다.
5. 마치며
“튜토리얼대로 했는데 왜 안 되지?”는 홈랩의 일상입니다. 이번 DevStack 도전도 7번 넘게 깨졌지만, 각 실패의 원인을 파고드는 과정 자체가 클라우드 인프라를 이해하는 가장 빠른 길이었습니다. 다음엔 clean.sh 원샷으로 완주시키고, 실제 인스턴스를 띄워 SSH로 접속하는 순간까지 이어가는 후속편으로 돌아오겠습니다. 홈랩에서 프라이빗 클라우드에 도전하는 분들, 깨져도 그게 정상입니다. 원인을 하나씩 잡으면 됩니다.
지난 편에서 CPU 함정을 넘었습니다. 하지만 그건 시작이었습니다. DevStack이 완주할 때까지 Neutron → Glance → Nova/Placement에서 연달아 막혔거든요. 이번 편은 그 실제 에러들과 원인, 그리고 관통하는 하나의 패턴을 정리합니다. 같은 벽을 만난 분께 지도가 되길 바랍니다.
벽 2. 테넌트 네트워크 생성 실패 (503)
다시 돌리자 이번엔 네트워크 생성에서 죽었습니다.
HttpException: 503: No project network is available for allocation.
서비스·네트워크·이미지가 다 됐는데 인스턴스가 ERROR. 이유는 “No valid host was found”. 하이퍼바이저는 up인데 왜? nova-compute 로그가 진짜 원인을 보여줬습니다.
400 Bad Request: Unknown resource class in inventory ...
No such resource class MEMORY_MB.
즉 placement DB에 표준 자원 클래스(MEMORY_MB·VCPU·DISK_GB)가 로드되지 않아서, nova-compute가 자원 인벤토리를 placement에 등록하지 못했습니다. 인벤토리가 없으니 스케줄러가 “쓸 수 있는 호스트 없음”으로 판단한 거죠.
관통하는 하나의 패턴
벽 3·4·5를 보면 공통점이 보입니다.
서비스 프로세스는 떠 있는데, 그 뒤에 와야 할 “초기화·동기화·등록”이 안 끝나 있다.
geneve 풀 동기화, glance 엔드포인트, placement 자원 클래스 — 전부 stack.sh가 끝까지 완주하며 해줬어야 할 마무리 단계입니다. 제 경우 stack.sh가 중간에 여러 번 죽으면서 이 마무리들이 제각각 미완성으로 남았고, 그래서 재시도할 때마다 “부분적으로만 살아있는” 상태가 겹쳐 새 증상이 계속 튀어나온 겁니다.
여기서 배운 교훈: DevStack은 “깨끗한 상태에서 한 번에 완주”가 생명입니다. 중간 실패 후 그 위에 계속 재시도하면, 서로 다른 실행의 잔재가 섞여 디버깅이 미궁에 빠집니다. 다음 편에서 이 교훈과 현실적인 후기를 정리하겠습니다.
프라이빗 클라우드를 제대로 공부하려면 OpenStack을 직접 깔아봐야 합니다. 가장 빠른 길이 DevStack — 스크립트 하나로 올인원 OpenStack을 올려주는 개발/학습용 도구죠. 저는 이걸 Proxmox 홈랩에 올려봤습니다. 결론부터 솔직히 말하면 한 방에 안 됐고, 여러 번 깨졌습니다. 이번 편은 설치 준비부터 첫 번째 벽까지의 실전 기록입니다.
1. 먼저 정한 것 — OS는 Ubuntu
제 홈랩엔 Rocky 9 설치용 VM이 있었지만, DevStack엔 안 썼습니다. DevStack은 사실상 Ubuntu 전용이거든요(공식 지원·테스트가 우분투 중심). Rocky/CentOS는 지원이 불안정합니다. 그래서 깨끗한 Ubuntu 24.04로 갔습니다.
RuntimeError: NumPy was built with baseline optimizations:
(X86_V2) but your machine doesn't support: (X86_V2).
원인은 가상 CPU 타입이었습니다. Proxmox VM의 기본 CPU 타입(kvm64)은 호환성을 위해 최신 명령어셋(SSE4.2 등, x86-64-v2)을 감춥니다. 그런데 요즘 NumPy 휠은 x86-64-v2를 전제로 빌드돼서, 그 명령어가 없으면 임포트 단계에서 크래시합니다. nova의 콘솔 프록시가 NumPy를 쓰다 죽은 거죠.
해결은 지난 KVM 글에서 다룬 바로 그 포인트 — CPU 타입을 host로 바꿔 물리 CPU 기능을 그대로 노출하는 것이었습니다.
qm stop 200
qm set 200 --cpu host # 물리 i5의 명령어셋 그대로 노출
qm start 200
# VM 안에서 확인 — 이제 노출됨
grep -o -m1 sse4_2 /proc/cpuinfo # sse4_2
grep -o -m1 avx2 /proc/cpuinfo # avx2
이건 일반 DevStack 튜토리얼엔 없는 함정입니다. 물리 서버나 워크스테이션에선 안 생기고, “기본 CPU 타입 가상머신”에서만 터지거든요. 홈랩에서 VM으로 OpenStack·AI 라이브러리를 돌린다면 --cpu host는 기본으로 챙기세요.
다음 편
CPU를 고치고 다시 ./stack.sh를 돌렸습니다. 그런데 이번엔 네트워크(Neutron)에서, 그다음엔 Glance에서, 또 placement에서 연달아 막혔습니다. 다음 편에서 이 “서비스는 뜨는데 안 되는” 연속 삽질과 각각의 원인을 낱낱이 분석합니다. DevStack이 홈랩에서 왜 만만치 않은지, 제대로 보여드리겠습니다.
OpenStack 스토리지는 Glance(이미지)로 시작 → Cinder(블록)로 디스크 확장 → Swift(오브젝트)로 파일 보관, 이 세 축이 전부입니다. “블록은 디스크처럼, 오브젝트는 드라이브처럼”만 기억하면 헷갈릴 일이 없습니다. 홈랩 랩에선 Glance + Cinder(LVM)부터 붙여보는 걸 권합니다.
OpenStack을 공부하다 보면 대부분 Neutron(네트워킹)에서 벽을 만납니다. 저도 그랬습니다. 컴퓨트·스토리지는 직관적인데, 네트워크는 개념이 겹겹이라 헷갈리죠. 이번 글은 홈랩 랩에서 삽질하며 정리한 Neutron 핵심 개념 지도입니다. 이거 하나 잡으면 OpenStack의 절반은 끝납니다.
1. 왜 Neutron이 어려운가
Neutron은 소프트웨어로 네트워크(스위치·라우터·방화벽)를 통째로 구현합니다(SDN). 물리 네트워크 지식 + 가상 네트워크 개념 + 여러 에이전트가 한꺼번에 얽혀서 어렵게 느껴지는 겁니다. 그래서 개념을 계층으로 쪼개서 봐야 합니다.
2. 두 가지 네트워크 — Provider vs Tenant
Provider 네트워크
Tenant(Project) 네트워크
정체
기존 물리망에 직접 연결
프로젝트별 격리된 가상망
관리 주체
관리자
사용자(테넌트)
용도
외부와 바로 통신
내부 인스턴스끼리
격리
없음(공용)
VLAN/VXLAN으로 격리
쉽게 말해 Provider는 “회사 실제 네트워크에 꽂는 선”, Tenant는 “내 프로젝트만의 사설망”입니다. 실제 클라우드에선 테넌트망(사설) + 라우터 + 외부 provider망 조합을 가장 많이 씁니다.
3. 핵심 구성요소
ML2 플러그인 + L2 에이전트: 실제 스위칭 담당(Open vSwitch 또는 Linux Bridge). VLAN/VXLAN으로 망을 나눔.
L3 에이전트: 가상 라우터. 테넌트망 ↔ 외부망 라우팅, Floating IP 처리.
DHCP 에이전트: 인스턴스에 IP 자동 할당.
Security Group: 인스턴스 단위 방화벽(포트 허용/차단).
4. Floating IP — 외부 접속의 핵심
인스턴스는 보통 사설 IP만 가집니다. 외부에서 접속하려면 Floating IP(외부망의 공인/실 IP)를 인스턴스에 “붙였다 뗐다” 합니다. 개념이 NAT과 같아서, Floating IP ↔ 인스턴스 사설 IP를 라우터(L3 에이전트)가 매핑합니다.
외부 사용자 → Floating IP(외부망) → [L3 라우터/NAT] → 인스턴스 사설 IP
“인스턴스는 만들었는데 SSH가 안 돼요”의 99%는 Floating IP 미할당 + Security Group에서 22번 미허용입니다. 이 둘을 먼저 확인하세요.
5. 홈랩 랩에서의 배치
컨트롤러: neutron-server(API) + DHCP/L3 에이전트
컴퓨트: L2 에이전트(OVS/Linux Bridge)만
외부망은 Proxmox의 Linux Bridge(vmbr)에 물려 provider 네트워크로 노출
즉 Proxmox의 브리지가 OpenStack provider 네트워크의 물리 기반이 됩니다. 중첩 구조라 처음엔 헷갈리지만, “Proxmox 브리지 = 물리망, 그 위에 Neutron 가상망”으로 이해하면 정리됩니다.
6. 공부 순서
Provider 네트워크부터: 기존 망에 인스턴스를 직접 붙여 “통신되는 것”을 먼저 경험.
Tenant 네트워크 + 라우터: 사설망을 만들고 라우터로 외부와 연결.
Floating IP + Security Group: 외부 접속과 방화벽까지.
7. 정리
Neutron은 “Provider(실제망) vs Tenant(가상 사설망)”와 “L2(스위칭)·L3(라우팅/Floating IP)·Security Group(방화벽)”이라는 두 축으로 나눠 보면 정리됩니다. 외부 접속이 안 될 땐 Floating IP와 Security Group부터. 이 구조가 손에 익으면 OpenStack이 훨씬 만만해집니다.
OpenStack을 처음 보면 Nova, Neutron, Cinder, Keystone, Glance… 낯선 이름에 압도됩니다. 하지만 각각이 “클라우드의 한 부품”이라고 생각하면 의외로 명료합니다. 제가 홈랩 랩에서 공부하며 정리한, 핵심 컴포넌트 지도를 공유합니다.
1. 컴포넌트 한눈에
컴포넌트
역할
익숙한 비유
Keystone
인증·권한(Identity)
로그인·출입증
Glance
OS 이미지 저장소
설치 ISO 창고
Nova
컴퓨트(인스턴스 생성)
VM을 찍어내는 공장
Neutron
네트워킹(가상 네트워크)
가상 스위치·라우터
Cinder
블록 스토리지(볼륨)
붙였다 뗐다 하는 디스크
Horizon
웹 대시보드
관리 콘솔
여기에 오브젝트 스토리지 Swift, 오케스트레이션 Heat 등이 더 있지만, 위 6개가 “인스턴스 하나 띄우기”의 핵심입니다.
2. 인스턴스 하나 띄울 때 무슨 일이 벌어지나
컴포넌트가 어떻게 맞물리는지는 “VM 하나 생성” 흐름을 따라가면 단번에 이해됩니다.
1) 사용자 → Keystone 에 로그인 → 토큰 발급 (이후 모든 요청에 사용)
2) Nova 에 "인스턴스 생성" 요청
3) Nova → Glance 에서 OS 이미지 가져옴
4) Nova → Neutron 에 네트워크/포트 요청 (IP 할당)
5) (선택) Nova → Cinder 에서 볼륨 붙임
6) Nova 스케줄러가 적당한 compute 노드 선택 → VM 부팅
7) Horizon 대시보드에서 상태 확인
즉 Keystone(인증)으로 문을 열고 → Nova(컴퓨트)가 지휘하면서 → Glance(이미지)·Neutron(네트워크)·Cinder(볼륨)를 불러다 조립하는 구조입니다. 이 흐름 하나만 머리에 넣으면 나머지가 술술 풀립니다.
컴퓨트 노드: Nova-compute·Neutron 에이전트 — 실제 인스턴스가 여기서 돎
스토리지: Cinder 백엔드(LVM/Ceph 등)
그래서 컨트롤러는 CPU·메모리를, 컴퓨트는 인스턴스용 자원을 더 챙겨줘야 합니다. 제 랩에서 컴퓨트 노드에 RAM을 더 준 이유가 이것입니다.
4. 공부 순서 추천
Keystone부터: 인증이 안 되면 아무것도 안 됩니다. 토큰·프로젝트·롤 개념 먼저.
Glance → Nova: 이미지 올리고 인스턴스 하나 띄워보기(성취감 큼).
Neutron: 가장 어렵습니다. 네트워크가 되면 절반은 끝난 것.
Cinder: 볼륨 붙이기까지 하면 기본은 완성.
5. 정리
OpenStack은 이름이 많아 겁나 보이지만, “인증(Keystone) → 컴퓨트(Nova)가 이미지·네트워크·볼륨을 조립”이라는 큰 그림 하나면 충분히 잡힙니다. 각 컴포넌트를 따로 외우지 말고, 인스턴스 생성 흐름 속에서 이해하세요. 홈랩 랩에서 직접 인스턴스를 한 번 띄워보면 이 모든 게 손에 익습니다.
클라우드 엔지니어링을 제대로 공부하려면 결국 OpenStack을 손으로 만져봐야 합니다. 그런데 클라우드를 배우자고 클라우드에 돈을 쓰긴 아깝죠. 그래서 저는 Proxmox 홈랩 안에 OpenStack 멀티노드 랩을 꾸며 두고, 공부할 때만 켭니다. 실제 제 랩 구성과 프라이빗 클라우드 학습 환경을 만드는 법을 공개합니다.
1. 왜 집에서 OpenStack인가
프라이빗 클라우드의 실체를 이해하려면 컨트롤러·컴퓨트·네트워크·스토리지가 어떻게 맞물리는지 직접 봐야 합니다.
퍼블릭 클라우드는 “결과”만 보여주지만, OpenStack은 그 아래 구조를 다 열어 줍니다.
자격증·실무(프라이빗 클라우드 운영) 준비에 이만한 실습 환경이 없습니다.
2. 내 랩의 실제 토폴로지
저는 Proxmox 위에 노드 역할을 나눈 멀티노드 구성과, 간단히 굴리는 올인원 학습용을 함께 둡니다.
노드(VM)
역할
vCPU / RAM
deploy
배포·오케스트레이션
1 / 2GB
control
API·스케줄러·DB·메시지큐
4 / 2GB
compute01~03
실제 인스턴스(VM) 구동
각 1 / 4GB
all-in-one(study)
단일 노드 전체 스택
6 / 16GB
멀티노드는 “진짜 구조”를 배우는 데 좋고, 올인원은 “빠르게 기능만” 볼 때 좋습니다. 둘 다 갖춰두면 학습 목적에 맞게 골라 쓸 수 있습니다.
3. 핵심 전제 — 중첩 가상화(Nested Virtualization)
OpenStack의 컴퓨트 노드는 그 안에서 또 VM(인스턴스)을 돌립니다. 즉 “VM 안의 VM”이라, Proxmox 호스트에서 중첩 가상화가 켜져 있어야 합니다.
# Proxmox 호스트에서 중첩 가상화 확인 (Intel)
cat /sys/module/kvm_intel/parameters/nested # Y 여야 함
# 컴퓨트 노드 VM의 CPU 타입을 host로 (가상화 기능 노출)
qm set 105 --cpu host
이게 빠지면 인스턴스가 아예 안 뜨거나 QEMU 소프트웨어 에뮬레이션으로 기어갑니다. compute 노드엔 반드시 --cpu host를 주세요.
4. 자원 현실 — OpenStack은 무겁다
솔직히 말하면 OpenStack은 홈랩 기준으로 무겁습니다. 올인원만 해도 16GB를 잡아먹고, 멀티노드는 노드 5개가 동시에 떠야 합니다. 그래서 제 원칙은 —
평소엔 꺼둡니다. 학습할 때만 부팅하고, 끝나면 종료해 RAM을 회수합니다.
멀티노드와 올인원을 동시에 켜지 않습니다.
미니 PC 한 대의 RAM 예산 안에서 굴리려면 “쓸 때만 켠다”가 필수입니다.
홈랩에서 상시 운영이 아니라 학습용 랩으로 접근하는 게 현실적입니다.
5. 배포 방식 고르기
방식
특징
추천
DevStack
스크립트로 올인원, 개발·기능 확인용
빠른 입문
Kolla-Ansible
컨테이너 기반 멀티노드, 운영에 가까움
제대로 배우기
수동 설치
컴포넌트 하나씩, 가장 깊이 이해
자격증·심화
입문은 DevStack 올인원으로 “돌아가는 걸” 먼저 보고, 구조를 이해했으면 Kolla-Ansible로 멀티노드에 도전하는 흐름을 권합니다.
6. 정리
OpenStack은 무겁지만, 프라이빗 클라우드의 내부를 이해하는 데 이만한 교재가 없습니다. Proxmox의 중첩 가상화 위에 노드를 나눠 올리고, 필요할 때만 켜는 학습 랩으로 운영하면 미니 PC 한 대로도 충분히 공부할 수 있습니다. 다음 글에서는 OpenStack과 Proxmox 중 무엇을 선택해야 하는지, 그리고 핵심 컴포넌트를 하나씩 뜯어보겠습니다.
OpenStack 플레이버 설계는 단순히 vCPU 몇 개, RAM 몇 GB를 고르는 일이 아닙니다. 실제 운영 환경에서는 이 선택 하나 때문에 웹 서버는 멀쩡한데 DB만 느려지거나, 작은 배치 작업 하나가 Compute Node(컴퓨트 노드, 가상 머신을 실제로 실행하는 호스트)의 리소스를 오래 붙잡는 상황이 생기거든요.
저도 처음 홈랩에서 OpenStack을 만졌을 때는 “그냥 small, medium, large 만들면 되겠지”라고 생각했습니다. 그런데 실제로 써보니 꽤 다르더라고요. 같은 4 vCPU VM(Virtual Machine, 가상 머신)이라도 웹 워크로드와 데이터베이스 워크로드가 원하는 리소스 성격은 완전히 달랐습니다. CPU가 순간적으로 치솟는 서비스도 있고, 메모리를 꾸준히 쓰는 서비스도 있고, 디스크 I/O(Input/Output, 입출력) 때문에 전체가 버벅이는 경우도 있었습니다.
VM 사양은 넉넉해 보이는데 애플리케이션은 느리고, 반대로 어떤 VM은 리소스를 거의 안 쓰는데 너무 큰 플레이버를 물고 있는 상황을 본 적 있으신가요? 이 글에서는 Nova 플레이버를 워크로드 기준으로 어떻게 나누고, 어떤 명령어로 만들고, 운영 중 어떤 지표를 보고 조정할지 실무 관점으로 정리해보겠습니다.
OpenStack에서 플레이버가 VM 크기뿐 아니라 워크로드 배치 전략의 출발점이 된다는 흐름을 보여주는 개요 이미지입니다.
Nova 플레이버 개념: VM의 표준 사이즈표
OpenStack에서 Flavor(플레이버)는 VM을 만들 때 선택하는 리소스 묶음입니다. vCPU, Memory(메모리), Disk(디스크) 같은 기본값을 정의하고, 필요하면 Extra Specs(추가 속성)를 붙여 스케줄링, CPU 정책, 메모리 페이지 정책까지 조정합니다.
쉽게 말해 옷 사이즈표와 비슷합니다. small, medium, large라는 이름만 있다고 좋은 게 아니라, 우리 서비스에 맞는 치수표를 만들어야 합니다. 운영자가 미리 합리적인 사이즈를 만들어두면 사용자는 매번 VM 사양을 고민하지 않아도 되고, 인프라 입장에서는 리소스 낭비를 줄일 수 있습니다.
vCPU: 가상 CPU 개수입니다. CPU 연산이 많은 워크로드에서 중요합니다.
RAM: VM에 할당되는 메모리입니다. 캐시, DB, JVM 기반 서비스에서 특히 민감합니다.
Root Disk: 기본 부팅 디스크 크기입니다. 이미지 기반 배포에서는 너무 크게 잡지 않는 편이 관리가 쉽습니다.
Ephemeral Disk: VM 삭제 시 함께 사라지는 임시 디스크입니다.
Extra Specs: CPU 고정, Huge Pages(휴즈 페이지, 큰 메모리 페이지), NUMA(Non-Uniform Memory Access, 비균일 메모리 접근) 같은 고급 옵션을 지정할 때 씁니다.
중요한 포인트는 하나입니다. 플레이버는 “많이 주면 좋다”가 아닙니다. 워크로드 분석을 먼저 하고, 그 다음에 VM 모양을 맞춰야 합니다. 이 순서가 바뀌면 나중에 튜닝이 꽤 피곤해집니다.
워크로드 분석 기준: CPU, 메모리, 디스크, 네트워크
실제 운영에서는 워크로드를 크게 네 부류로 나눠 보는 게 편했습니다. 웹/API 서버, 데이터베이스, 배치/분석 작업, 네트워크 장비형 VM입니다. 이름은 단순하지만 확인해야 할 지표는 서로 다릅니다.
워크로드 유형
주요 병목
플레이버 설계 방향
확인할 지표
웹/API 서버
순간 CPU, 네트워크
중간 vCPU, 적당한 RAM, 수평 확장 고려
CPU 사용률, Load Average, 요청 지연
DB 서버
메모리, 디스크 I/O
RAM 여유, 빠른 볼륨, 필요 시 전용 CPU
iowait, 디스크 await, 캐시 히트율
배치/분석
CPU 지속 사용, 메모리 피크
작업 시간대와 동시 실행 수 기준으로 분리
pidstat, sar, 메모리 스왑 여부
네트워크 장비형 VM
패킷 처리, 인터럽트
CPU 정책과 네트워크 드라이버 확인
pps, 인터페이스 오류, softirq
실무에서는 평균값보다 피크 패턴을 더 자주 봅니다. CPU 평균이 낮아도 특정 시간대에 요청이 몰리면 체감 성능은 나빠집니다. 반대로 하루에 한 번만 도는 배치 작업에 항상 큰 플레이버를 붙여두면 리소스가 아깝습니다. VM 수가 늘어나면 이 차이가 진짜 크게 느껴지더라고요.
OpenStack 플레이버 설계 실전: CLI로 생성하기
이제 실제 명령어로 가보겠습니다. 아래 예시는 OpenStackClient 기준입니다. 환경마다 인증 방식은 다르지만, 보통은 OpenRC 파일을 source 한 뒤 실행합니다.
여기서 RAM 단위는 MB입니다. 4096은 4GB, 8192는 8GB로 보면 됩니다. 처음엔 저도 이 단위를 대충 보고 넘겼다가 “왜 생각보다 작게 잡혔지?” 하고 한참 봤던 기억이 있습니다. 은근히 자주 하는 실수입니다.
DB나 지연 시간에 민감한 워크로드는 Extra Specs(추가 속성)를 고민할 수 있습니다. 예를 들어 CPU를 공유 정책으로 둘지, dedicated(전용 할당) 정책을 쓸지 판단해야 합니다. 다만 hw:cpu_policy=dedicated 같은 설정은 Compute Node의 전용 CPU 집합, Placement 리소스, Nova 설정이 맞아야 의미가 있습니다. 명령어만 넣는다고 마법처럼 빨라지지는 않더라고요.
OpenStack CLI로 기본 플레이버를 만들고 Extra Specs를 붙여 워크로드별로 구분하는 과정을 나타낸 구성 이미지입니다.
hw:cpu_policy=dedicated는 전용 pCPU(Physical CPU, 물리 CPU)에 vCPU를 고정하는 정책이고, hw:mem_page_size=large는 큰 메모리 페이지 사용을 요청합니다. 단, Huge Pages는 호스트 커널과 libvirt/KVM 쪽 준비가 필요합니다. 지원되지 않는 환경에서 무작정 넣으면 VM 생성이 실패할 수 있습니다.
가상 머신 최적화: 작은 VM 여러 대 vs 큰 VM 한 대
가상 머신 최적화에서 자주 나오는 고민이 있습니다. “2 vCPU VM 여러 대가 나을까, 8 vCPU VM 한 대가 나을까?” 정답은 워크로드에 따라 다릅니다. 웹/API 서버처럼 stateless(상태를 서버에 많이 저장하지 않는 구조)에 가까우면 작은 VM을 여러 대 두고 로드밸런서로 나누는 편이 운영상 편했습니다. 장애 격리도 좋고, 배포 롤백도 덜 무섭습니다.
반대로 DB처럼 상태가 크고 디스크 I/O가 중요한 서비스는 무작정 쪼개기 어렵습니다. 이 경우에는 메모리와 디스크 경로를 먼저 보고, 필요하면 전용 CPU 정책이나 빠른 Cinder Volume(신더 볼륨, OpenStack 블록 스토리지)을 붙이는 식으로 접근합니다.
먼저 애플리케이션의 병목 후보를 정합니다. CPU인지, 메모리인지, 디스크인지 구분합니다.
작은 기본 플레이버로 시작하되, 모니터링 지표를 붙입니다.
피크 시간대에 CPU iowait, 메모리 swap, 디스크 await 같은 값을 확인합니다.
증설이 필요하면 같은 계열의 다음 플레이버로 올립니다.
계속 같은 병목이 반복되면 플레이버 문제가 아니라 애플리케이션 구조나 스토리지 설계를 다시 봅니다.
추천하는 방식은 “처음부터 대형 플레이버”가 아니라 계열을 나눠 점진적으로 올리는 방식입니다. 예를 들어 web.small → web.medium → web.large처럼 같은 성격 안에서만 키우면 운영자가 판단하기 쉽습니다. 이거 진짜 편하더라고요.
점검 명령어: VM 내부와 OpenStack 외부를 같이 보기
플레이버가 적절한지 보려면 VM 내부 지표와 OpenStack 외부 상태를 같이 봐야 합니다. VM 안에서는 리눅스 성능 도구를 씁니다. 아래 명령어는 대부분의 리눅스 서버에서 sysstat 패키지를 설치하면 사용할 수 있습니다.
# CPU 사용률과 iowait 확인
sar -u 1 5
# 디스크 서비스 시간, 대기열, 사용률 확인
iostat -x 1 5
# 프로세스별 CPU/메모리/디스크 사용 확인
pidstat -urd 1 5
# 메모리와 swap 확인
free -h
해석은 이렇게 합니다. sar에서 %iowait가 계속 눈에 띄게 높다면 CPU가 부족하다기보다 디스크 응답을 기다리는 쪽을 의심합니다. iostat -x에서는 await, %util, r/s, w/s를 함께 봅니다. %util이 계속 높은데 await도 같이 늘면 스토리지 병목 가능성이 커집니다. free -h에서 swap 사용량이 증가하고 줄지 않는다면 메모리 플레이버를 올리거나 애플리케이션 메모리 설정을 줄여야 합니다.
OpenStack 쪽에서는 현재 하이퍼바이저 자원 상태와 VM 배치를 확인합니다. 일부 명령은 관리자 권한이 필요할 수 있습니다.
openstack hypervisor list
openstack hypervisor stats show
openstack server list --all-projects --long
openstack server show <SERVER_ID>
여기서 보는 핵심은 “한 Compute Node에 특정 유형 VM이 몰렸는가”입니다. CPU 집약형 VM이 한 노드에 너무 몰리면 개별 VM 스펙은 정상이어도 전체 성능이 흔들릴 수 있습니다. 이때는 Availability Zone(가용 영역), Host Aggregate(호스트 집합), Flavor Extra Specs를 조합해서 배치 정책을 나누는 쪽을 검토합니다.
주의사항과 트러블슈팅: 자주 헷갈리는 부분
OpenStack 플레이버 설계에서 가장 많이 하는 실수는 “플레이버 이름만 그럴듯하게 만든 것”입니다. m1.large라는 이름은 익숙하지만, 정작 어떤 워크로드용인지 아무도 모르면 시간이 지나면서 엉망이 됩니다. 그래서 이름에 목적을 넣는 편이 좋습니다. 예를 들면 m1.web.small, m1.db.memory, m1.batch.cpu처럼요.
VM 생성 실패: Extra Specs가 호스트 기능과 맞지 않을 때 발생합니다. flavor show와 nova-compute 로그를 같이 봅니다.
메모리가 부족함: swap이 늘면 체감 성능이 급격히 나빠집니다. RAM 증설 또는 애플리케이션 heap 설정을 조정합니다.
CPU를 많이 줬는데도 느림: CPU steal, iowait, 스레드 병렬성, 애플리케이션 락을 같이 봐야 합니다.
재현 가능한 시나리오 하나를 들어보겠습니다. 웹 서버 VM에 2 vCPU, 4GB RAM을 주고 운영했는데 피크 시간에 응답이 느려졌습니다. 처음에는 CPU가 부족한 줄 알고 4 vCPU로 올렸습니다. 그런데 개선이 애매했습니다. 다시 보니 sar에서 iowait가 계속 보였고, iostat에서는 디스크 대기가 늘어났습니다. 원인은 로그가 같은 루트 디스크에 과하게 쌓이는 구조였고, 별도 볼륨으로 로그 경로를 분리하니 훨씬 안정됐습니다.
검증과 결과: 플레이버 변경 후 확인할 것
플레이버를 바꿨다면 “VM이 켜졌다”에서 끝내면 안 됩니다. 저는 최소한 아래 순서로 확인합니다. 특히 resize 이후에는 환경에 따라 confirm 단계가 필요할 수 있으니 운영 정책도 같이 확인하세요.
VM 생성 또는 resize(크기 변경)가 정상 완료됐는지 확인합니다.
게스트 OS에서 CPU, 메모리, 디스크가 기대한 값으로 보이는지 확인합니다.
애플리케이션 로그에 오류나 타임아웃이 늘지 않았는지 봅니다.
피크 시간대 지표를 이전과 비교합니다.
동일 계열 VM 여러 대의 편차가 크지 않은지 확인합니다.
openstack server resize --flavor m1.api.medium <SERVER_ID>
openstack server resize --confirm <SERVER_ID>
# VM 내부에서 확인
nproc
free -h
lsblk
결과 해석 기준은 간단하게 잡아두면 좋습니다. CPU 사용률이 피크 시간에만 높고 요청 지연이 없다면 굳이 올리지 않아도 됩니다. 메모리는 swap이 생기는지, 디스크는 iowait와 await가 함께 나빠지는지 봅니다. 네트워크는 대역폭뿐 아니라 인터페이스 오류, retransmission(재전송)도 같이 봐야 합니다.
CPU, 메모리, 디스크 I/O 지표를 기준으로 플레이버 변경 전후를 비교하는 검증용 대시보드 예시입니다.
자주 묻는 질문: OpenStack 플레이버 설계 FAQ
Q1. 플레이버는 몇 종류로 시작하는 게 좋나요?
처음부터 너무 많이 만들지 않는 걸 추천합니다. 웹/API용 2~3개, 메모리 중심 1~2개, CPU 중심 1~2개 정도로 시작하고 실제 사용 패턴을 보면서 늘리는 편이 관리하기 쉽습니다.
Q2. dedicated CPU는 무조건 좋은 선택인가요?
아닙니다. 지연 시간에 민감하거나 성능 격리가 중요한 VM에는 도움이 될 수 있지만, 전체 클러스터 효율은 떨어질 수 있습니다. 호스트의 전용 CPU 구성과 운영 정책이 준비된 경우에만 쓰는 게 좋습니다.
Q3. 디스크 크기를 크게 잡으면 성능도 좋아지나요?
대부분의 경우 단순 디스크 용량과 성능은 별개로 봐야 합니다. 성능은 스토리지 백엔드, 볼륨 타입, 캐시 정책, I/O 패턴 영향을 더 많이 받습니다.
마무리: 워크로드별 추천 기준
OpenStack에서 VM 구성을 잘 잡고 싶다면 플레이버를 “사이즈”가 아니라 “운영 정책”으로 봐야 합니다. 이 관점이 잡히면 OpenStack 플레이버 설계가 훨씬 쉬워집니다.
웹/API 서버라면 작은 VM 여러 대와 수평 확장을 우선 추천합니다.
DB 서버라면 메모리, 디스크 I/O, 볼륨 타입을 먼저 보고 필요할 때 전용 CPU를 검토하세요.
배치 작업이라면 실행 시간대와 동시성 기준으로 CPU형 플레이버를 따로 두는 게 좋습니다.
네트워크 장비형 VM이라면 CPU 정책, 인터럽트, 드라이버, 패킷 처리량을 함께 봐야 합니다.
제 기준에서는 기본 플레이버를 작고 명확하게 시작한 뒤, 관측 지표를 보고 계열을 늘리는 방식이 가장 덜 아팠습니다. 한 번에 완벽한 표준안을 만들려고 하면 오히려 오래 걸리더라고요. 다음 글에서는 Host Aggregate와 Availability Zone을 이용해서 특정 플레이버를 특정 Compute Node 그룹에 배치하는 방법을 다룰 예정입니다. 이전 글에서 다룬 OpenStack 네트워크 기본 구조도 함께 참고하면 흐름이 더 잘 이어질 겁니다.
웹, DB, 배치, 네트워크형 VM을 어떤 기준으로 나눌지 한눈에 정리한 요약 이미지입니다.
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 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 접속 경로에서 드러납니다.
Ceph 병목: OSD latency, PG 상태, recovery/backfill, full/nearfull, 네트워크 손실, CRUSH 배치 문제로 드러납니다.
현장에서 자주 본 실패 패턴은 HEALTH_OK니까 Ceph는 아니라고 너무 빨리 결론 내리는 경우였습니다. HEALTH_OK는 클러스터의 일관성과 위험 상태를 보는 신호에 가깝지, 모든 OSD가 빠르고 모든 클라이언트 경로가 정상이라는 보장은 아닙니다. 반대로 HEALTH_WARN이 있어도 실제 사용자 지연의 직접 원인은 libvirt secret 불일치일 수 있습니다. 그래서 Ceph와 OpenStack을 항상 나란히 봐야 합니다.
Ceph 병목을 잡는 첫 10분: 범위를 먼저 자르세요
처음부터 fio를 돌리거나 설정값을 바꾸지 마세요. 저는 먼저 영향을 받는 범위를 세 가지 질문으로 자릅니다.
모든 VM이 느린가, 특정 compute node의 VM만 느린가?
볼륨 작업만 느린가, 이미지 부팅과 업로드도 같이 느린가?
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가 높으면 스토리지 문제가 아니라 호스트 자원 경합일 수 있습니다.
OSD latency, iostat, 네트워크 지표를 나란히 비교하며 병목 지점을 좁히는 장면입니다.
Nova, Cinder, Glance 설정은 같은 Ceph를 보는가부터 확인합니다
OpenStack Ceph 연동에서 의외로 많은 문제는 Ceph 성능이 아니라 설정 일관성에서 생깁니다. Glance는 Ceph RBD에 이미지를 저장하는데 Nova는 로컬 파일 기반으로 부팅한다든지, Cinder와 Nova가 서로 다른 user/keyring을 본다든지, compute node마다 /etc/ceph/ceph.conf 내용이 다른 식입니다. 이거 진짜 자주 나옵니다.
rbd_flatten_volume_from_snapshot = false는 clone 기반 흐름을 살려 생성 속도를 빠르게 가져갈 수 있지만, clone depth가 깊어지면 나중에 읽기 경로가 복잡해질 수 있습니다. rbd_max_clone_depth는 그 균형점입니다. 볼륨 생성 속도가 중요하고 snapshot 계층이 잘 관리된다면 clone을 적극적으로 쓰는 편이 유리합니다. 반대로 오래된 snapshot에서 파생된 볼륨이 많이 쌓이고 삭제 정책이 느슨한 환경이라면 flatten 전략을 더 보수적으로 잡아야 합니다.
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에 두면 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 단위 문제가 나오면 아래 명령을 거의 습관처럼 칩니다.
정상 노드와 문제 노드의 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과 테스트 볼륨으로 재현 경로를 확인하고, 업무 영향이 낮은 시간대에 점진적으로 부하를 올리는 편이 안전합니다. 스토리지는 한 번 흔들리면 넓게 흔들리는 영역이라서, 확인도 단계적으로 해야 합니다.
Nova, Cinder, Glance 서비스가 각각 vms, volumes, images 풀을 사용하는 구성을 보여주는 이미지입니다.
운영 체크리스트: 성능보다 먼저 무너지는 것들
pool 분리: 운영 환경에서는 images, vms, volumes pool을 분리해 원인 분석과 정책 적용을 쉽게 만듭니다.
CRUSH rule 확인: HDD, SSD, NVMe가 섞인 환경에서는 장치 class와 rule이 의도대로 적용되는지 확인합니다.
시간 동기화: 모든 컨트롤러, compute, storage node에서 chrony 또는 NTP 상태를 확인합니다.
복구 작업 정책: 업무 시간과 점검 시간의 recovery/backfill 정책을 다르게 가져갈지 결정합니다.
로그 보존: nova-compute, cinder-volume, glance-api, libvirt 또는 virtqemud, kernel 로그가 충분히 남도록 설정합니다.
배포 일관성: ceph.conf, keyring, libvirt secret이 모든 관련 노드에 동일하게 배포되는지 검증합니다.
여기서 제일 많이 과소평가되는 항목은 배포 일관성입니다. Ceph 자체가 아무리 튼튼해도 compute node 한 대가 오래된 ceph.conf를 보고 있으면 사용자에게는 OpenStack Ceph 성능 문제로 접수됩니다. 자동화 도구를 쓰더라도 실제 파일 checksum을 비교하는 습관이 도움이 됩니다.
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 운영 가이드를 함께 연결해두면 독자가 다음 점검 단계로 이동하기 좋습니다.
증상별로 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 로그를 통해 병목 위치를 먼저 좁히면 불필요한 튜닝을 줄일 수 있습니다. 운영에서 좋은 트러블슈팅은 멋진 한 방이 아니라, 잘못된 가능성을 빠르게 제거하는 과정에 더 가깝습니다.