13년차의 서버실

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

[카테고리:] openstack

  • [OpenStack] OpenStack에서 Ollama로 프라이빗 LLM 추론 환경 구축하기

    [OpenStack] OpenStack에서 Ollama로 프라이빗 LLM 추론 환경 구축하기

    [OpenStack] OpenStack과 Ollama로 프라이빗 LLM 추론 환경 구축하기

    OpenStack 인스턴스에 Ollama를 올려서 프라이빗 LLM 추론 환경을 만드는 이야기는 요즘 꽤 자주 나오더라고요. 저도 홈랩이랑 업무성 테스트 환경을 오가면서 이것저것 붙여봤는데, 공개 SaaS에 바로 데이터를 넣기 애매한 상황에서는 Ollama OpenStack 조합이 생각보다 실용적이었습니다. 특히 로그, 운영 문서, 내부 위키처럼 외부 반출이 조심스러운 데이터를 다룰 때는 더 그렇고요. 혹시 ‘GPU는 비싸고, 그렇다고 완전 관리형 서비스만 믿기엔 불안하다’ 같은 고민 해보신 적 있으신가요? 저는 딱 그 지점에서 이 구성을 꽤 오래 만지작거렸습니다.

    이번 글은 특정 벤더 홍보가 아니라, OpenStack AI 실험을 실제 인프라 관점에서 어떻게 굴려볼 수 있는지 정리한 사례입니다. 처음엔 이게 뭔가 싶었는데, 막상 해보니 구조는 단순합니다. OpenStack 가상머신 위에 Ollama를 올리고, 모델을 내려받고, 네트워크와 스토리지, 보안그룹만 제대로 잡아주면 됩니다. 다만 여기서 중요한 포인트가 몇 개 있습니다. CPU만으로도 테스트는 되지만, 추론 속도와 동시성은 기대치를 잘 관리해야 하거든요.

    Ollama OpenStack 기반 프라이빗 LLM 아키텍처 다이어그램

    OpenStack 기반 프라이빗 LLM 아키텍처를 한눈에 보여주는 개요 이미지입니다.

    1. 왜 굳이 OpenStack에 Ollama를 올렸을까

    쉽게 말해 Ollama는 로컬이나 서버에서 대형 언어 모델을 비교적 간단하게 실행하게 도와주는 런타임(runtime, 실행 환경)입니다. 반면 OpenStack은 가상머신, 네트워크, 볼륨 같은 인프라 자원을 묶어서 운영할 수 있게 해주는 IaaS(Infrastructure as a Service, 서비스형 인프라) 플랫폼이고요. 둘을 합치면 뭐가 좋으냐면, 프라이빗 LLM 실험 환경을 내가 통제하는 네트워크 안에서 만들 수 있습니다.

    제가 직접 해보니 이 조합의 장점은 아래처럼 정리되더라고요.

    • 데이터 통제: 추론 요청과 응답이 내부 네트워크에 머물 수 있습니다.
    • 배포 유연성: 테스트용 인스턴스와 운영성 인스턴스를 분리하기 쉽습니다.
    • 복제 가능성: 스냅샷(snapshot, 시점 복사)이나 이미지 기반으로 재현이 편합니다.
    • 네트워크 제어: 보안그룹(Security Group, 가상 방화벽)과 내부망만으로 노출 범위를 제한할 수 있습니다.
    • 확장 여지: 나중에 API Gateway, Reverse Proxy, 모니터링을 붙이기 좋습니다.

    반대로 단점도 있습니다. Ollama 자체는 비교적 쉽게 뜨는데, 모델 파일이 크고 디스크 I/O나 메모리 조건을 꽤 타는 편입니다. 그리고 OpenStack 쪽에서 Floating IP, 내부망, 볼륨 연결, 이미지 준비 같은 기본기가 안 되어 있으면 이상하게 자꾸 삽질하게 됩니다. 저도 처음엔 애플리케이션 문제가 아니라 네트워크 정책 때문에 응답이 안 와서 한참 헤맸거든요 ㅎㅎ

    2. Ollama OpenStack 구성 개념 쉽게 이해하기

    이 구성을 너무 어렵게 볼 필요는 없습니다. 전체 흐름은 이렇습니다.

    1. OpenStack에서 Ubuntu 계열 Linux 인스턴스를 하나 만듭니다.
    2. 필요하면 Block Storage(블록 스토리지) 볼륨을 따로 붙입니다.
    3. 서버에 Ollama를 설치합니다.
    4. 원하는 모델을 내려받아 로드합니다.
    5. 보안그룹과 Reverse Proxy(리버스 프록시, 요청 전달기)를 붙여 내부 사용자만 접근하게 합니다.
    6. curl이나 간단한 앱에서 API 호출로 검증합니다.

    여기서 핵심은 모델 실행 위치와 접근 제어입니다. 모델은 인스턴스 안에서 돌고, 사용자는 HTTP API로 붙습니다. 즉, AI 서비스처럼 보이지만 사실은 내부 애플리케이션 하나 더 배포하는 느낌에 가깝습니다. 그래서 인프라 엔지니어 입장에서는 웹 애플리케이션 운영하듯 접근하면 편합니다.

    구성 요소 역할 운영 포인트
    OpenStack Instance Ollama 실행 서버 vCPU, RAM, 디스크 여유 확인
    Volume 모델 파일 저장 루트 디스크와 분리 시 관리 편함
    Security Group 접근 제어 22, 11434 등 최소 포트만 허용
    Private Network 내부 통신 내부 서비스 전용망 권장
    Reverse Proxy TLS, 접근 경로 정리 Nginx 등으로 앞단 보호
    Ollama 모델 추론 런타임 모델 다운로드와 실행 담당

    3. 배포 전에 체크할 현실적인 준비 사항

    이 단계 무시하면 나중에 꼭 되돌아오게 됩니다. 실제로 써보니까 아래 세 가지가 제일 중요했습니다.

    3-1. 컴퓨트 리소스 계획

    정확한 수치는 환경마다 달라서 함부로 말하면 안 되지만, 적어도 메모리 여유는 넉넉하게 잡는 게 좋습니다. 작은 모델 테스트와 실서비스성 사용은 체감 차이가 큽니다. CPU-only 환경은 검증용으로는 괜찮아도, 응답 지연이 길어질 수 있습니다. GPU 패스스루(passthrough, 장치 직접 할당)나 vGPU를 쓰는 환경이라면 OpenStack 쪽 설정 난이도가 확 올라가니, 처음에는 CPU 기반 검증 후 확장하는 편이 안전합니다.

    3-2. 스토리지 분리

    모델 파일은 금방 용량을 먹습니다. 그래서 루트 디스크에 다 넣기보다 별도 볼륨을 붙여서 /var/lib/ollama 같은 경로를 분리하는 방식이 운영상 편했습니다. 백업, 확장, 재배포가 훨씬 수월하거든요.

    3-3. 보안 기준

    Ollama API를 외부에 바로 열어두는 건 추천하지 않습니다. 적어도 다음은 챙기세요.

    • 내부망 우선 배치
    • 보안그룹 최소 허용
    • SSH 키 기반 로그인
    • 필요 시 Nginx로 TLS 종료
    • 로그와 요청 이력 점검

    여기서 중요한 포인트! 프라이빗 LLM이라고 해서 자동으로 안전해지는 건 아닙니다. 외부 SaaS 대신 내부에 둔다는 의미일 뿐, 접근 제어를 대충 하면 오히려 더 위험해질 수 있습니다.

    4. 실전 구현: OpenStack 인스턴스에 Ollama 설치

    이제 본격적으로 해보겠습니다. 아래 예시는 Ubuntu 계열 Linux 인스턴스를 기준으로 정리했습니다. 저는 보통 먼저 인스턴스를 띄우고, 볼륨 붙이고, 방화벽부터 확인한 다음 애플리케이션을 올립니다. 순서를 바꾸면 나중에 원인 분석이 꼬이더라고요.

    4-1. 보안그룹과 인스턴스 준비

    필수 포트는 최소한으로만 엽니다. SSH용 22 포트, 그리고 내부 호출이 필요하면 Ollama 기본 포트로 알려진 11434를 내부 대역에만 허용하는 식이 무난합니다.

    # 예시: 서버 접속 후 기본 점검
    uname -a
    lsblk
    ip a
    sudo timedatectl set-timezone Asia/Seoul

    볼륨을 별도로 붙였다면 먼저 마운트합니다.

    sudo mkfs.ext4 /dev/vdb
    sudo mkdir -p /data/ollama
    sudo mount /dev/vdb /data/ollama
    sudo blkid /dev/vdb

    /etc/fstab에 UUID 기준으로 등록해두면 재부팅 후에도 안정적입니다.

    sudo cp /etc/fstab /etc/fstab.bak
    sudo editor /etc/fstab
    UUID=YOUR_VOLUME_UUID  /data/ollama  ext4  defaults,nofail  0  2

    4-2. Ollama 설치

    공식 설치 방식은 시점에 따라 바뀔 수 있으니 실제 배포 전에는 공식 문서를 꼭 같이 확인하시는 걸 권장합니다. 다만 큰 흐름은 비슷합니다. 서버에 패키지를 설치하고 서비스로 띄우는 구조입니다.

    curl -fsSL https://ollama.com/install.sh | sh
    sudo systemctl enable ollama
    sudo systemctl status ollama

    설치 후 서비스가 떠 있는지 먼저 확인하세요. 여기서 안 뜨면 모델 문제 보기 전에 서비스 로그부터 보는 게 맞습니다.

    sudo journalctl -u ollama -n 100 --no-pager
    OpenStack 인스턴스에서 Ollama 배포 구성을 설명하는 이미지

    배포 과정 중 네트워크와 스토리지, 서비스 구성을 설명하는 이미지입니다.

    4-3. 데이터 경로 분리

    모델 저장 경로를 별도 볼륨으로 빼고 싶다면 서비스 환경 변수를 조정하는 식으로 운영할 수 있습니다. 배포 방식에 따라 경로 정의가 다를 수 있어서 저는 서비스 오버라이드 방식으로 처리하는 편입니다.

    sudo mkdir -p /data/ollama/models
    sudo systemctl edit ollama
    [Service]
    Environment="OLLAMA_MODELS=/data/ollama/models"
    Environment="OLLAMA_HOST=0.0.0.0:11434"
    sudo systemctl daemon-reload
    sudo systemctl restart ollama
    sudo systemctl show ollama --property=Environment

    여기서 OLLAMA_HOST를 0.0.0.0으로 열었다면, 네트워크 레벨에서 반드시 접근 대역을 제한하세요. 애플리케이션이 열려 있다는 건 생각보다 금방 스캔됩니다.

    4-4. 모델 다운로드와 실행

    모델 이름은 시점마다 추가되거나 바뀔 수 있으니, 실제 사용 시에는 현재 지원 목록을 직접 확인하셔야 합니다. 이 글에서는 특정 최신 모델명을 무리하게 적기보다, 일반적인 사용 흐름 위주로 보겠습니다.

    ollama pull llama3
    ollama list
    ollama run llama3

    제가 직접 해보니 처음 실행은 모델 준비 때문에 시간이 걸릴 수 있습니다. 이때 ‘멈췄나?’ 싶어서 여러 번 다시 치면 오히려 꼬입니다. 디스크 사용량과 네트워크 다운로드 상태를 같이 보면서 기다리는 게 낫습니다.

    4-5. API 호출 테스트

    Ollama는 HTTP API 기반으로 붙이기 쉬운 편입니다. 간단한 curl 테스트부터 해보면 감이 금방 옵니다.

    curl http://127.0.0.1:11434/api/generate \
      -H "Content-Type: application/json" \
      -d '{
        "model": "llama3",
        "prompt": "OpenStack 환경에서 프라이빗 LLM을 운영할 때 주의할 점 3가지를 설명해줘.",
        "stream": false
      }'

    내부 다른 서버에서 붙일 거라면 127.0.0.1 대신 인스턴스의 프라이빗 IP를 사용하면 됩니다. 다만 이 경우 보안그룹과 OS 방화벽을 같이 확인하세요.

    5. Ollama와 Reverse Proxy로 운영 편의성 높이기

    실무 느낌으로 가려면 앞단에 Reverse Proxy를 두는 게 편합니다. Nginx를 붙이면 TLS 종료, 접근 경로 통합, 간단한 접근 제어가 가능하거든요. 나중에 인증 프록시나 API Gateway로 확장하기도 좋습니다.

    sudo apt update
    sudo apt install -y nginx
    server {
        listen 80;
        server_name ollama.internal;
    
        location / {
            proxy_pass http://127.0.0.1:11434;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
    sudo nginx -t
    sudo systemctl reload nginx

    여기까지 오면 내부 DNS나 /etc/hosts로 이름을 붙여서 접근하기도 편해집니다. 작은 차이 같아도 운영성은 꽤 올라갑니다. 특히 여러 추론 서버를 비교 테스트할 때요.

    6. ⚠️ 실제 겪었던 문제와 트러블슈팅

    이 섹션은 좀 현실적으로 적어볼게요. 저는 이 작업하면서 애플리케이션보다 인프라 쪽에서 더 많이 막혔습니다.

    6-1. 포트는 열었는데 접속이 안 되는 문제

    처음엔 분명 11434를 열었는데 외부에서 응답이 없었습니다. 알고 보니 셋 중 하나였습니다.

    • 서비스가 127.0.0.1에만 바인딩됨
    • OpenStack 보안그룹에는 열었지만 OS 방화벽이 차단
    • Floating IP가 아닌 내부망 전용 인스턴스라 접근 경로 자체가 다름

    해결은 단순합니다. ss -lntp, ufw status, 보안그룹 규칙을 순서대로 확인하면 됩니다.

    ss -lntp | grep 11434
    sudo ufw status
    ip route

    6-2. 디스크 공간 부족

    작은 테스트 VM에서 시작했다가 모델을 몇 개만 내려받아도 금방 공간이 줄어듭니다. 이건 진짜 많이 겪는 문제예요. 루트 디스크를 아끼겠다고 너무 작게 잡으면 결국 다시 옮기게 됩니다. 그래서 초반부터 모델 저장 경로를 분리하는 걸 추천드립니다.

    6-3. 응답 속도가 너무 느린 문제

    이건 대부분 버그가 아니라 리소스 문제입니다. CPU 기반에서는 특히 그렇습니다. 프롬프트가 길거나 동시에 여러 요청이 들어오면 체감이 확 느려집니다. 저도 처음엔 설정이 잘못된 줄 알았는데, 실제로는 기대치를 조정해야 하는 영역이더라고요. 검증 목적과 운영 목적을 구분해서 보셔야 합니다.

    6-4. 재부팅 후 경로가 꼬이는 문제

    볼륨 마운트를 수동으로만 해두면 재부팅 뒤 서비스가 이상한 위치를 바라보는 경우가 있습니다. 꼭 fstab와 systemd 서비스 환경 변수를 함께 확인하세요. 이거 한 번 놓치면 ‘어제 됐는데 왜 오늘 안 되지?’ 모드 들어갑니다 ㅎㅎ

    Ollama OpenStack API 테스트와 프록시 검증 운영 이미지

    API 테스트와 프록시 구성을 검증하는 실제 운영 흐름을 보여주는 이미지입니다.

    7. 검증과 결과 확인

    구축이 끝났으면 이제 ‘떠 있다’가 아니라 ‘쓸 수 있다’를 확인해야 합니다. 저는 보통 아래 순서로 검증합니다.

    1. 서비스 상태 확인
    2. 로컬 API 호출 확인
    3. 내부망 다른 서버에서 호출 확인
    4. 리소스 사용량 확인
    5. 로그 확인
    systemctl status ollama
    curl http://127.0.0.1:11434/api/tags
    curl http://YOUR_PRIVATE_IP:11434/api/tags
    free -h
    df -h
    sudo journalctl -u ollama -n 50 --no-pager

    응답이 정상이고, 모델 목록이 보이고, 간단한 프롬프트가 처리되면 1차 검증은 통과입니다. 여기서 한 걸음 더 나가면 Prometheus(프로메테우스, 메트릭 수집기)나 Grafana(그라파나, 대시보드 도구) 같은 모니터링 체계를 붙이는 것도 좋습니다. 아직 이 글에서는 거기까지 깊게 다루진 않지만, 다음 글에서 OpenStack AI 운영 관점의 모니터링도 다뤄볼 예정입니다.

    간단한 체크리스트도 남겨보겠습니다.

    • ✅ 인스턴스 재부팅 후 서비스 자동 시작 확인
    • ✅ 모델 저장 경로가 의도한 볼륨인지 확인
    • ✅ 내부 대역 외 접근 차단 확인
    • ✅ 테스트 프롬프트 응답 정상 확인
    • ✅ 로그에 반복 오류 없는지 확인

    드디어 됐다! 싶은 순간은 사실 OpenStack 인스턴스가 뜨는 순간이 아니라, 재부팅 후에도 똑같이 잘 동작할 때입니다. 이건 진짜 운영해보면 공감하실 겁니다.

    OpenStack AI 환경에서 Ollama 결과 검증을 보여주는 대시보드 이미지

    구축 완료 후 상태 점검과 결과 검증을 시각적으로 보여주는 이미지입니다.

    8. 어떤 환경에 특히 잘 맞는가

    모든 곳에 이 구성이 정답은 아닙니다. 하지만 아래 같은 경우에는 꽤 잘 맞습니다.

    사용 상황 적합도 이유
    내부 문서 요약/검색 보조 높음 데이터 외부 반출 부담을 줄이기 좋음
    개발팀 실험용 AI 추론 환경 높음 빠르게 띄우고 지우기 쉬움
    고성능 대규모 실시간 서비스 중간 리소스 계획과 확장 설계가 더 중요함
    완전 비관리형 개인 테스트 높음 홈랩과 사내 테스트베드에 잘 맞음

    사실 저는 이 구성을 ‘최종 답안’보다는 프라이빗 LLM 운영 감각을 익히는 출발점으로 봅니다. 나중에는 컨테이너 기반으로 옮기거나, 쿠버네티스 위에 올리거나, 인증 계층을 붙이거나, 모델 라우팅을 나누는 식으로 진화할 수 있거든요.

    9. 정리하며: OpenStack AI 첫걸음으로는 꽤 괜찮았습니다

    Ollama OpenStack 조합은 화려하진 않지만, 인프라 엔지니어 입장에서 이해하기 쉽고 제어하기 편한 방식입니다. 제가 직접 해보니 핵심은 세 가지였습니다. 리소스 계획, 스토리지 분리, 그리고 접근 제어입니다. 이 셋만 제대로 잡아도 절반은 성공입니다.

    처음엔 단순히 ‘내부망에서 LLM 한 번 돌려보자’ 정도로 시작했었는데, 실제로 써보니까 운영 포인트가 꽤 명확했습니다. 특히 OpenStack을 이미 쓰고 있는 조직이라면 기존 VM 운영 경험을 그대로 가져올 수 있다는 게 큽니다. 반대로, 모델 성능 자체를 극한까지 뽑아내는 목적이라면 별도 GPU 전략과 오케스트레이션 설계가 더 필요하겠죠.

    혹시 지금 AI 추론 환경을 사내에 조용히 검증해보고 싶으셨다면, 이 방식부터 시작해보셔도 좋겠습니다. 이전 글에서 다뤘던 스토리지와 네트워크 기본기와도 연결되는 내용이고, 다음 글에서는 인증 프록시를 붙여 여러 팀이 함께 쓰는 형태까지 이어서 정리해보겠습니다. 여기서 중요한 포인트는 거창한 아키텍처보다, 작게 시작해서 반복 가능하게 만드는 것입니다. 그게 결국 오래 가더라고요. 🎉

    프라이빗 LLM 구축 단계와 운영 체크포인트 요약 이미지

    구축 절차와 운영 체크포인트를 한 장으로 정리한 요약 이미지입니다.

  • [OpenStack] OpenStack 프라이빗 클라우드 보안 강화: 최신 감사 보고서 분석 및 대응 전략

    [OpenStack] OpenStack 프라이빗 클라우드 보안 강화: 최신 감사 보고서 분석 및 대응 전략

    [인프라] OpenStack 프라이빗 클라우드 보안 강화 대응 전략

    OpenStack 프라이빗 클라우드 보안 이야기는 평소엔 좀 뒤로 밀리기 쉽습니다. 서비스가 잘 돌고 있으면 당장 체감이 안 되거든요. 그런데 클라우드 보안 감사 한 번 들어오면 분위기가 바로 달라집니다. 계정 정책, API TLS, 로그 보관, 이미지 무결성 같은 항목이 한꺼번에 쏟아지니까요. 저도 홈랩과 실무 환경에서 비슷한 점검을 여러 번 겪어봤는데, 처음엔 “이건 설정 파일 몇 개만 손보면 되겠지” 싶었거든요. 근데 막상 들어가 보니 Keystone(키스톤, 인증/인가), Nova(노바, 컴퓨트), Neutron(뉴트론, 네트워크), RabbitMQ(래빗MQ, 메시지 브로커)까지 서로 얽혀 있어서 삽질 좀 했습니다 ㅎㅎ

    이번 글은 특정 벤더 보고서 하나를 요약하는 방식보다는, 최근 감사에서 반복적으로 지적되는 OpenStack 보안 항목을 공식 Security Guide와 체크리스트 기준으로 묶어서 정리한 내용입니다. 즉, 보고서가 달라도 결국 자주 걸리는 포인트는 비슷하더라고요. 그래서 오늘은 OpenStack 프라이빗 클라우드 보안을 실제 운영 관점에서 어떻게 강화할지, 제가 실무에서 우선순위를 잡는 방식으로 풀어보겠습니다.

    컨트롤 플레인, 컴퓨트 노드, 스토리지, 관리망과 외부망을 분리한 OpenStack 보안 아키텍처 예시입니다.

    1. 왜 감사에서 늘 같은 항목이 걸릴까요?

    쉽게 말해 감사는 “설정이 있느냐”보다 보안 경계(Security Boundary, 보안 경계)가 실제로 분리되어 있느냐를 봅니다. OpenStack은 컴포넌트가 많아서, 한 군데만 HTTPS를 켰다고 끝나지 않거든요. 예를 들어 Horizon(호라이즌, 대시보드)은 TLS를 쓰는데 서비스 간 내부 통신은 평문으로 남아 있거나, RabbitMQ 인증서는 넣었는데 호스트네임 검증은 꺼져 있는 식입니다. 겉으로는 안전해 보여도 감사에서는 바로 티가 납니다.

    제가 최근 점검할 때도 지적이 많이 나온 항목은 아래 네 가지였습니다.

    • 관리망과 외부망 분리 부족: 내부 API가 외부 엔드포인트를 타는 경우
    • 과도한 권한: 관리자 계정 공유, 서비스 계정 권한 과다
    • 로그는 있는데 감사 추적이 어려움: 중앙 수집과 상관분석 부재
    • 이미지/메시지 경로 무결성 미흡: 이미지 서명 검증, 메시지 브로커 TLS 검증 미설정

    2. OpenStack 보안 베스트 프랙티스, 핵심만 먼저 잡아보겠습니다

    OpenStack 보안 베스트 프랙티스를 한 줄로 줄이면 이겁니다. “외부 공개 구간만 막지 말고, 내부 제어면(Control Plane, 제어 평면)까지 신뢰하지 말자.” 저도 처음엔 내부망이면 괜찮지 않나 싶었는데, 실제로는 운영자 실수나 계정 탈취가 더 무섭더라고요.

    감사 항목 자주 보이는 문제 즉시 대응 장기 대응
    인증/인가 관리자 계정 공유, MFA 미적용 관리자 계정 분리, 외부 IdP 연동 검토 RBAC 재설계, 페더레이션 적용
    통신 보안 내부 API 평문, 인증서 검증 비활성화 HTTPS 강제, internal endpoint 지정 전 구간 TLS, 인증서 수명주기 자동화
    감사 로그 노드별 로그 분산, 이벤트 표준화 부족 중앙 로그 수집 CADF 기반 감사 추적 체계화
    무결성 이미지 검증 없음, 설정 파일 변경 감시 없음 서명 검증, 권한 점검 FIM, 골든 이미지 파이프라인

    여기서 중요한 포인트! 감사 대응은 문서부터 쓰는 게 아니라 데이터 흐름부터 그려야 합니다. 누가 로그인하고, 어떤 API를 타고, 어떤 메시지 브로커를 지나, 최종적으로 어떤 로그가 남는지 보셔야 합니다. 이 흐름이 안 보이면 체크리스트만 돌려도 자꾸 빠지는 항목이 생깁니다.

    3. 실전 구현 1: 계정, 엔드포인트, TLS부터 정리합니다

    제가 직접 해보니 제일 효과가 큰 첫 단계는 “접속면 줄이기”였습니다. 즉, 공개 엔드포인트와 내부 엔드포인트를 분리하고, 서비스 간 통신이 public URL이 아니라 internal URL을 쓰도록 강제하는 겁니다.

    1. 서비스 카탈로그(Service Catalog, 서비스 목록)에서 internal endpoint를 분리합니다.
    2. 각 서비스 설정에서 Keystone 인증 URL과 연동 URL이 HTTPS인지 확인합니다.
    3. insecure = false 여부를 전부 확인합니다.
    openstack endpoint list --long
    openstack endpoint create identity --region RegionOne internal https://keystone.internal.example:5000/v3
    openstack endpoint create image --region RegionOne internal https://glance.internal.example:9292
    openstack endpoint create network --region RegionOne internal https://neutron.internal.example:9696
    # /etc/nova/nova.conf
    [keystone_authtoken]
    www_authenticate_uri = https://keystone.internal.example:5000
    auth_url = https://keystone.internal.example:5000
    insecure = false
    
    [glance]
    api_servers = https://glance.internal.example:9292

    이 작업은 단순해 보여도 효과가 큽니다. 내부 관리 트래픽이 외부 공개 주소를 타지 않게 되니까요. 특히 프록시나 로드밸런서가 여러 겹일 때 감사 추적도 훨씬 쉬워집니다.

    OpenStack 프라이빗 클라우드 보안 내부 API TLS 분리 구성 이미지

    public endpoint와 internal endpoint를 분리하고 서비스 간 통신을 HTTPS로 고정한 예시 구성입니다.

    4. 실전 구현 2: RabbitMQ, 로그, 이미지 무결성을 같이 보셔야 합니다

    OpenStack은 API만 안전해도 끝이 아닙니다. 실제로 서비스끼리 대화하는 길목은 RabbitMQ 같은 메시지 브로커인 경우가 많거든요. 여기 TLS를 켜도 인증서 체인만 보고 호스트네임 검증을 안 하면 허점이 남습니다. 최근 oslo.messaging 릴리스 노트에서도 이 부분이 분명히 언급됐습니다. 그래서 제가 운영할 때는 브로커 TLS와 로그 표준화를 같이 묶어서 봅니다.

    # /etc/nova/nova.conf 또는 공통 oslo.messaging 설정
    [oslo_messaging_rabbit]
    ssl = true
    ssl_ca_file = /etc/ssl/certs/openstack-ca.pem
    ssl_cert_file = /etc/ssl/certs/client.pem
    ssl_key_file = /etc/ssl/private/client-key.pem
    ssl_enforce_hostname_verification = true

    단, 이 옵션은 배포판 패키지 버전에 따라 지원 여부가 다를 수 있습니다. 그래서 바로 적용하기 전에 패키지 changelog나 릴리스 노트를 꼭 보셔야 합니다. 저도 이거 모르고 넣었다가 서비스 재시작만 반복한 적이 있었네요.

    감사 로그 쪽은 Keystone의 CADF(Cloud Auditing Data Federation, 클라우드 감사 이벤트 표준) 포맷을 적극 검토할 만합니다. 사람이 보기엔 조금 딱딱하지만, SIEM(보안 정보 이벤트 관리)으로 넘길 때 훨씬 정리가 잘 됩니다.

    # /etc/keystone/keystone.conf
    [DEFAULT]
    notification_format = cadf

    그리고 이미지 무결성도 자주 빠뜨립니다. Glance(글랜스, 이미지 서비스)와 Nova에서 서명 검증 흐름을 넣어두면, 검증되지 않은 이미지 부팅을 줄일 수 있습니다.

    # /etc/nova/nova.conf
    [glance]
    verify_glance_signatures = true

    처음엔 이게 너무 과한가 싶었는데, 골든 이미지(Golden Image, 표준 이미지)를 운영하는 환경에서는 진짜 편하더라고요. 누가 어떤 이미지를 올렸는지, 검증됐는지 흐름이 분명해집니다.

    OpenStack 프라이빗 클라우드 보안 감사 로그와 RabbitMQ TLS 흐름 이미지

    메시지 브로커 TLS 보호와 Keystone CADF 감사 로그가 중앙 수집 시스템으로 모이는 흐름입니다.

    5. 실전 구현 3: 파일 권한과 노드 하드닝은 기본인데 가장 많이 놓칩니다

    이건 너무 기본 같아서 오히려 빼먹습니다. 그런데 공식 Security Checklist를 보면 Keystone, Nova, Neutron 설정 파일의 소유권과 권한을 아주 명확하게 확인하라고 하거든요. 감사에서도 이건 빠지지 않습니다.

    stat -L -c "%U %G %a" /etc/keystone/keystone.conf
    stat -L -c "%U %G %a" /etc/nova/nova.conf
    stat -L -c "%U %G %a" /etc/neutron/neutron.conf
    find /etc/keystone /etc/nova /etc/neutron -type f -perm /027 -ls

    제가 주로 보는 기준은 이렇습니다.

    • 서비스 계정과 그룹이 올바른지 확인
    • 설정 파일 권한이 과도하게 열려 있지 않은지 확인
    • SELinux(셀리눅스, 강제 접근 통제)나 AppArmor 정책과 충돌 없는지 확인
    • FIM(File Integrity Management, 파일 무결성 감시) 대상에 핵심 설정 파일 포함

    여기서 많이 겪는 문제는 자동화 도구가 재배포하면서 권한을 널널하게 바꿔버리는 경우입니다. 특히 템플릿 한 군데 잘못 두면 전체 노드가 같은 실수를 반복합니다. 그래서 저는 배포 후 검증 명령을 CI 파이프라인이나 운영 점검 스크립트에 꼭 넣습니다.

    6. ⚠️ 감사 때 자주 터지는 트러블슈팅

    이 섹션은 실전에서 진짜 많이 부딪히는 부분입니다.

    6-1. HTTPS는 켰는데 인증 실패가 납니다

    대부분 CA 체인이나 호스트네임 불일치입니다. 인증서를 넣었다고 끝이 아니고, 서비스가 접속하는 URL과 인증서 SAN(Subject Alternative Name, 주체 대체 이름)이 맞아야 합니다.

    6-2. 내부 통신을 HTTPS로 바꾸니 서비스 등록은 됐는데 호출이 꼬입니다

    이 경우 public endpoint는 바꿨는데, 개별 서비스 설정은 여전히 외부 주소를 보고 있는 경우가 많습니다. 카탈로그와 각 서비스 설정 파일을 둘 다 봐야 합니다.

    6-3. 로그는 모이는데 감사 보고서에서 추적성이 부족하다고 나옵니다

    이건 단순 보관이 아니라 상관관계(Correlation, 상관 분석) 문제입니다. 사용자 로그인, 토큰 발급, 인스턴스 생성, 볼륨 연결, 보안그룹 변경 이벤트를 하나의 흐름으로 이어서 볼 수 있어야 하거든요. 그래서 Keystone 이벤트, API 로그, 하이퍼바이저 로그를 따로 보지 말고 묶어야 합니다.

    6-4. 보안 강화 후 성능이 걱정됩니다

    맞습니다. TLS와 추가 로깅은 비용이 있습니다. 그래서 저는 처음부터 전부 켜기보다 인터넷 노출 구간, 관리자 구간, 메시지 브로커, 이미지 검증 순서로 우선순위를 잡습니다. 한 번에 다 바꾸면 장애 원인 분석이 어려워집니다.

    7. 검증은 이렇게 하시면 됩니다

    보안 설정은 “넣었다”가 아니라 “검증됐다”로 끝내야 합니다. 제가 보통 마지막에 확인하는 체크는 아래와 같습니다.

    1. 모든 핵심 서비스 엔드포인트가 HTTPS인지 확인
    2. 서비스 설정의 insecure = true 흔적 제거 확인
    3. 메시지 브로커 TLS 연결 및 인증서 검증 확인
    4. CADF 또는 중앙 로그에서 관리자 행위 추적 가능 여부 확인
    5. 서명되지 않은 이미지가 정책상 차단되는지 확인
    openstack endpoint list --long | egrep "https|Region"
    grep -R "insecure *= *true" /etc/keystone /etc/nova /etc/neutron /etc/glance
    openssl s_client -connect rabbitmq.internal.example:5671 -servername rabbitmq.internal.example
    openstack image list
    openstack server list

    완료 후 대시보드와 CLI 둘 다 테스트해보세요. Horizon만 되고 CLI가 안 되거나, 반대로 API는 되는데 메타데이터 프록시가 깨지는 경우가 있습니다. 저도 이 단계에서 “드디어 됐다!” 했다가 보안그룹 갱신이 안 되는 걸 뒤늦게 발견한 적이 있었거든요.

    OpenStack 프라이빗 클라우드 보안 강화 결과 대시보드 이미지

    보안 점검 항목이 통과되고 중앙 로그에서 관리자 행위를 추적할 수 있는 결과 화면 예시입니다.

    8. 정리: OpenStack 프라이빗 클라우드 보안은 순서가 중요합니다

    OpenStack 프라이빗 클라우드 보안은 기능을 많이 넣는 게임이 아닙니다. 순서를 잘 잡는 작업에 가깝습니다. 제가 실제로 운영하면서 느낀 우선순위는 이렇습니다. 계정 통제 → 내부 API TLS → 메시지 브로커 보호 → 감사 로그 표준화 → 이미지 무결성 → 파일 무결성 감시. 이 순서로 가면 감사 대응도 수월하고, 장애가 나도 어디서 꼬였는지 찾기 편합니다.

    혹시 지금 프라이빗 클라우드 감사 대응을 준비 중이시라면, 문서부터 만들기보다 먼저 엔드포인트와 계정, 로그 흐름을 그림으로 그려보세요. 그 다음에 체크리스트를 맞추면 훨씬 빨라집니다. 다음 글에서는 Barbican(바비칸, 비밀 관리 서비스)과 이미지 서명 체계를 조금 더 깊게 다뤄보겠습니다. 이전에 정리한 리눅스 하드닝 글이 있으시면 그 흐름과 같이 보셔도 연결이 잘 됩니다.

    OpenStack 프라이빗 클라우드 보안 강화 우선순위 요약 이미지

    계정 통제, TLS, 로그, 이미지 무결성, 파일 무결성 감시 순서로 정리한 대응 우선순위 요약입니다.

    9. 자주 묻는 질문

    Q1. 작은 홈랩에도 이렇게까지 해야 할까요?

    전부 한 번에 할 필요는 없습니다. 다만 관리자 계정 분리, HTTPS, 설정 파일 권한 점검은 작은 환경에서도 바로 체감됩니다.

    Q2. 클라우드 보안 감사에서 가장 빨리 점수 올리는 항목은 뭔가요?

    보통은 내부 API TLS, 관리자 접근 통제, 중앙 로그 수집입니다. 이 세 개가 눈에 잘 보이고 재현도 쉽습니다.

    Q3. OpenStack 보안 베스트 프랙티스를 어디서 시작하면 좋을까요?

    공식 Security Checklist를 서비스별로 돌려보는 게 제일 현실적입니다. Keystone, Nova, Neutron부터 보시면 됩니다.

  • [OpenStack] 테넌트 쿼터로 클라우드 비용 효율화하기

    [OpenStack] 테넌트 쿼터로 클라우드 비용 효율화하기

    [OpenStack] 테넌트 쿼터로 클라우드 비용 효율화하기

    OpenStack 쿼터 관리, 이거 운영 조금만 해보신 분들은 왜 중요한지 바로 체감하실 겁니다. 프로젝트 테넌트(Project Tenant, 프로젝트 단위 자원 사용 영역)를 여러 팀에 열어두면 초반엔 다들 조심해서 쓰는 것 같거든요. 근데 어느 순간부터 vCPU, RAM, Volume(볼륨, 블록 스토리지), Floating IP(플로팅 아이피, 외부 연결용 공인 IP) 같은 자원이 한쪽으로 몰리기 시작합니다. 저도 홈랩이랑 사내 비슷한 테스트 환경을 굴리면서 처음엔 “일단 넉넉하게 주자” 쪽이었는데요. 결과는 뻔했습니다. 누군가는 필요 이상으로 잡아두고, 누군가는 정말 필요한 순간에 못 쓰더라고요. 결국 OpenStack 비용 최적화는 자원을 덜 쓰는 문제가 아니라, 필요한 팀이 필요한 만큼만 쓰게 만드는 운영 규칙에서 시작됩니다.

    특히 비용 관점에서 보면 더 명확합니다. 퍼블릭 클라우드처럼 바로 청구서가 날아오지 않더라도, 내부 클라우드도 결국은 서버, 스토리지, 네트워크 장비, 전력, 운영 시간까지 전부 비용이거든요. 그래서 이번 글에서는 제가 실제로 자주 쓰는 방식대로 OpenStack 쿼터 관리의 개념, 프로젝트 테넌트별 설계 기준, 그리고 운영 중 삽질했던 포인트까지 한 번에 정리해보겠습니다.

    프로젝트 테넌트마다 컴퓨트, 스토리지, 네트워크 자원이 어떻게 제한되고 분배되는지 보여주는 개요 이미지입니다.

    OpenStack 쿼터 관리가 왜 비용 효율성과 연결될까요?

    쉽게 말해 쿼터(Quota, 사용 한도)는 “이 프로젝트가 얼마나 많이 가져갈 수 있는가”를 정하는 안전장치입니다. 이걸 안 걸어두면 성실한 팀이 손해를 보고, 빨리 점유한 팀이 이득을 보게 되는 거죠. 운영 입장에서는 제일 피곤한 구조더라고요.

    제가 처음 쿼터 정책을 손댔을 때 제일 헷갈렸던 부분이 이거였습니다. “어차피 남는 자원인데 굳이 제한해야 하나?” 근데 실제로 써보니까, 남는 자원과 점유된 자원은 완전히 다른 이야기더라고요. 인스턴스(Instance, 가상머신) 하나가 꺼져 있어도 디스크는 잡고 있고, IP는 할당돼 있고, 볼륨 스냅샷까지 누적되면 체감보다 훨씬 빨리 자원이 막혀버립니다.

    • 과도한 선점 방지: 한 프로젝트가 전체 클러스터 자원을 독식하는 상황을 막습니다.
    • 예산 예측 가능성 확보: 프로젝트별 사용 상한을 정해두면 증설 시점이 보입니다.
    • 운영 정책 표준화: 요청이 들어올 때마다 감으로 승인하지 않아도 됩니다.
    • OpenStack 비용 최적화: 남는 자원을 없애는 게 아니라, 불필요하게 묶인 자원을 줄입니다.

    프로젝트 테넌트 기준으로 봐야 하는 핵심 자원

    OpenStack에서 쿼터를 잡을 때 보통 Compute(컴퓨트), Block Storage(블록 스토리지), Network(네트워크) 세 축으로 나눠서 봅니다. 여기서 중요한 건 팀이 실제로 병목을 느끼는 자원을 먼저 보는 겁니다.

    영역 대표 쿼터 항목 운영에서 자주 문제 되는 부분
    Compute instances, cores, ram 테스트 VM 대량 생성, 과도한 vCPU 점유
    Block Storage volumes, snapshots, gigabytes 안 쓰는 볼륨 누적, 스냅샷 방치
    Network floating-ips, ports, routers 공인 IP 고갈, 포트 수 초과

    여기서 중요한 포인트! 모든 프로젝트에 동일한 숫자를 주는 건 공평해 보이지만, 실제로는 비효율적인 경우가 많습니다. 예를 들어 개발팀은 인스턴스 수는 많이 필요하지만 볼륨 용량은 적을 수 있고요. 데이터 처리 팀은 반대로 대용량 스토리지가 더 중요할 수 있거든요. 그래서 프로젝트 테넌트 성격별 기본 등급을 나눠두는 방식이 운영이 훨씬 편합니다.

    제가 추천하는 기본 등급 방식

    1. 샌드박스용 프로젝트: 작은 인스턴스 수와 낮은 RAM 한도
    2. 개발/검증용 프로젝트: 중간 수준의 vCPU, RAM, 볼륨 허용
    3. 운영/서비스용 프로젝트: 승인 기반으로 높은 한도 부여

    이렇게 해두면 신규 프로젝트 생성 때마다 처음부터 숫자 싸움을 안 해도 되거든요. 진짜 편하더라고요.

    OpenStack 쿼터 관리 설계 전략: 숫자보다 기준이 먼저입니다

    쿼터 값 자체보다 더 중요한 건 “왜 이 숫자인가”입니다. 저도 처음엔 그냥 현재 남는 자원을 보고 나눴었는데요. 그 방식은 시간이 지나면 꼭 꼬입니다. 지금 비어 있다고 앞으로도 비는 게 아니거든요.

    그래서 기준을 아래처럼 잡아두면 좋습니다.

    • 현재 총 자원이 아니라 안전 여유분을 제외한 가용 자원을 기준으로 잡습니다.
    • 프로젝트 중요도와 업무 특성을 반영합니다.
    • 일시적 피크와 상시 사용량을 구분합니다.
    • 분기별 재평가 일정을 미리 운영 정책에 넣습니다.

    예를 들어 vCPU 200개가 있다고 해서 프로젝트들에 합산 200개를 딱 맞춰 배정하면 안 됩니다. 장애 복구, 호스트 점검, 임시 증설 같은 변수 때문에 버퍼가 필요하거든요. 실제로 호스트 하나 유지보수 들어가면 체감 여유분이 확 줄어들더라고요. 저는 이런 부분 때문에 쿼터를 자원 총량 관리가 아니라, 리스크 관리로 보는 편입니다.

    실전 구현: OpenStack CLI로 프로젝트 테넌트 쿼터 설정하기

    이제 실제로 설정하는 흐름을 보겠습니다. 예시는 OpenStack CLI 기준으로 적겠습니다. 환경마다 서비스 구성 차이는 있지만, 기본 흐름은 비슷합니다.

    1. 현재 프로젝트 목록과 상태 확인

    openstack project list
    openstack project show myproject

    먼저 어떤 프로젝트 테넌트에 정책을 적용할지 확인합니다. 이름이 비슷한 프로젝트가 많으면 ID 기준으로 작업하는 게 안전하거든요. 저도 이름만 보고 했다가 다른 프로젝트를 건드린 적이 있었는데, 그때 식은땀 좀 났습니다 ㅎㅎ

    2. 현재 쿼터 확인

    openstack quota show myproject
    openstack volume quota show myproject
    openstack network quota show myproject

    배포판이나 서비스 버전에 따라 출력 항목이 조금 다를 수 있습니다. 핵심은 Compute, Volume, Network를 분리해서 확인하는 습관을 들이는 거죠.

    OpenStack 쿼터 관리 CLI 작업 화면을 표현한 이미지

    운영자가 CLI에서 프로젝트별 쿼터를 조회하고 조정하는 실제 작업 흐름을 보여주는 이미지입니다.

    3. Compute 쿼터 설정

    openstack quota set \
      --instances 20 \
      --cores 40 \
      --ram 81920 \
      myproject

    여기서 RAM은 보통 MB 단위로 다루는데, 꼭 환경 문서를 먼저 확인하셔야 합니다. 숫자 단위를 헷갈리면 의도보다 훨씬 크게 열어줄 수 있거든요.

    4. Block Storage 쿼터 설정

    openstack quota set \
      --volumes 20 \
      --snapshots 20 \
      --gigabytes 2048 \
      myproject

    스토리지 쪽은 특히 방치 비용이 큽니다. 인스턴스는 지워도 볼륨과 스냅샷이 남아 있는 경우가 정말 많거든요. OpenStack 비용 최적화 관점에서는 이 영역이 생각보다 효과가 크더라고요.

    5. Network 쿼터 설정

    openstack quota set \
      --floating-ips 5 \
      --ports 50 \
      --routers 2 \
      myproject

    공인 IP가 적은 환경에서는 Floating IP 제한만 잘 잡아도 운영이 훨씬 안정됩니다.

    6. 프로젝트별 기준을 문서화하기

    명령어만 실행하고 끝내면 나중에 왜 그렇게 했는지 아무도 모릅니다. 저는 최소한 아래 형태로 남겨두는 걸 추천하거든요.

    project_quota_policy:
      project_name: myproject
      profile: development
      compute:
        instances: 20
        cores: 40
        ram_mb: 81920
      storage:
        volumes: 20
        snapshots: 20
        gigabytes: 2048
      network:
        floating_ips: 5
        ports: 50
        routers: 2
      reason: "개발 검증 환경 기본 등급"
      review_cycle: "quarterly"

    운영은 결국 사람이 이어받는 일이 많으니까요. 문서화된 기준이 있어야 분쟁도 줄고, 승인 속도도 빨라집니다.

    자동화까지 가면 더 편합니다: 점검 스크립트 예시

    쿼터 설정은 한 번 해두는 걸로 끝나지 않습니다. 실제 사용량과 비교해야 의미가 있거든요. 저는 예전에 프로젝트는 많은데 사람이 일일이 확인하다 보니 누수 자원을 놓치는 경우가 많았습니다. 그래서 간단한 점검 스크립트라도 돌려보는 걸 추천합니다.

    import json
    import subprocess
    
    PROJECT = "myproject"
    
    result = subprocess.run(
        ["openstack", "quota", "show", PROJECT, "-f", "json"],
        capture_output=True,
        text=True,
        check=True,
    )
    quota = json.loads(result.stdout)
    
    for key in ["instances", "cores", "ram"]:
        value = quota.get(key)
        print(f"{key}: {value}")

    물론 실제 운영에선 사용량 조회와 비교 로직까지 붙여야 합니다. 다만 시작은 단순한 게 좋거든요. 처음부터 거대한 자동화 만들려다가 손 놓는 경우가 더 많더라고요.

    OpenStack 쿼터 관리 결과를 보여주는 프로젝트 테넌트 대시보드 이미지

    각 프로젝트의 사용량 대비 쿼터 한도를 한눈에 비교해 병목과 과다 할당을 찾는 대시보드 이미지입니다.

    ⚠️ 실제로 많이 겪는 문제와 트러블슈팅

    이 섹션은 제가 삽질 좀 했던 부분입니다. 문서만 보면 쉬워 보이는데, 운영에서는 꼭 이런 일이 생깁니다.

    1. 쿼터는 남았는데 인스턴스 생성이 실패하는 경우

    이건 쿼터 문제가 아니라 실제 물리 자원 부족이거나 스케줄링(Scheduling, 배치 결정) 이슈일 수 있거든요. 예를 들어 특정 AZ(Availability Zone, 가용 영역)나 호스트 집합에 여유가 없으면 쿼터가 남아도 실패합니다.

    • 프로젝트 쿼터와 실제 클러스터 가용량을 분리해서 봅니다.
    • 특정 호스트 집합에 몰리는 Flavor(플레이버, VM 사양 템플릿) 사용 패턴을 확인합니다.

    2. 볼륨은 삭제했는데 용량이 안 돌아오는 경우

    스냅샷, 백업, 또는 분리된 리소스가 남아 있을 수 있습니다. 저는 처음에 인스턴스만 없애면 끝인 줄 알았는데, 실제로 써보니까 스토리지가 조용히 계속 점유되고 있더라고요.

    • 미연결 볼륨과 오래된 스냅샷을 주기적으로 점검합니다.
    • 프로젝트 종료 절차에 스토리지 정리 단계를 넣습니다.

    3. 프로젝트 생성마다 쿼터 요청이 제각각 들어오는 경우

    이건 기술 문제가 아니라 정책 부재죠. 기준 등급이 없으면 모든 요청이 예외처럼 보입니다. 그래서 아예 기본 프로필을 나눠두고, 초과 요청은 사유 기반 승인으로 바꾸는 게 운영이 훨씬 편합니다.

    상황 권장 대응
    개발팀 신규 프로젝트 기본 개발 등급 자동 적용
    일시적 부하 테스트 기간 제한 임시 증액 후 자동 회수
    운영 서비스 확장 근거 확인 후 상향 조정 및 재검토 일정 등록

    검증: 쿼터 정책이 제대로 먹혔는지 확인하는 방법

    설정한 뒤에는 반드시 검증이 필요합니다. 여기서 대충 넘어가면 나중에 “분명 설정했는데 왜 안 되죠?” 상황이 옵니다.

    1. 프로젝트별 쿼터를 다시 조회해 의도한 값이 반영됐는지 확인합니다.
    2. 테스트 인스턴스 생성으로 제한 동작을 확인합니다.
    3. 볼륨, 스냅샷, Floating IP도 같은 방식으로 검증합니다.
    4. 운영 문서와 실제 값이 일치하는지 대조합니다.
    openstack quota show myproject
    openstack volume quota show myproject
    ostack network quota show myproject

    가능하면 소규모 프로젝트 하나를 골라서 먼저 적용해보세요. 한 번에 전 프로젝트에 밀어 넣는 방식은 위험합니다. 저도 처음엔 빨리 끝내고 싶어서 한꺼번에 바꾸려다가, 예외 케이스 때문에 되돌아보는 시간이 더 길었거든요.

    검증이 끝나면 보통 아래 같은 변화가 보입니다.

    • 공유 자원 고갈 빈도가 줄어듭니다.
    • 불필요한 증설 요청이 감소합니다.
    • 프로젝트별 책임 범위가 명확해집니다.
    • 클러스터 전체 자원 사용률이 더 예측 가능해지더라고요. 🎉
    OpenStack 비용 최적화와 쿼터 적용 전후 비교 인포그래픽

    쿼터 정책 적용 전과 후의 자원 점유율, 낭비 감소, 운영 효율 향상을 비교하는 요약 이미지입니다.

    비용 관점에서 꼭 같이 보면 좋은 운영 지표

    OpenStack 쿼터 관리만으로 모든 비용 문제가 해결되지는 않습니다. 하지만 아래 지표를 같이 보면 OpenStack 비용 최적화 효과가 훨씬 명확하게 드러납니다.

    • 프로젝트별 평균 인스턴스 가동률
    • 미연결 볼륨 수와 총 용량
    • 스냅샷 누적량
    • Floating IP 미사용 비율
    • 임시 증액 요청 빈도

    이런 지표를 한 달만 모아도 “어디가 진짜 병목인지”가 보입니다. 감으로 운영할 때랑은 차이가 정말 크거든요. 혹시 지금 프로젝트 테넌트 쿼터를 이미 쓰고 계신데도 자원 부족이 계속 반복되시나요? 그럼 숫자를 더 주는 것보다, 사용 패턴과 회수 정책부터 점검해보시는 게 맞습니다.

    정리: OpenStack 쿼터 관리는 제한이 아니라 운영 최적화입니다

    오늘 이야기의 핵심은 단순합니다. OpenStack 쿼터 관리는 사용자를 불편하게 하려는 장치가 아니라, 클라우드 자원 관리의 기준선을 만드는 작업이라는 점입니다. 제가 직접 해보니 쿼터를 잘 잡아두면 장애가 줄고, 승인 절차가 빨라지고, 무엇보다 비용 이야기할 때 근거가 생기거든요. 이게 진짜 큽니다.

    특히 프로젝트 테넌트가 늘어나는 환경이라면, 초기에 조금 귀찮아도 기본 등급과 재검토 주기를 만들어두세요. 나중에 훨씬 편합니다. 드디어 됐다 싶었던 순간이 바로, 운영팀과 사용자팀이 같은 숫자를 보고 이야기하기 시작했을 때였거든요.

    다음 글에서는 프로젝트 테넌트 사용량을 주기적으로 수집해서 보고서 형태로 만드는 방법도 다뤄볼 예정입니다. 이전 글에서 다뤘던 인스턴스 라이프사이클 정리 정책과 같이 보시면 더 흐름이 잘 잡히실 겁니다. ✅

    자주 묻는 질문

    Q. 모든 프로젝트에 같은 쿼터를 주면 안 되나요?

    가능하지만 비효율적인 경우가 많습니다. 업무 특성이 다르기 때문에 같은 숫자가 오히려 낭비를 만들 수 있거든요.

    Q. 쿼터를 낮게 잡으면 사용자 불만이 커지지 않나요?

    기준 없이 낮추면 그렇습니다. 대신 기본 등급, 임시 증액 절차, 재검토 일정을 같이 운영하면 마찰을 많이 줄 수 있습니다.

    Q. OpenStack 비용 최적화에서 가장 먼저 볼 항목은 뭔가요?

    제 경험상 미연결 볼륨, 오래된 스냅샷, 과도한 Floating IP 점유부터 보는 게 체감 효과가 빠릅니다.

  • [OpenStack] OpenStack 업그레이드 10가지 체크리스트: 실전 베스트 프랙티스로 성공 확률 높이기

    [OpenStack] OpenStack 업그레이드 10가지 체크리스트: 실전 베스트 프랙티스로 성공 확률 높이기

    OpenStack 업그레이드 10가지 체크리스트: 실전 베스트 프랙티스로 성공 확률 높이기

    OpenStack 업그레이드는 생각보다 자주, 그리고 생각보다 크게 운영팀을 흔듭니다. 평소엔 잘 돌던 Nova(노바, 컴퓨트 서비스), Neutron(뉴트론, 네트워크 서비스), Cinder(신더, 블록 스토리지 서비스)가 업그레이드 직후 서로 미묘하게 어긋나기 시작하면 진짜 진땀 나거든요. 저도 처음엔 “패키지 버전만 맞추면 되겠지” 했다가 메시지 큐(Message Queue, 서비스 간 비동기 통신), DB schema(데이터베이스 스키마), API microversion(API 세부 버전 정책) 때문에 삽질 좀 했습니다 ㅎㅎ 이번 글은 그런 시행착오를 줄이기 위한 OpenStack 업그레이드 체크리스트를 정리한 내용입니다.

    특히 운영 중인 프라이빗 클라우드(private cloud)를 관리하시는 분들이라면, 단순히 패키지를 올리는 작업이 아니라 클라우드 업그레이드 전체 흐름으로 봐야 합니다. 오늘은 제가 홈랩과 실서비스 환경에서 반복해서 확인했던 항목들을 기준으로, 실패 확률을 줄이는 순서와 OpenStack 베스트 프랙티스를 풀어보겠습니다.

    컨트롤 플레인과 컴퓨트 노드, 스토리지, 네트워크 컴포넌트가 단계적으로 업그레이드되는 전체 흐름을 보여주는 이미지입니다.

    왜 OpenStack 업그레이드가 까다로운가

    쉽게 말해 OpenStack은 하나의 프로그램이 아니라 여러 서비스 묶음입니다. Keystone(키스톤, 인증 서비스), Glance(글랜스, 이미지 서비스), Nova, Neutron, Cinder 같은 핵심 서비스가 각각 DB, API, 에이전트, 백엔드 드라이버를 갖고 있고요. 그래서 한 군데만 올리면 끝나는 구조가 아닙니다.

    여기서 중요한 포인트! 업그레이드의 핵심은 버전 상승 자체가 아니라 호환성 유지입니다. 실제로 써보니까 장애는 대개 패키지 설치보다 서비스 간 정합성이 깨질 때 발생하더라고요. 예를 들어 API는 올라갔는데 agent(에이전트, 각 노드에서 동작하는 구성요소)가 예전 상태면 네트워크 포트 생성이 꼬이거나, DB migration(데이터베이스 마이그레이션)이 덜 끝난 상태에서 서비스가 붙으면서 애매한 오류를 만들기도 합니다.

    OpenStack 업그레이드 전 꼭 봐야 할 10가지 체크리스트

    1. 공식 릴리스 노트와 업그레이드 경로 확인
      지원되는 업그레이드 경로인지 먼저 확인해야 합니다. 중간 릴리스를 건너뛰면 안 되는 경우가 있거든요.
    2. 현재 인벤토리와 의존성 파악
      컨트롤러, 컴퓨트, 네트워크 노드, 스토리지 백엔드, 하이퍼바이저, OS 패키지 상태를 정리합니다.
    3. 백업과 복구 시나리오 검증
      DB dump만 뜨고 끝내면 부족합니다. 실제 복원 테스트까지 해봐야 합니다.
    4. 테스트 환경 또는 스테이징 검증
      프로덕션과 최대한 비슷한 구조에서 한 번 굴려봐야 예상치 못한 이슈를 줄일 수 있습니다.
    5. API, DB, Message Queue 호환성 점검
      RabbitMQ 같은 메시지 큐와 MariaDB/MySQL, PostgreSQL 설정 차이도 같이 봐야 합니다.
    6. 드레인(Drain)과 유지보수 창 확보
      라이브 마이그레이션 가능 여부, 예약 작업, 사용자 공지까지 포함해서 계획을 세워야 합니다.
    7. 롤링 업그레이드 가능 범위 확인
      서비스별로 순차 적용 가능한지, 전체 중단이 필요한지 구분해야 합니다.
    8. 설정 파일 diff 비교
      기존 설정과 새 기본값이 어떻게 달라졌는지 비교해야 합니다.
    9. 모니터링과 로그 수집 체계 준비
      업그레이드 직후엔 로그가 거의 유일한 힌트일 때가 많습니다.
    10. 검증 시나리오 문서화
      인스턴스 생성, 삭제, 볼륨 연결, 플로팅 IP, 보안 그룹, 이미지 업로드 같은 기본 기능을 체크리스트로 만들어야 합니다.

    업그레이드 방식 비교: 인플레이스 vs 블루그린 관점

    현실적으로는 대부분 인플레이스(in-place, 기존 환경에서 직접 업그레이드)를 선택합니다. 비용과 장비 여유 때문이죠. 저도 홈랩에서는 거의 인플레이스로 갔었는데, 대신 검증 시나리오를 더 빡세게 잡았습니다. 반대로 규모가 크고 서비스 중단 허용 범위가 작다면 블루그린(blue-green, 신규 환경을 따로 구성 후 전환) 접근이 더 안전할 수 있습니다.

    방식 장점 주의점
    인플레이스 업그레이드 추가 자원 부담이 적고 기존 운영 체계를 유지하기 쉽습니다 롤백이 까다롭고 서비스 간 버전 혼합 구간 관리가 중요합니다
    블루그린 전환 검증 후 전환이 가능해 리스크를 줄이기 좋습니다 추가 인프라와 데이터 동기화 전략이 필요합니다
    하이브리드 단계 전환 핵심 서비스만 분리해 현실적으로 적용하기 좋습니다 운영 절차가 복잡해지고 문서화가 필수입니다

    실전 구현: OpenStack 업그레이드 작업 순서

    여기서는 배포 도구에 종속되지 않는 공통 흐름으로 설명하겠습니다. Ansible(앤서블, 자동화 도구), Kolla-Ansible, OpenStack-Ansible, 수동 패키지 기반 환경 모두 참고 가능한 순서입니다.

    1. 현재 상태 수집

    처음엔 이게 뭔가 싶었는데, 이 단계가 제일 중요합니다. 업그레이드 전 상태를 남겨놓지 않으면 장애가 나도 비교 기준이 없거든요.

    openstack compute service list
    openstack network agent list
    openstack volume service list
    openstack hypervisor list
    openstack server list --all-projects
    openstack volume list --all-projects
    

    이 명령으로 서비스 상태를 저장해두면 업그레이드 후 비교가 훨씬 쉬워집니다. 가능하면 결과를 파일로 보관하세요.

    2. 데이터베이스와 설정 백업

    mysqldump --single-transaction --routines --databases keystone glance nova nova_api neutron cinder > openstack-backup.sql
    cp -a /etc/keystone /root/backup/etc-keystone
    cp -a /etc/nova /root/backup/etc-nova
    cp -a /etc/neutron /root/backup/etc-neutron
    cp -a /etc/cinder /root/backup/etc-cinder
    

    제가 직접 해보니 DB dump만 믿고 갔다가 설정 파일 옵션 차이 때문에 더 오래 헤맨 적이 있습니다. 그래서 DB + 설정 파일 + 서비스 목록을 같이 백업하는 습관이 중요합니다.

    3. 유지보수 창 공지와 워크로드 정리

    운영 환경이라면 프로젝트 사용자에게 공지하고, 가능하면 대규모 배포 작업이나 자동 스케일링 작업은 멈춰두는 게 좋습니다. 라이브 마이그레이션이 가능한 구조라면 컴퓨트 노드 분산도 미리 해두세요.

    OpenStack 업그레이드 체크리스트와 운영 절차를 보여주는 이미지

    사전 점검, 백업, 서비스 중지, DB 마이그레이션, 단계별 기동 검증까지 이어지는 작업 순서를 시각화한 이미지입니다.

    4. 컨트롤 플레인부터 순차 업그레이드

    일반적으로는 인증, 이미지, API, 스케줄러, 컨덕터 같은 컨트롤 플레인(control plane, 중앙 제어 계층)을 먼저 올리고 이후 컴퓨트와 에이전트를 따라갑니다. 근데 여기서 중요한 건 무조건 한 번에 다 올리는 게 아니라 서비스별 검증 후 다음 단계로 이동하는 겁니다.

    systemctl stop openstack-nova-api
    systemctl stop openstack-nova-scheduler
    systemctl stop openstack-nova-conductor
    
    # 패키지 업데이트 또는 배포 도구 실행
    # 예: dnf update, apt upgrade, ansible-playbook 실행 등
    
    nova-manage api_db sync
    nova-manage db sync
    systemctl start openstack-nova-api
    systemctl start openstack-nova-scheduler
    systemctl start openstack-nova-conductor
    

    서비스 이름은 배포판마다 조금 다를 수 있습니다. 그래서 실환경에 맞는 서비스 유닛 이름을 먼저 확인해야 합니다.

    5. Neutron과 Cinder는 연결 관계를 같이 본다

    네트워크와 스토리지는 겉보기보다 외부 의존성이 많습니다. Neutron은 L2/L3 agent, ML2 plugin, DHCP, Metadata 구성이 엮여 있고요. Cinder는 백엔드 스토리지 드라이버와의 호환성이 중요합니다. 저도 예전에 API는 멀쩡한데 agent 상태가 down으로 찍혀서 한참 로그를 봤던 적이 있네요.

    openstack network agent list
    openstack volume service list
    journalctl -u neutron-server -n 100
    journalctl -u openstack-cinder-volume -n 100
    

    6. 컴퓨트 노드는 소수부터 검증

    모든 컴퓨트 노드를 한 번에 건드리지 말고, 먼저 일부 노드만 올려서 인스턴스 생성과 마이그레이션을 확인하는 게 좋습니다. 이건 정말 실전에서 체감이 큽니다. 작은 범위에서 틀어지면 복구가 빠르거든요.

    설정 파일에서 자주 놓치는 포인트

    • deprecated option: 더 이상 권장되지 않는 옵션이 남아 있으면 경고만 보이다가 실제 동작에 영향을 줄 수 있습니다.
    • endpoint URL: 내부 엔드포인트와 퍼블릭 엔드포인트 주소 체계가 섞이면 인증이나 이미지 호출이 실패할 수 있습니다.
    • policy: 정책 파일 구조가 바뀌는 경우가 있어 권한 문제가 생기기도 합니다.
    • backend driver 설정: Cinder, Neutron 플러그인 쪽은 예전 옵션명이 유지되지 않는 경우가 있습니다.

    설정 비교는 단순히 파일 존재 여부가 아니라 기본값 변화를 보는 작업입니다. 여기서 중요한 포인트! 새 버전 기본 설정 샘플과 현재 운영 설정을 diff로 비교해보세요.

    diff -u /root/backup/etc-nova/nova.conf /etc/nova/nova.conf
    diff -u /root/backup/etc-neutron/neutron.conf /etc/neutron/neutron.conf
    

    ⚠️ 실제 많이 겪는 문제와 트러블슈팅

    DB migration은 끝났는데 서비스가 안 붙는 경우

    이건 생각보다 흔합니다. 서비스 계정 권한, 커넥션 문자열, 캐시, 메시지 큐 인증 정보가 미묘하게 어긋난 경우가 많더라고요. 로그에서 connection refused, access denied, transport error 같은 키워드를 먼저 찾으세요.

    네트워크 에이전트가 살아 있는데 포트 생성이 실패하는 경우

    Neutron server와 agent 버전 조합, ML2 설정, OVS(Open vSwitch, 가상 스위치) 또는 Linux bridge 구성이 어긋난 경우가 많습니다. 이럴 땐 API 응답만 보지 말고 agent heartbeat(에이전트 하트비트)와 브리지 상태를 같이 봐야 합니다.

    openstack network agent list
    ovs-vsctl show
    ip link show
    

    인스턴스는 생성되는데 콘솔 접속이 안 되는 경우

    novncproxy, metadata, 보안 그룹, 프록시 설정이 엮여 있는 경우가 많습니다. 처음엔 컴퓨트 문제라고 생각하기 쉬운데, 실제로는 프론트 API나 프록시 계층 이슈인 경우도 있었습니다.

    롤백이 필요한데 되돌릴 순서가 없는 경우

    사실 제일 무서운 상황입니다. 그래서 업그레이드 시작 전에 “어디까지 실패하면 중단할지” 기준을 잡아야 합니다. 저는 보통 컨트롤 플레인 검증 실패, 인스턴스 신규 생성 실패, 기존 VM 네트워크 연결 실패 이 세 가지를 즉시 중단 기준으로 둡니다.

    검증: 업그레이드 후 무엇을 확인해야 하나

    업그레이드가 끝났다고 바로 종료하면 안 됩니다. OpenStack 유지보수 관점에서는 사후 검증이 절반입니다. 아래 항목은 꼭 순서대로 확인해보세요.

    1. 인증 토큰 발급과 대시보드 로그인 확인
    2. 이미지 목록 조회와 신규 이미지 업로드 확인
    3. 네트워크 생성, 서브넷 생성, 라우터 연결 확인
    4. 테스트 인스턴스 생성과 삭제 확인
    5. 플로팅 IP 연결 및 외부 통신 확인
    6. 볼륨 생성, 연결, 분리 확인
    7. 보안 그룹 규칙 반영 확인
    8. 라이브 또는 콜드 마이그레이션 시나리오 확인
    9. 모니터링 알림과 로그 수집 확인
    10. 에러 로그 증가 여부 추적
    OpenStack 업그레이드 후 상태 검증 대시보드 이미지

    서비스 상태가 모두 정상이며 컴퓨트, 네트워크, 스토리지 검증 항목이 체크 완료된 운영 대시보드 이미지입니다.

    openstack token issue
    openstack image list
    openstack network list
    openstack server create --flavor m1.small --image test-image --network private test-vm
    openstack server list
    openstack volume create --size 1 test-volume
    openstack volume list
    

    이 검증 절차를 문서화해두면 다음 업그레이드 때 시간이 정말 많이 줄어듭니다. 실제로 써보니까 사람 기억보다 체크리스트가 훨씬 믿을 만하더라고요.

    제가 정리해보는 OpenStack 베스트 프랙티스

    • 작게 시작해서 넓힌다: 일부 노드, 일부 서비스부터 검증합니다.
    • 업그레이드 전 상태를 숫자와 결과로 남긴다: 서비스 목록, 워크로드 수, 에이전트 상태를 저장합니다.
    • 백업은 복원 테스트까지 포함한다: 백업 파일 존재만으로 안심하면 안 됩니다.
    • 문서화한다: 명령어, 순서, 실패 지점, 복구 시간을 기록합니다.
    • 배포 도구의 자동화를 맹신하지 않는다: 자동화는 빠르지만, 원인 분석은 사람이 해야 하거든요.

    혹시 이런 경험 있으신가요? 업그레이드는 끝났는데 사용자 쪽에서 “왜 VM 생성이 예전보다 느려졌죠?”라는 질문이 나오는 경우요. 이런 건 단순 성공/실패가 아니라 성능과 안정성까지 같이 봐야 한다는 뜻입니다. 그래서 클라우드 업그레이드는 배포 이벤트가 아니라 운영 이벤트로 봐야 합니다.

    정리: 체크리스트 기반으로 움직이면 성공 확률이 올라갑니다

    OpenStack 업그레이드는 한 번의 명령으로 끝나는 작업이 아닙니다. 서비스 의존성, DB migration, 에이전트 상태, 검증 시나리오가 다 맞물려 있습니다. 저도 처음엔 버전만 맞추면 되겠지 싶었는데, 실제로는 사전 점검과 사후 검증이 훨씬 중요했습니다. 드디어 됐다! 싶은 순간은 마지막 패키지 설치가 아니라, 테스트 VM이 정상적으로 뜨고 네트워크와 볼륨이 다 붙는 걸 확인했을 때 오더라고요.

    이번 글에서는 운영 기준으로 바로 써먹을 수 있는 체크리스트 중심으로 정리해봤습니다. 다음 글에서는 Kolla-Ansible 기반 환경에서 업그레이드 점검 포인트를 더 구체적으로 다뤄볼 예정입니다. 이전 글에서 백업 전략을 정리해두셨다면 이번 체크리스트와 같이 묶어서 보시면 흐름이 훨씬 잘 잡히실 겁니다.

    OpenStack 업그레이드 전후 비교 인포그래픽 이미지

    업그레이드 전 점검 항목과 업그레이드 후 검증 항목을 한눈에 비교할 수 있는 요약 인포그래픽입니다.

    자주 묻는 질문

    Q. OpenStack 업그레이드는 무중단으로 가능한가요?

    일부 구성에서는 롤링 업그레이드가 가능하지만, 실제 운영에서는 서비스 영향도를 0으로 만들기 쉽지 않습니다. 특히 네트워크와 스토리지 쪽은 사전 검증이 더 중요합니다.

    Q. 테스트 환경이 작아도 도움이 되나요?

    네, 도움이 됩니다. 완벽히 같지 않아도 서비스 기동 순서, DB migration, 기본 API 검증만 해봐도 큰 차이가 납니다.

    Q. 가장 먼저 자동화해야 할 부분은 뭔가요?

    상태 수집, 백업, 검증 명령 실행 결과 저장입니다. 이 세 가지가 자동화되면 반복 작업이 훨씬 안정적이 됩니다.

  • [OpenStack] OpenStack VXLAN 오버레이 네트워크 성능 벤치마크 가이드

    [OpenStack] OpenStack VXLAN 오버레이 네트워크 성능 벤치마크 가이드

    OpenStack VXLAN 오버레이 네트워크 성능 벤치마크 가이드

    OpenStack VXLAN 환경에서 성능이 얼마나 나오는지 궁금하신 분들 많으실 겁니다. VM은 잘 뜨는데, 막상 테넌트 네트워크를 여러 개 나누고 나면 트래픽 처리량이 생각보다 안 나오거나, 지연시간이 튀는 경우가 있거든요. 저도 처음엔 “VXLAN이면 그냥 캡슐화 하나 더 되는 거니까 조금만 느리겠지” 정도로 생각했는데, 실제로 홈랩과 운영 비슷한 구조에서 만져보니 **MTU, 오프로딩(offloading, NIC 하드웨어 처리), OVS(Open vSwitch, 가상 스위치) 경로**에 따라 체감이 꽤 달라지더라고요.

    이번 글에서는 OpenStack VXLAN 기반 오버레이 네트워크를 어떻게 벤치마크하면 좋을지, 그리고 Neutron VXLAN 환경에서 테넌트 격리와 처리량을 어떤 기준으로 봐야 하는지 정리해보겠습니다. 숫자를 지어내는 벤치마크 글은 의미가 없으니까, 이 글은 재현 가능한 측정 방법과 해석 기준에 초점을 맞췄습니다. 지금 OpenStack 네트워크 튜닝 중이시라면 꽤 바로 써먹으실 수 있을 거예요.

    컨트롤러, 컴퓨트 노드, 테넌트 네트워크, 터널 엔드포인트가 보이는 OpenStack VXLAN 개요 이미지입니다.

    1. 왜 OpenStack VXLAN 성능 벤치마크가 중요한가요?

    쉽게 말해 VXLAN(Virtual Extensible LAN, 가상 확장 LAN)은 물리 네트워크 위에 가상 네트워크를 하나 더 얹는 방식입니다. 멀티테넌트 환경에서는 정말 편하거든요. VLAN ID 제한에 덜 묶이고, 테넌트별 네트워크를 유연하게 분리할 수 있으니까요. 근데 여기서 중요한 포인트가 있어요. 편리함과 성능은 항상 같은 방향으로 가지는 않는다는 점 말이에요.

    • 캡슐화(encapsulation, 패킷을 한 번 더 감싸는 작업) 오버헤드가 생깁니다.
    • MTU 설정이 맞지 않으면 단편화(fragmentation, 패킷 쪼개짐)로 성능이 무너질 수 있습니다.
    • OVS나 Linux bridge 경로에 따라 CPU 사용률이 크게 달라집니다.
    • east-west traffic(이스트-웨스트 트래픽, VM 간 내부 통신)과 north-south traffic(노스-사우스 트래픽, 외부와의 통신)을 나눠서 봐야 합니다.

    실제로 써보니까 성능 저하 자체보다 더 무서운 건 병목 지점을 모른 채 감으로 튜닝하는 상황이었어요. 이게 제일 오래 갑니다. 삽질 좀 했습니다 ㅎㅎ

    2. OpenStack VXLAN과 Neutron VXLAN 개념, 쉽게 정리해보겠습니다

    OpenStack 네트워크에서 VXLAN은 보통 Neutron(뉴트론, OpenStack 네트워크 서비스)의 오버레이 메커니즘으로 사용돼요. 각 컴퓨트 노드는 터널 종단점 VTEP(VXLAN Tunnel Endpoint, VXLAN 터널 끝점) 역할을 하고, 테넌트 네트워크 트래픽을 UDP 기반 VXLAN 패킷으로 캡슐화해 전달합니다.

    2-1. 데이터 경로를 이해하면 벤치마크 포인트가 보입니다

    1. VM에서 패킷이 나갑니다.
    2. 가상 NIC를 통해 보안 그룹과 가상 스위치를 통과합니다.
    3. 로컬 브리지에서 VXLAN 캡슐화가 이뤄집니다.
    4. 물리 underlay(언더레이, 실제 네트워크)로 전송됩니다.
    5. 상대 노드에서 디캡슐화(decapsulation, 캡슐 해제) 후 대상 VM으로 들어갑니다.

    여기서 성능 포인트는 명확해요. 가상 스위치 처리, 터널 캡슐화, 물리 NIC, MTU 이 네 군데를 봐야 합니다.

    2-2. VLAN과 VXLAN 비교

    항목 VLAN VXLAN
    격리 방식 L2 태그 기반 오버레이 터널 기반
    확장성 상대적으로 제한적 멀티테넌트 확장에 유리
    설계 복잡도 비교적 단순 터널, MTU, 오프로딩 고려 필요
    성능 변수 상대적으로 적음 캡슐화 오버헤드 영향 있음
    OpenStack 활용 Provider network에 자주 사용 Tenant network에 자주 사용

    벤치마크를 할 때는 “VXLAN이 느리다”가 아니라, 어떤 경로에서 얼마나 손실이 생기는지를 봐야 합니다.

    3. 벤치마크 설계: 오버레이 네트워크 성능을 정확히 측정하려면

    제가 직접 해보니 벤치마크가 실패하는 가장 흔한 이유는 측정 항목이 너무 단순하다는 거였어요. `iperf3` 한 번 돌려보고 끝내면, 그건 네트워크 테스트라기보다 순간 샘플에 가까우니까요.

    3-1. 최소 측정 항목

    • 처리량(throughput, 초당 전송량): TCP/UDP 각각 확인
    • 지연시간(latency, 왕복 시간): ping 또는 fping으로 확인
    • 패킷 손실(packet loss): UDP 테스트에서 특히 중요
    • CPU 사용률: 컴퓨트 노드의 `ovs-vswitchd`, `qemu-kvm`, `softirq` 확인
    • MTU 일관성: 인스턴스, TAP, 브리지, 물리 NIC가 연결되는지 확인

    3-2. 테스트 시나리오

    1. 같은 컴퓨트 노드 내 VM 간 통신
    2. 다른 컴퓨트 노드 간 VM 통신
    3. 같은 테넌트 네트워크 내 다수 VM 동시 통신
    4. 서로 다른 테넌트 간 격리 검증
    5. floating IP 또는 router를 통한 외부 통신

    여기서 두 번째와 세 번째가 핵심이에요. 첫 번째만 보면 터널 영향이 덜 보일 수 있거든요. 반대로 크로스-노드(cross-node, 노드 간) 테스트를 해보면 오버레이 네트워크 성능 차이가 확실히 드러납니다.

    4. 실전 구현: OpenStack VXLAN 테스트 환경 준비

    이제 실제로 측정 가능한 구조를 만들어보겠습니다. 예시는 OpenStack CLI 기준으로 적겠습니다. 배포판은 다양하지만, 개념은 거의 비슷해요.

    4-1. 테넌트 네트워크 생성

    openstack network create demo-vxlan-net
    openstack subnet create demo-vxlan-subnet \
      --network demo-vxlan-net \
      --subnet-range 10.10.10.0/24
    
    openstack router create demo-router
    openstack router add subnet demo-router demo-vxlan-subnet

    환경에 따라 외부 네트워크 연결도 필요합니다.

    openstack router set demo-router --external-gateway public

    4-2. 테스트용 인스턴스 2대 이상 배치

    openstack server create vxlan-test-1 \
      --flavor m1.small \
      --image ubuntu \
      --network demo-vxlan-net \
      --key-name mykey
    
    openstack server create vxlan-test-2 \
      --flavor m1.small \
      --image ubuntu \
      --network demo-vxlan-net \
      --key-name mykey

    여기서 가능하면 서로 다른 컴퓨트 노드에 올리는 게 좋아요. 스케줄러 힌트나 가용성 영역을 활용하면 더 명확하게 분리할 수 있습니다.

    4-3. ML2 VXLAN 설정 확인

    배포 환경마다 파일 위치가 다를 수 있지만, 핵심은 ML2 plugin(ML2 플러그인)과 VXLAN 타입 드라이버가 활성화되어 있는지에요.

    [ml2]
    type_drivers = flat,vlan,vxlan
    tenant_network_types = vxlan
    mechanism_drivers = openvswitch,l2population
    
    [ml2_type_vxlan]
    vni_ranges = 1001:2000

    `l2population`은 브로드캐스트/플러딩을 줄이는 데 도움이 되는 기능으로 잘 알려져 있어요. 대규모 환경일수록 의미가 커집니다.

    Neutron ML2 설정, VNI 범위, 각 컴퓨트 노드의 VXLAN 터널 연결 관계를 보여주는 이미지입니다.

    4-4. MTU 확인은 꼭 하셔야 합니다

    VXLAN은 추가 헤더가 붙기 때문에 underlay MTU보다 tenant MTU를 조금 보수적으로 잡는 경우가 많아요. 이 부분을 놓치면 `iperf3`는 애매하게 나오고, 대용량 전송에서만 문제가 재현되기도 합니다. 저도 처음엔 보안 그룹만 의심했는데, 결국 MTU 문제였던 적이 있었어요.

    ip link show
    ip addr
    ping -M do -s 1472 <target_ip>

    `-M do`는 경로 MTU를 강제로 확인할 때 유용해요. 패킷 크기를 조금씩 조정해보면 어디서 단편화가 발생하는지 감이 옵니다.

    5. 성능 측정 방법: iperf3, ping, 시스템 지표를 같이 보세요

    5-1. 기본 처리량 측정

    테스트 VM 한쪽에서는 서버를 띄우고, 다른 쪽에서는 클라이언트로 붙습니다.

    # server
    iperf3 -s
    
    # client
    iperf3 -c 10.10.10.20 -t 30 -P 4

    여기서 `-P 4`처럼 병렬 스트림(parallel stream, 동시 세션)을 주는 이유는 단일 세션만으로는 경로 활용도를 다 못 볼 수 있기 때문이에요.

    5-2. UDP와 손실률 확인

    iperf3 -c 10.10.10.20 -u -b 1G -t 30

    UDP는 대역폭을 강제로 밀어붙이니까 손실과 지터(jitter, 지연 변동폭)를 보기 좋아요. 다만 숫자만 보고 “실사용도 이렇다”고 단정하면 안 돼요. 어디까지나 한계 구간을 찾는 용도에 가깝습니다.

    5-3. 지연시간과 격리 검증

    ping -c 20 10.10.10.20
    
    openstack network create isolated-net
    openstack subnet create isolated-subnet \
      --network isolated-net \
      --subnet-range 10.20.20.0/24

    서로 다른 테넌트 네트워크에서 직접 통신이 안 되는지 확인해보세요. 테넌트 격리는 보안 기능이자 성능 분석의 기준선이에요. 격리가 흐트러지면 벤치마크 이전에 설계부터 다시 봐야 합니다.

    5-4. 호스트 측 관찰 포인트

    top
    htop
    sar -n DEV 1
    ip -d link show
    ovs-vsctl show
    ovs-ofctl dump-ports br-tun

    성능이 기대보다 안 나오는데 VM 내부는 멀쩡하다면, 호스트의 softirq나 OVS 포트 카운터를 같이 봐야 해요. 근데 여기서 중요한 건, 네트워크만 보지 말고 CPU를 같이 보라는 점이에요. 오버레이는 생각보다 CPU 영향을 받거든요.

    6. ⚠️ 트러블슈팅: 실제로 자주 막히는 지점

    이 섹션은 정말 중요해요. 제가 홈랩에서 OpenStack 네트워크 만질 때 제일 오래 잡아먹은 부분들이거든요.

    6-1. MTU 불일치

    • 증상: TCP는 되는데 대용량 전송에서 처리량이 애매하게 떨어짐
    • 원인: VXLAN 캡슐화 헤더를 고려하지 않은 MTU 설정
    • 해결: 인스턴스 NIC, TAP, `br-int`, `br-tun`, 물리 NIC까지 경로 전체 MTU 점검

    6-2. 오프로딩 설정 이슈

    • 증상: CPU 사용률이 과하게 올라가고 처리량이 들쭉날쭉함
    • 원인: NIC offload와 가상화 경로 조합 문제
    • 해결: `ethtool -k`로 현재 상태를 보고 변경 전후 비교 측정
    ethtool -k eth0

    이건 환경마다 정답이 달라요. 무조건 켜라, 무조건 꺼라 식으로 가면 위험해요. 그래서 반드시 변경 전후를 같은 조건으로 비교해야 합니다.

    6-3. 보안 그룹과 conntrack 병목

    • 증상: 연결 수가 늘면 응답이 갑자기 무거워짐
    • 원인: stateful filtering(상태 기반 필터링)과 connection tracking 부담
    • 해결: 테스트 시나리오를 단순화하고, 보안 정책 영향도 분리해서 확인

    6-4. 같은 노드와 다른 노드 성능 차이

    같은 컴퓨트 노드 안에서는 생각보다 잘 나오는데, 다른 노드로 넘어가는 순간 성능이 달라지는 경우가 많아요. 이럴 때는 거의 대부분 터널 경로 또는 물리 underlay를 의심하게 됩니다.

    VM 간 iperf3 측정, 호스트 CPU 사용률, MTU 점검 포인트가 함께 보이는 실전 운영 이미지입니다.

    7. 검증과 결과 해석: 숫자보다 중요한 것

    벤치마크 결과를 볼 때 저는 보통 아래 순서로 해석해요. 숫자 하나만 보고 결론 내리면 나중에 꼭 후회하더라고요.

    1. 같은 노드와 다른 노드 간 격차가 큰가
    2. TCP와 UDP 결과 차이가 과도한가
    3. 지연시간 평균보다 편차가 큰가
    4. 호스트 CPU 사용률이 병목처럼 보이는가
    5. 테넌트 수 증가 시 성능 하락 패턴이 급격한가

    예를 들어 처리량이 조금 낮아도 지연시간이 안정적이고 손실이 적다면, 실서비스에서는 충분히 좋은 결과일 수 있어요. 반대로 순간 최대 처리량이 높아도 CPU가 포화되고 지터가 심하면 운영 입장에서는 불안한 구조죠.

    검증 항목 좋은 신호 주의 신호
    처리량 반복 측정 시 편차가 작음 테스트마다 편차가 큼
    지연시간 평균과 최대값 차이가 적당함 간헐적 스파이크 발생
    패킷 손실 UDP 부하에서도 통제 가능 부하 시 급격히 증가
    CPU 사용률 여유가 있음 ovs-vswitchd 또는 softirq 집중
    격리 상태 테넌트 간 통신 차단 명확 정책 누락 또는 라우팅 혼선

    오버레이 네트워크 성능은 결국 설계와 운영 습관의 결과물이에요. 그래서 결과 보고서에는 숫자만 넣지 말고, 테스트 조건도 같이 남기시는 걸 권장합니다. 다음에 다시 비교할 때 진짜 큰 도움이 돼요.

    OpenStack VXLAN 벤치마크 결과와 지연시간 처리량을 보여주는 대시보드 이미지

    처리량, 지연시간, CPU 사용률을 함께 보여주는 OpenStack VXLAN 벤치마크 결과 시각화 이미지입니다.

    8. 정리와 다음 단계: OpenStack 네트워크 튜닝은 이렇게 이어가시면 됩니다

    정리해보면 OpenStack VXLAN 벤치마크에서 중요한 건 단순 최고 속도가 아니에요. Neutron VXLAN 환경에서 테넌트 격리가 제대로 되는지, 크로스-노드 트래픽이 안정적인지, MTU와 OVS 경로가 일관적인지, 그리고 호스트 CPU가 어디서 쓰이는지를 같이 봐야 합니다.

    제가 직접 해보니 가장 효과가 컸던 접근은 이것이었어요.

    1. 같은 노드와 다른 노드 결과를 분리해서 기록합니다.
    2. TCP, UDP, ping을 각각 따로 봅니다.
    3. 문제가 보이면 MTU와 오프로딩부터 확인합니다.
    4. 그 다음에 보안 그룹, conntrack, underlay를 봅니다.

    이 순서로 가면 삽질을 꽤 줄일 수 있어요. 드디어 됐다! 싶은 순간이 오거든요.

    OpenStack VXLAN 성능 최적화 체크리스트와 비교 요약 인포그래픽

    MTU, 오프로딩, OVS, 테넌트 격리, 처리량 검증 항목을 한눈에 정리한 요약 인포그래픽입니다.

    자주 묻는 질문

    Q1. VXLAN이면 무조건 VLAN보다 느린가요?

    무조건 그렇지는 않아요. 캡슐화 오버헤드는 있지만, 실제 체감은 NIC 성능, CPU, OVS 구성, underlay 품질에 따라 달라집니다.

    Q2. 벤치마크는 어떤 도구부터 쓰면 좋을까요?

    가볍게는 `ping`, `iperf3`, `sar`, `ethtool`, `ovs-vsctl` 정도면 시작하기 좋아요. 도구보다 중요한 건 같은 조건으로 반복 측정하는 습관입니다.

    Q3. 테넌트 격리는 어떻게 검증하나요?

    서로 다른 테넌트 네트워크에 VM을 두고 직접 통신 가능 여부, 라우터 연결 여부, 보안 그룹 정책을 분리해서 확인하시면 돼요.

    다음 글에서는 Open vSwitch 기반에서 `br-int`, `br-tun`, provider network 경로를 좀 더 깊게 파서, 어디서 병목이 생기는지 보는 방법을 다뤄볼 예정입니다. 이전 글에서 다룬 Linux 네트워크 기본기와 함께 보시면 훨씬 이해가 잘 될 거예요.

  • [OpenStack] OpenStack Manila 도입 1년 회고

    [OpenStack] OpenStack Manila 도입 1년 회고

    [OpenStack] OpenStack Manila 도입 1년 회고

    프라이빗 클라우드 파일 스토리지 이야기를 하면, 많은 분들이 처음엔 Cinder(신더, 블록 스토리지)나 Swift(스위프트, 오브젝트 스토리지)부터 떠올리시더라고요. 저도 그랬습니다. 그런데 VM(가상머신) 여러 대와 컨테이너 워크로드가 같이 굴러가기 시작하면, 결국 팀에서 꼭 묻는 질문이 하나 나옵니다. “공유 폴더처럼 쓸 수 있는 스토리지는 없나요?” 바로 그 지점에서 OpenStack Manila가 등장합니다.

    저는 지난 1년 동안 홈랩과 사내와 유사한 형태의 프라이빗 환경에서 Manila 운영 방식을 꽤 집요하게 다듬어봤습니다. 처음엔 “이게 Nova(노바, 컴퓨트)나 Neutron(뉴트론, 네트워크)처럼 그냥 붙이면 되겠지” 했었는데요. 막상 들어가 보니 기능은 명확한데, 프라이빗 클라우드 파일 스토리지 운영할 때 고려할 포인트가 생각보다 많더라고요. 특히 Manila로 파일 스토리지를 운영하면 자동화가 편해지는 대신, 네트워크와 백엔드 설계를 대충 하면 나중에 꼭 되돌아오니까요. 오늘은 OpenStack Manila 도입 1년 회고라는 관점에서, 좋았던 점과 아쉬웠던 점을 솔직하게 정리해보겠습니다.

    OpenStack Manila, 컴퓨트 노드, 스토리지 백엔드, 사용자 네트워크가 어떻게 연결되는지 한눈에 보여주는 아키텍처 이미지가 들어갈 자리입니다.

    1. 왜 OpenStack Manila를 보게 되었는가

    처음 문제는 단순했습니다. 프로젝트마다 VM 안에 데이터를 따로 넣어두다 보니, 배치 작업 서버와 애플리케이션 서버가 같은 데이터를 봐야 하는 상황에서 계속 복사본이 생겼거든요. 이러면 데이터 일관성도 깨지고, 백업 정책도 꼬이고, 장애가 나면 복구 지점도 애매해집니다.

    프라이빗 클라우드 파일 스토리지 요구가 계속 나오면서 선택지를 세 가지로 놓고 봤습니다.

    • VM 내부 디스크를 각자 관리한다
    • Cinder 볼륨을 붙여서 우회한다
    • 공유 파일 스토리지 자체를 서비스로 제공한다

    세 번째가 바로 OpenStack Manila, 즉 프라이빗 클라우드 파일 스토리지 서비스의 자리였습니다. 실제로 써보니까, 파일 공유를 사람 손으로 매번 만들어주는 방식보다 API(에이피아이, 프로그램 호출 인터페이스) 기반으로 표준화하는 게 훨씬 관리가 잘 되더라고요.

    2. OpenStack Manila란 무엇인가

    쉽게 말해 OpenStack Manila는 공유 파일 시스템을 서비스 형태로 제공하는 컴포넌트입니다. Cinder가 블록 디바이스를 내주는 역할이라면, Manila는 NFS(엔에프에스, 네트워크 파일 시스템)나 SMB(에스엠비, 파일 공유 프로토콜) 같은 형태의 공유 스토리지를 만들어주는 쪽에 가깝습니다.

    처음엔 이름이 좀 낯설죠. 저도 처음엔 “왜 이름이 Manila지?” 싶었는데, 기능 자체는 꽤 직관적입니다. 핵심 개념만 잡아두면 어렵지 않거든요.

    핵심 개념 한 번에 정리

    • Share: 실제로 사용자에게 제공되는 파일 공유 자원
    • Share Type: 성능, 백엔드, 기능 정책을 구분하는 템플릿
    • Share Network: 공유 스토리지가 붙을 네트워크 정보
    • Backend Driver: CephFS(세프에프에스), NetApp, Generic driver 같은 실제 구현체와 연결되는 계층
    • Access Rule: 어떤 IP나 사용자에게 접근을 허용할지 정하는 규칙

    여기서 중요한 포인트! Manila 자체가 스토리지를 저장하는 제품은 아닙니다. 정확히는 백엔드 파일 스토리지를 OpenStack 방식으로 관리해주는 제어 계층이라고 생각하시면 돼요. 이 차이를 이해 못 하면 설계가 꼬입니다.

    다른 스토리지와 무엇이 다른가

    구분 주 용도 접근 방식 운영 시 느낌
    Ephemeral Disk 인스턴스 로컬 작업 VM 내부 로컬 디스크 빠르지만 수명과 이동성 제약이 크다
    Cinder 데이터베이스, 단일 서버 디스크 블록 디바이스 마운트 명확하지만 다중 공유에는 부적합
    Swift 백업, 아카이브, 객체 저장 HTTP API 확장성은 좋지만 파일시스템처럼 쓰긴 어렵다
    Manila (프라이빗 클라우드 파일 스토리지) 공유 파일 스토리지 NFS/SMB 등 협업과 공용 데이터셋에 강하다

    3. 도입 전에 꼭 봐야 했던 설계 포인트

    제가 1년 운영하면서 느낀 건, Manila는 설치보다 설계가 더 중요하다는 점입니다. 특히 아래 세 가지를 먼저 정리해야 나중에 덜 고생합니다.

    1. 백엔드 선택: CephFS처럼 분산 파일 시스템을 붙일지, 전통적인 NAS(나스, 네트워크 스토리지)를 붙일지 결정해야 한다
    2. 네트워크 분리: 스토리지 트래픽과 테넌트 트래픽을 어느 정도 분리할지 판단해야 한다
    3. 운영 권한 모델: 누가 share를 만들고, 누가 접근 규칙을 열 수 있는지 기준을 세워야 한다

    사실 여기서 많이들 놓치는 게 두 번째입니다. 프라이빗 클라우드 파일 스토리지는 결국 네트워크 영향을 강하게 받습니다. 스토리지 백엔드는 멀쩡한데도 MTU(엠티유, 최대 전송 단위)나 라우팅, 보안그룹 정책 때문에 체감 성능이 무너지는 경우를 꽤 봤거든요.

    4. OpenStack Manila 실전 구현: 제가 실제로 잡았던 기본 흐름

    이제 구현 얘기를 해보겠습니다. 환경마다 패키지 설치 방식은 다를 수 있으니, 여기서는 운영 개념과 명령 흐름 위주로 정리하겠습니다. 저는 처음에 모든 설정을 한 번에 넣으려다가 꼬여서, 결국 가장 단순한 형태부터 올리는 방식으로 갔습니다. 이게 훨씬 낫더라고요.

    1) 서비스 상태 확인

    openstack share service list
    openstack endpoint list --service manila
    openstack network list
    

    맨 처음엔 화려한 기능보다 서비스가 보이느냐부터 확인했습니다. 생각보다 기본 서비스 등록이나 엔드포인트 누락이 자주 나옵니다.

    2) share type 생성

    openstack share type create default_share false
    openstack share type set --extra-specs snapshot_support=true default_share
    

    Share Type은 나중에 Manila 운영 정책의 중심이 됩니다. 성능 클래스, 스냅샷 허용 여부, 백엔드 매핑 기준을 여기에 녹여두면 사용자 설명이 쉬워지거든요.

    3) share network 생성

    openstack share network create \
      --name manila-share-net \
      --neutron-net-id <tenant-network-id> \
      --neutron-subnet-id <tenant-subnet-id>
    

    여기서 저도 한 번 크게 삽질했습니다. 인스턴스가 붙은 네트워크와 share network 관계를 대충 맞추면 될 줄 알았는데, 실제로는 접근 경로와 라우팅이 명확해야 마운트 단계에서 덜 막힌다더라고요.

    4) 공유 스토리지 생성

    openstack share create \
      --name project-data \
      --share-type default_share \
      --share-network manila-share-net \
      --size 100 \
      NFS
    

    생성 직후 바로 쓰려고 하면 안 됩니다. 상태가 available이 될 때까지 기다려야 합니다.

    openstack share list
    openstack share show project-data
    
    OpenStack Manila share type과 share network 구성 흐름 이미지

    Share type, share network, backend driver, tenant network가 어떤 순서로 연결되는지 보여주는 구성 다이어그램이 들어갈 자리입니다.

    5) 접근 제어 추가

    openstack share access create project-data ip 10.10.20.15
    openstack share access list project-data
    

    Manila 운영하면서 가장 체감이 좋았던 부분 중 하나가 이겁니다. 예전엔 파일 공유를 열 때 네트워크팀, 스토리지팀, 운영팀이 각각 손대야 했었는데요. Manila를 붙이니 최소한 권한과 절차가 API로 정리되니까 일이 많이 단순해졌습니다.

    6) 인스턴스에서 마운트

    sudo mkdir -p /mnt/project-data
    sudo mount -t nfs <share-export-location> /mnt/project-data
    df -h
    mount | grep project-data
    

    여기서 export location이 올바르게 나오는지 확인해야 합니다. 실제 사용자는 이 지점만 보기 때문에, 앞단 자동화가 아무리 좋아도 마운트 실패하면 평가가 박해집니다. 냉정하죠 ㅎㅎ

    7) 설정 예시

    [DEFAULT]
    default_share_type = default_share
    enabled_share_backends = cephfsnfs
    
    [cephfsnfs]
    share_backend_name = CEPHFSNFS
    driver_handles_share_servers = false
    

    설정은 백엔드마다 달라지니 그대로 복붙하시면 안 되고, 운영 중인 백엔드 문서와 정확히 맞춰야 합니다. 다만 관점 자체는 비슷합니다. 어떤 백엔드를 활성화할지, 드라이버가 share server를 직접 다룰지 여부를 정하는 구조니까요.

    5. 1년 운영하며 좋았던 점: 명(明)

    OpenStack Manila 운영을 1년쯤 해보니까, 분명 장점이 있습니다. 이건 꽤 명확했습니다.

    • 셀프서비스화: 사용 부서가 요청만 하면 표준 절차로 공유 스토리지를 만들 수 있다
    • 정책 통일: share type 중심으로 Manila 운영 기준을 맞추기 쉽다
    • 접근 제어 가시성: 누가 어떤 share에 접근 가능한지 추적이 쉬워진다
    • 자동화 친화적: Terraform(테라폼, 인프라 선언형 자동화)이나 내부 포털과 엮기 좋다

    특히 프로젝트 단위로 수명주기를 관리할 때 편했습니다. 인스턴스는 바뀌어도 데이터 공유 계층은 유지할 수 있으니, 작업 서버를 새로 올려도 공유 데이터를 다시 설계할 필요가 없거든요. 이거 진짜 편하더라고요.

    또 하나는 운영 책임 구간이 분리된다는 점입니다. 예전엔 “공유 폴더 느려요”라는 말이 나오면 원인 범위가 너무 넓었는데, Manila 도입 후에는 적어도 API 계층, 네트워크 계층, 백엔드 계층으로 잘게 나눠서 볼 수 있었습니다.

    6. 1년 운영하며 아쉬웠던 점: 암(暗)

    근데 여기서 중요한 게 있습니다. Manila는 만능이 아닙니다. 오히려 기대치를 너무 높게 잡으면 실망하기 쉽습니다.

    첫째, 문제의 절반은 결국 백엔드와 네트워크입니다

    사용자 입장에서는 OpenStack Manila가 파일 스토리지를 제공하는 것처럼 보이지만, 실제 체감 품질은 백엔드 스토리지와 네트워크 설계에 크게 좌우됩니다. 즉, Manila가 느린 게 아니라 뒤쪽이 느린 경우가 많습니다. 이걸 분리해서 설명하는 데 시간이 꽤 들었습니다.

    둘째, 권한 설계가 느슨하면 금방 복잡해집니다

    처음엔 “필요한 사람에게 IP만 열어주면 되지” 했었는데요. 몇 달 지나면 예외 규칙이 누적됩니다. 접근 규칙을 누가 승인하는지, 만료 기준은 뭔지, 프로젝트 종료 시 어떻게 닫을지 초반에 정해야 합니다.

    셋째, 장애 분석이 생각보다 단순하지 않습니다

    마운트 실패 하나만 놓고 봐도 원인이 다양합니다. DNS(디엔에스, 이름 해석), 라우팅, 보안그룹, export location, 백엔드 상태, 커널 NFS 클라이언트 옵션까지 봐야 하거든요. 처음엔 “왜 이렇게 복잡하지?” 싶었는데, 결국 파일 공유라는 게 여러 계층이 맞물리는 서비스라 그렇더라고요.

    7. ⚠️ 실제로 겪었던 트러블슈팅

    이 섹션은 좀 현실적으로 적어볼게요. 저도 처음엔 문서만 보면 금방 될 줄 알았는데, 실제 Manila 운영에선 아래 이슈를 자주 만났습니다.

    문제 1. share는 생성됐는데 마운트가 안 되는 경우

    • 증상: `mount.nfs: access denied by server`
    • 원인 후보: 접근 규칙 누락, 클라이언트 IP 변경, 잘못된 네트워크 경로
    • 해결: `openstack share access list`로 허용 규칙 확인 후, 실제 클라이언트 IP와 비교
    openstack share access list project-data
    ip addr
    ip route
    

    생각보다 NAT(엔에이티, 주소 변환)나 점프 구간 때문에 사용자가 보는 IP와 실제 서버가 보이는 IP가 다른 경우가 있었습니다.

    문제 2. 생성 속도는 괜찮은데 체감 성능이 들쭉날쭉한 경우

    • 증상: 어떤 VM은 빠르고 어떤 VM은 유독 느림
    • 원인 후보: 네트워크 경로 차이, MTU 불일치, 혼잡 구간 존재
    • 해결: 경로별 성능 차이를 먼저 분리 측정하고, Manila 문제로 단정하지 않기

    여기서 제가 배운 건 하나입니다. 스토리지 문제를 API 문제로 착각하지 말 것. 관리 평면(control plane)과 데이터 평면(data plane)을 분리해서 봐야 합니다.

    문제 3. 공유는 살아 있는데 운영 기록이 남지 않는 경우

    • 증상: 누가 왜 접근 규칙을 열었는지 추적이 어려움
    • 원인 후보: 수동 작업, 표준 요청 절차 부재
    • 해결: 변경 요청 번호나 티켓 번호를 share 이름 또는 메타데이터 규칙에 반영

    이건 기술 이슈 같지 않지만 실제 Manila 운영에선 꽤 큽니다. 나중에 감사나 보안 점검 때 힘들어지거든요.

    문제 4. 기대보다 운영 난도가 높게 느껴지는 경우

    사실 OpenStack 스토리지는 모두 그렇지만, Manila도 “기능 추가”보다 “운영 모델 정리”가 더 어렵습니다. 백엔드 드라이버 특성, 네트워크 토폴로지, 접근 정책이 모두 연결되니까요. 그래서 제가 추천하는 방식은 이겁니다.

    1. 처음엔 딱 한 가지 share type만 운영한다
    2. 접근 제어는 가장 보수적으로 시작한다
    3. 사용자 수요가 확인된 뒤에 스냅샷, 멀티 백엔드, 성능 클래스 분리를 확장한다

    한 번에 다 하려 하지 않는 것, 이게 제일 중요했습니다.

    8. 검증과 운영 결과: 무엇이 달라졌나

    그럼 1년 운영해서 뭐가 남았냐, 이 질문이 제일 중요하겠죠. 제가 직접 해보니 결과는 꽤 분명했습니다.

    • 프라이빗 클라우드 파일 스토리지 개설 절차가 표준화됐다
    • 프로젝트별 데이터 공유 방식이 단순해졌다
    • 수동 NAS 작업이 줄어들었다
    • 장애 시 원인 구간을 더 빨리 좁힐 수 있게 됐다

    반대로, 운영 문서와 접근 정책이 없으면 Manila 운영은 금방 복잡해진다는 것도 확인했습니다. 즉, OpenStack Manila의 성공 조건은 설치가 아니라 운영 규칙이에요.

    openstack share list
    openstack share service list
    openstack share type list
    openstack share network list
    

    검증할 때는 단순히 리소스가 보이는지보다, 아래 항목을 같이 확인했습니다.

    1. Share 상태가 `available`인지
    2. 접근 규칙이 기대한 대상에만 열려 있는지
    3. 실제 인스턴스에서 마운트와 읽기/쓰기가 되는지
    4. 장애 시 로그와 변경 이력이 추적 가능한지
    OpenStack Manila 운영 결과와 검증 체크리스트 대시보드 이미지

    Share 상태, 접근 규칙, 마운트 성공 여부, Manila 운영 지표를 한 화면에서 점검하는 대시보드 이미지가 들어갈 자리입니다.

    9. FAQ와 마무리: 다음 단계는 어떻게 가면 좋을까

    자주 묻는 질문

    • Q. Manila는 모든 환경에서 꼭 필요한가요?
      아닙니다. 프라이빗 클라우드 파일 스토리지 요구가 적고 운영 단순성이 더 중요하면 굳이 넣지 않는 게 나을 수도 있습니다.
    • Q. 프라이빗 클라우드 파일 스토리지로 바로 도입해도 될까요?
      가능은 하지만, 먼저 한두 팀 대상 파일 공유 서비스로 시작해 Manila 운영 모델을 검증하는 걸 추천합니다.
    • Q. OpenStack 스토리지 중 우선순위는 어떻게 잡아야 하나요?
      블록, 오브젝트, 파일의 요구가 다르니 워크로드 기준으로 판단해야 합니다. “공유 파일”이 핵심이면 Manila가 후보가 됩니다.

    정리해보면 이렇습니다. OpenStack Manila는 프라이빗 클라우드 파일 스토리지 운영을 표준화하는 데 꽤 좋은 도구입니다. 다만 제품만 올린다고 끝나는 게 아니고, 백엔드 선택과 네트워크 설계, 접근 정책, 운영 문서화까지 같이 가야 진짜 효과가 납니다.

    저도 처음엔 이게 뭔가 싶었는데, 1년쯤 지나고 나니 보이더라고요. Manila 운영의 핵심은 “기능 활성화”가 아니라 “운영 경계 정의”였습니다. 이걸 빨리 이해할수록 삽질이 줄어들더라고요.

    다음 글에서는 OpenStack Manila 운영 시 백엔드 선택 기준, 예를 들면 CephFS 계열과 전통적인 NAS 연동 관점에서 무엇을 봐야 하는지 더 구체적으로 다뤄볼 예정입니다. 이전 글에서 다뤘던 OpenStack 네트워크 설계 내용과도 연결해서 보시면 훨씬 이해가 쉬우실 겁니다.

    OpenStack Manila 도입 전후 장단점 비교 인포그래픽

    도입 전 수동 운영 방식과 도입 후 표준화된 프라이빗 클라우드 파일 스토리지 운영 방식을 비교하는 요약 인포그래픽이 들어갈 자리입니다.

    혹시 지금 OpenStack Manila 도입을 고민 중이시라면, 제 경험상 가장 먼저 할 일은 하나입니다. “누가 어떤 데이터를 어떤 방식으로 공유해야 하는가”를 먼저 적어보세요. 그 다음에 Manila를 붙이면 훨씬 덜 헤맵니다. 이 순서, 생각보다 정말 중요합니다. 🎉

  • [OpenStack] OpenStack Floating IP 연결 문제 해결: 보안 그룹 디버깅

    [OpenStack] OpenStack Floating IP 연결 문제 해결: 보안 그룹 디버깅

    [OpenStack] Floating IP 연결 문제 해결: 보안 그룹 디버깅

    OpenStack Floating IP 연결 문제 때문에 VM(가상 머신)은 멀쩡히 떠 있는데 외부에서 SSH 하나 안 붙는 상황, 한 번쯤 겪어보셨을 겁니다. 저도 처음엔 라우터(router)나 네임스페이스(namespace)부터 의심했었는데, 막상 까보면 보안 그룹(Security Group, 가상 방화벽 정책)이 원인이었던 경우가 꽤 많았습니다. 특히 인스턴스 생성은 잘 되고 Floating IP 할당도 정상인데 ping은 안 되고 SSH도 timeout 나면, 이거 진짜 사람 멘탈 흔들리거든요. 오늘은 제가 홈랩과 테스트 환경에서 실제로 자주 확인하는 흐름 기준으로, OpenStack Floating IP 연결 문제를 어떻게 좁혀 가는지 정리해보겠습니다.

    이 글은 단순히 명령어만 던지는 글은 아닙니다. 왜 막히는지, 어디서 확인해야 하는지, 그리고 보안 그룹 디버깅을 어떤 순서로 해야 삽질을 줄일 수 있는지에 집중해보겠습니다. 이전 글에서 다뤘던 Neutron(뉴트론, OpenStack 네트워크 서비스) 기본 구조를 알고 계시면 더 이해가 빠르고요, 다음 글에서는 router namespace 추적도 따로 다뤄볼 예정입니다.

    OpenStack Floating IP와 보안 그룹 흐름 개요 다이어그램

    OpenStack 네트워크에서 인스턴스, 포트, 라우터, Floating IP, 보안 그룹이 어떻게 연결되는지 한눈에 보여주는 개요 이미지입니다.

    1. 왜 Floating IP는 붙었는데 접속이 안 될까요?

    쉽게 말해 Floating IP는 공인 접근용 주소를 내부 인스턴스에 매핑하는 기능입니다. 그런데 주소만 연결됐다고 바로 통신이 되는 건 아닙니다. 실제 트래픽은 중간에 여러 단계를 통과하거든요.

    • Floating IP가 인스턴스 포트(port)에 제대로 연결돼 있어야 합니다.
    • 라우터가 외부 네트워크(external network)와 내부 서브넷(subnet)을 이어줘야 합니다.
    • 인스턴스 내부 OS 방화벽도 열려 있어야 합니다.
    • 그리고 가장 자주 놓치는 게 보안 그룹(Security Group)입니다.

    여기서 중요한 포인트! OpenStack 보안 그룹은 AWS 보안 그룹과 비슷하게 가상 NIC(네트워크 인터페이스) 앞단에서 동작하는 방화벽 개념으로 이해하면 편합니다. 즉, VM 안의 sshd가 떠 있어도 보안 그룹에서 막으면 외부에서는 그냥 응답이 없는 것처럼 보입니다.

    2. 개념부터 정리: Security Group과 Floating IP의 관계

    저도 처음엔 헷갈렸는데, Floating IP는 주소 매핑이고 Security Group은 트래픽 허용 정책입니다. 둘은 역할이 완전히 다릅니다. 쉽게 말해 집 주소는 알고 있는데 현관문이 잠겨 있는 상태라고 보시면 됩니다.

    구성 요소 역할 문제 발생 시 증상
    Floating IP 외부 IP를 내부 포트에 매핑 연결 대상 자체를 못 찾음
    Router 내부망과 외부망 라우팅 외부 통신 경로 없음
    Security Group 포트 단위 Ingress/Egress 제어 ping/SSH/HTTP가 timeout 또는 drop
    Guest OS Firewall 인스턴스 내부 방화벽 OpenStack 설정은 정상인데 접속 실패

    특히 Ingress(인그레스, 외부에서 들어오는 트래픽) 규칙이 빠져 있으면 SSH 22/tcp나 ICMP가 막힙니다. 반대로 Egress(이그레스, 외부로 나가는 트래픽)가 과하게 제한되어 있으면 응답 패킷이 못 나가서 통신이 이상하게 보일 수도 있습니다. OpenStack 네트워크 오류를 볼 때는 반드시 양방향 관점으로 봐야 합니다.

    3. 먼저 확인할 체크리스트: 문제를 좁히는 순서

    제가 직접 해보니 무작정 명령어부터 많이 치는 것보다, 확인 순서를 고정하는 게 훨씬 낫더라고요. 아래 순서대로 보면 대부분 원인을 빨리 찾습니다.

    1. 인스턴스에 Floating IP가 정말 연결됐는지 확인합니다.
    2. 해당 인스턴스 포트에 어떤 보안 그룹이 붙어 있는지 봅니다.
    3. 보안 그룹 규칙에 SSH, ICMP, 필요한 서비스 포트가 있는지 확인합니다.
    4. 인스턴스 내부에서 IP 주소와 default route가 정상인지 확인합니다.
    5. Guest OS firewall(예: firewalld, ufw, iptables/nftables)도 봅니다.
    6. 그래도 안 되면 라우터, 네트워크 네임스페이스, 포트 상태까지 내려갑니다.

    이 순서를 지키면 OpenStack Floating IP 연결 문제를 네트워크 전체 장애로 오해하는 일을 꽤 줄일 수 있습니다.

    4. 실전 구현: CLI로 보안 그룹 디버깅하기

    이제 실제로 많이 쓰는 OpenStack CLI 기준으로 확인해보겠습니다. 환경마다 alias나 RC 파일은 다를 수 있으니, 먼저 인증 환경을 로드해 주세요.

    4-1. Floating IP 연결 상태 확인

    source admin-openrc
    
    openstack server list
    openstack floating ip list
    openstack server show <SERVER_NAME_OR_ID>

    여기서 제가 제일 먼저 보는 건 두 가지입니다. 하나는 Floating IP가 어느 포트에 연결됐는지, 다른 하나는 서버에 private IP와 mapped IP가 어떻게 보이는지입니다. 간혹 Floating IP는 생성됐는데 실제로 port association(포트 연결)이 안 된 경우도 있습니다.

    openstack floating ip show <FLOATING_IP>

    출력에서 확인할 포인트는 다음과 같습니다.

    • Port 값이 비어 있지 않은지
    • Fixed IP Address가 대상 인스턴스 IP와 일치하는지
    • Status가 DOWN처럼 이상하지 않은지

    4-2. 인스턴스 포트와 보안 그룹 확인

    openstack port list --server <SERVER_NAME_OR_ID>
    openstack port show <PORT_ID>

    여기서 security_group_ids를 확인합니다. 생각보다 흔한 실수가, 인스턴스는 맞는데 기대한 보안 그룹이 아니라 default만 붙어 있는 경우입니다. 저도 예전에 Terraform 수정하다가 보안 그룹 연결이 빠져서 한참 헤맨 적이 있었네요. 이런 건 CLI로 보면 바로 드러납니다.

    인스턴스 포트와 보안 그룹 연결 관계를 보여주는 설정 다이어그램

    인스턴스 포트에 어떤 보안 그룹이 연결되고, 그 규칙이 Floating IP 트래픽에 어떻게 적용되는지 설명하는 구성 이미지입니다.

    4-3. 보안 그룹 규칙 점검

    openstack security group list
    openstack security group show <SECURITY_GROUP_ID_OR_NAME>

    SSH 접속 기준으로는 보통 아래 규칙이 필요합니다.

    openstack security group rule create --protocol tcp --dst-port 22 <SECURITY_GROUP_ID>
    openstack security group rule create --protocol icmp <SECURITY_GROUP_ID>

    운영 환경이라면 0.0.0.0/0 전체 허용보다는 remote IP prefix(원격 IP 대역 제한)를 걸어두는 게 좋습니다.

    openstack security group rule create \
      --protocol tcp \
      --dst-port 22 \
      --remote-ip 203.0.113.10/32 \
      <SECURITY_GROUP_ID>

    여기서 중요한 포인트! Ping이 안 된다고 해서 무조건 네트워크 전체가 죽은 건 아닙니다. ICMP 규칙이 없어서 ping만 실패하고, SSH는 되는 경우도 있고 그 반대도 있습니다. 그래서 테스트는 항상 protocol별로 따로 봐야 합니다.

    4-4. 인스턴스 내부에서도 확인

    보안 그룹만 열어놓고 끝이 아니더라고요. 게스트 OS 쪽도 같이 봐야 합니다.

    ip addr
    ip route
    ss -tulpn | grep :22
    sudo systemctl status sshd
    sudo firewall-cmd --list-all
    sudo ufw status

    배포판에 따라 `sshd` 서비스명이나 방화벽 도구는 다를 수 있습니다. 핵심은 서비스가 실제로 떠 있는지, 그리고 OS 방화벽이 22/tcp를 막고 있지 않은지입니다.

    5. 자주 만나는 OpenStack 네트워크 오류 패턴

    이 섹션은 진짜 실전용입니다. 제가 실제로 써보니까 아래 패턴들이 반복해서 나오더라고요. OpenStack 쪽 문제처럼 보여도 원인은 의외로 단순한 경우가 많습니다.

    5-1. default 보안 그룹만 붙어 있는 경우

    가장 흔합니다. 인스턴스 생성할 때 별도 보안 그룹 지정이 빠지면 default만 달리는데, 이 default 정책이 환경에 따라 거의 비어 있거나 내부 통신 위주일 수 있습니다. 그러면 Floating IP 오류처럼 보이지만 사실은 허용 규칙 부재입니다.

    5-2. IPv4 규칙은 있는데 잘못된 원격 대역으로 제한한 경우

    예를 들어 사무실 공인 IP만 허용해뒀는데, VPN을 안 켜고 집에서 접속하면 당연히 안 됩니다. 근데 현장에서는 이걸 잊고 라우터 문제부터 의심하게 되거든요. 저도 몇 번 당했습니다 ㅎㅎ

    5-3. Egress 규칙 누락

    대부분 Ingress만 보는데, 보안 정책을 엄격하게 운영하는 환경에서는 Egress도 제한합니다. 이 경우 SYN은 들어왔는데 응답이 못 나가서 연결이 묘하게 실패할 수 있습니다.

    5-4. 인스턴스 내부 default route 문제

    DHCP가 꼬였거나 cloud-init 설정이 예상과 다르면, VM 내부 게이트웨이 경로가 어긋나기도 합니다. 그러면 보안 그룹을 아무리 열어도 답이 안 나옵니다.

    5-5. SSH 데몬 미기동 또는 이미지 자체 문제

    간단하지만 놓치기 쉽습니다. 이미지 빌드 과정에서 `sshd` 설정이 바뀌었거나, cloud-init 키 주입이 실패해서 인증 단계에서 막힐 수도 있습니다. 그래서 네트워크 계층과 서비스 계층을 같이 봐야 합니다.

    6. 제가 쓰는 추천 점검 순서: 최소 삽질 루틴

    혹시 이런 경험 있으신가요? 원인이 여러 군데일 수 있으니 한 번에 다 건드리다가 더 꼬이는 상황이요. 저는 그래서 아래 루틴으로 고정해두고 봅니다.

    1. `openstack floating ip show`로 실제 연결 포트를 확인합니다.
    2. `openstack port show`로 보안 그룹 부착 상태를 확인합니다.
    3. `openstack security group show`로 SSH/ICMP 규칙 유무를 봅니다.
    4. 필요하면 임시로 테스트 규칙을 넣고 재시도합니다.
    5. 안 되면 VM 콘솔 접속으로 내부 IP, route, sshd 상태를 봅니다.
    6. 마지막으로 라우터와 네트워크 노드 쪽을 의심합니다.

    이 루틴의 장점은, 원인을 주소 매핑 문제, 정책 문제, 게스트 OS 문제로 나눠서 볼 수 있다는 점입니다. 문제를 범주화하면 훨씬 덜 흔들립니다.

    단계별 디버깅 체크리스트와 명령어 흐름도

    Floating IP 확인부터 보안 그룹, 인스턴스 내부 점검까지 이어지는 트러블슈팅 순서를 시각적으로 정리한 이미지입니다.

    7. 검증: 수정 후 무엇을 확인해야 할까?

    보안 그룹 수정 후에는 단순히 “붙었다”에서 끝내지 말고, 최소한 아래는 검증해보는 게 좋습니다.

    • 관리용 PC에서 `ping` 또는 `ssh`가 즉시 응답하는지
    • 인스턴스에서 외부로 `curl` 또는 `ping`이 가능한지
    • 필요한 서비스 포트만 열려 있는지
    • 너무 넓은 허용 대역이 남아 있지 않은지
    ping <FLOATING_IP>
    ssh -i ~/.ssh/mykey ubuntu@<FLOATING_IP>
    curl -I http://<FLOATING_IP>

    드디어 됐다! 이 순간이 은근 기분 좋죠. 다만 여기서 끝내면 안 됩니다. 테스트용으로 열어둔 `0.0.0.0/0` 규칙이 있다면 반드시 운영 기준에 맞게 다시 조여야 합니다.

    검증 항목 성공 기준 추가 조치
    Ping(ICMP) 응답 수신 운영 정책상 불필요하면 비활성화 검토
    SSH 22/tcp 로그인 프롬프트 도달 접근 IP 제한 적용
    웹 포트 80/443 HTTP/HTTPS 응답 로드밸런서 사용 여부 점검
    Egress 통신 패키지 저장소/외부 API 접근 가능 최소 허용 정책 재정리
    접속 성공 후 SSH와 네트워크 검증 결과를 보여주는 운영 화면 이미지

    보안 그룹 수정 후 SSH 접속 성공, 포트 응답 확인, 네트워크 상태 검증이 완료된 모습을 표현한 결과 이미지입니다.

    8. ⚠️ 운영 환경에서 특히 주의할 점

    보안 그룹 디버깅 하다 보면 급한 마음에 전체 오픈으로 먼저 뚫고 싶어집니다. 저도 장애 상황에서 그렇게 했던 적이 있습니다. 근데 이건 정말 임시 확인용으로만 쓰셔야 합니다.

    • 0.0.0.0/0 전체 허용은 테스트 후 반드시 회수합니다.
    • 여러 보안 그룹을 중복 적용했다면 실제 허용 범위를 다시 검토합니다.
    • 자동화 도구(Terraform, Heat, Ansible)와 수동 변경이 섞이면 drift(구성 불일치)가 생깁니다.
    • 운영 정책상 ICMP 차단이 정상일 수도 있으니 ping 실패만으로 장애 판단하면 안 됩니다.

    사실 실무에서는 “왜 안 되지?”보다 “어디까지는 정상인가?”를 구분하는 게 더 중요합니다. 예를 들어 ping은 막혀도 SSH는 정상일 수 있고, SSH는 되는데 애플리케이션 포트만 안 열려 있을 수도 있거든요.

    9. 정리 및 FAQ

    OpenStack Floating IP 연결 문제는 겉으로 보기엔 복잡해 보여도, 실제로는 Floating IP 연결 여부, 보안 그룹 규칙, 인스턴스 내부 네트워크와 서비스 상태 이 세 축으로 나눠 보면 꽤 빨리 풀립니다. 제가 여러 번 삽질해보니, 가장 먼저 봐야 할 건 역시 보안 그룹이었습니다. 주소는 붙었는데 정책이 막고 있는 경우가 정말 많더라고요.

    처음엔 이게 뭔가 싶었는데, 디버깅 순서만 몸에 익으면 OpenStack 네트워크 오류도 덜 무섭습니다. 다음 글에서는 `router`, `qrouter namespace`, `SNAT/DNAT` 흐름까지 조금 더 깊게 들어가보겠습니다. 이전 글 참고하셨다면 오늘 내용이 훨씬 입체적으로 보이실 거예요.

    자주 묻는 질문

    • Q. Floating IP가 붙어 있는데 ping이 안 됩니다.
      A. ICMP Ingress 규칙이 없을 수 있습니다. 다만 운영 정책상 ping 차단이 정상일 수도 있으니 SSH나 서비스 포트도 함께 확인해보세요.
    • Q. SSH만 안 됩니다.
      A. 보안 그룹의 22/tcp 규칙, 원격 IP 제한, 인스턴스 내부 `sshd` 상태를 순서대로 보시면 됩니다.
    • Q. 보안 그룹은 맞는데 여전히 안 됩니다.
      A. 인스턴스 내부 route, guest OS firewall, 라우터 연결 상태까지 내려가야 합니다.
    Floating IP 문제 해결 요약 인포그래픽과 점검 포인트 정리

    OpenStack Floating IP 연결 문제를 해결할 때 확인해야 할 핵심 체크포인트를 한 장으로 요약한 인포그래픽 이미지입니다.

  • [클라우드 보안] OpenStack 보안 그룹 취약점과 Floating IP 보안 강화 전략

    [클라우드 보안] OpenStack 보안 그룹 취약점과 Floating IP 보안 강화 전략

    [클라우드 보안] OpenStack 보안 그룹 취약점과 Floating IP 보안 강화 전략

    OpenStack 운영하다 보면 제일 많이 방심하는 지점 중 하나가 바로 보안 그룹(Security Group, 가상 방화벽 정책)과 Floating IP(플로팅 IP, 공인 IP를 인스턴스에 동적으로 붙이는 기능) 조합이에요. 저도 홈랩이랑 사내 테스트 환경에서 처음 이 구조를 만졌을 때는 “보안 그룹만 잘 걸어두면 끝 아닌가?” 싶었는데, 실제로 뜯어보면 그렇지 않더라고요. 특히 OpenStack 보안 그룹 취약점이라고 검색해서 들어오신 분들이라면, 단순히 룰 몇 개 추가하는 수준이 아니라 연결 상태(state), NAT(Network Address Translation, 네트워크 주소 변환), 정책 권한까지 같이 봐야 한다는 게 핵심이에요.

    이번 글은 2014년에 공개된 OpenStack Security Note OSSN-0020에서 다뤄진 Floating IP 분리 후 기존 NAT 연결이 살아남는 문제, 그리고 2022년 이후에도 논의된 특정 Floating IP 지정 시 외부 네트워크 게이트웨이 IP와 충돌할 수 있는 운영 리스크를 바탕으로 정리했어요. 즉, 새로운 미확인 이슈를 다루는 게 아니라, 실제로 문서화된 동작과 운영상 취약 지점을 기준으로 Floating IP 보안 전략을 재구성한 분석입니다.

    보안 그룹, Neutron 라우터, 외부 네트워크, 인스턴스 사이의 트래픽 흐름을 한눈에 보여주는 개요 이미지가 들어갈 자리입니다.

    1. 왜 이 이슈를 다시 봐야 하나요

    공식 보안 노트 OSSN-0020은 Neutron L3 agent 환경에서 Floating IP를 해제해도 이미 맺어진 연결(established connection)은 바로 끊기지 않을 수 있다고 설명해요. 쉽게 말해, 운영자는 “공인 IP를 떼었으니 외부 접근도 끝났다”고 생각했는데, 실제 세션은 계속 살아 있는 상황이 생길 수 있다는 뜻이거든요.

    이게 위험한 이유는 장애 대응이나 침해 대응 때 판단을 잘못하게 만들기 때문이에요. 예를 들어 외부에서 SSH가 붙어 있던 인스턴스에서 이상 행위가 발견돼서 Floating IP만 급하게 떼는 경우가 있잖아요. 저도 예전에 비슷하게 대응했다가, “어? 왜 세션이 안 죽지?” 하고 한참 봤던 적이 있어요. 나중에야 알았는데 보안 그룹 정책과 Floating IP 분리만으로 세션 종료가 보장되지 않는다는 게 핵심이었거든요.

    2. OpenStack 보안 그룹 취약점, 쉽게 말해 뭐가 문제인가요

    보안 그룹(Security Group)은 Neutron 포트에 붙는 가상 방화벽이에요. 기본적으로 Ingress(인그레스, 외부에서 안으로 들어오는 트래픽)는 막고, Egress(이그레스, 내부에서 바깥으로 나가는 트래픽)는 허용하는 구성이 많아요. 문서 기준으로도 보안 그룹은 포트 단위로 적용되고, 여러 그룹이 붙으면 룰은 가산적(additive)으로 합쳐진답니다.

    문제는 여기서 Floating IP가 끼어들 때 생겨요. Floating IP는 인스턴스 NIC에 공인 IP를 직접 꽂는 느낌이라기보다, 대개 Neutron 라우터의 NAT 경로를 통해 외부와 연결돼요. 그래서 정책을 바꿨다고 해서 이미 형성된 세션이 운영자가 기대하는 순간에 깔끔하게 정리되는 건 아닐 수 있다는 뜻이에요.

    정리하면 OpenStack 보안 그룹 취약점은 단순히 “룰이 뚫린다”가 아니라, 다음처럼 여러 층에서 나타나요:

    • 상태 기반 연결 잔존: Floating IP를 떼어도 기존 세션이 남을 수 있어요.
    • 과도한 권한: 특정 public IP를 사용자가 직접 지정하게 두면 외부 네트워크와 충돌 가능성이 생겨요.
    • 예외 기능 남용: allowed-address-pairs나 port_security 예외를 잘못 쓰면 정책 의미가 흐려져요.
    • 운영 착시: 콘솔에서 “분리됨”으로 보여도 실제 통신은 곧바로 끊기지 않을 수 있어요.

    3. 공식 문서 기준으로 봐야 할 핵심 포인트

    항목 확인된 사실 운영 의미
    OSSN-0020 Floating IP 분리 후 기존 NAT 연결이 남을 수 있음 침해 대응 시 FIP 분리만으로 종료 판단하면 위험
    보안 그룹 기본 동작 포트 단위 적용, 룰은 가산적 적용 인스턴스 단위로만 생각하면 누락이 생겨요
    Neutron 정책 create_floatingip:floating_ip_address 권한을 정책으로 제어 가능 특정 공인 IP 직접 지정 권한을 축소할 수 있어요
    Allowed Address Pairs 특정 조건에서 원격 그룹 기반 제한을 우회할 수 있다는 경고 존재 예외 기능은 최소화해야 해요
    정책 파일 형식 JSON 정책 파일은 deprecated, YAML 권장 하드닝 작업은 policy.yaml 기준으로 정리하는 게 안전해요

    제가 직접 문서랑 버그 토론을 다시 읽어보니, 많은 분이 “이게 CVE냐 아니냐”에만 집중하시더라고요. 근데 운영자 입장에서는 그보다 지금 내 클라우드에서 어떤 권한과 어떤 연결이 실제로 남느냐가 훨씬 중요해요. 특히 Floating IP 보안은 네트워크 설계, 테넌트 권한, 대응 절차를 같이 봐야 실수가 줄어들거든요.

    4. 실전 구현: Floating IP 보안 강화 체크리스트

    4-1. 현재 노출 범위부터 확인하기

    처음엔 화려한 정책부터 만지지 마시고, 현재 어떤 인스턴스가 외부로 열려 있는지부터 봐야 해요. 이 단계 건너뛰면 진짜 자주 꼬여요.

    openstack floating ip list
    openstack server list --long
    openstack port list --server <SERVER_NAME>
    openstack security group list
    openstack security group rule list <SECURITY_GROUP_NAME>

    여기서 확인할 건 세 가지예요:

    1. 어떤 인스턴스에 Floating IP가 붙어 있는지
    2. 해당 포트에 어떤 보안 그룹이 붙어 있는지
    3. 0.0.0.0/0 같은 광범위 Ingress 규칙이 있는지

    4-2. 보안 그룹을 최소 허용(Least Privilege)으로 다시 자르기

    SSH, HTTPS처럼 꼭 필요한 포트만 열고, 출발지 IP도 가능한 한 좁게 잡는 게 가장 실효성 있어요. 기본처럼 들리지만 체감 효과가 정말 크거든요.

    openstack security group create web-tight
    openstack security group rule create web-tight \
      --ingress --ethertype IPv4 --protocol tcp --dst-port 22 \
      --remote-ip 203.0.113.10/32
    openstack security group rule create web-tight \
      --ingress --ethertype IPv4 --protocol tcp --dst-port 443 \
      --remote-ip 0.0.0.0/0

    운영 환경이면 22번도 bastion host(배스천 호스트, 점프 서버) 대역으로 더 좁히는 걸 권해요. 저도 처음엔 귀찮아서 넓게 열었다가, 나중에 로그 뒤지면서 후회했거든요.

    Floating IP 보안 강화를 위한 OpenStack 보안 그룹 최소 허용 구성 다이어그램

    실전 구현 단계에서 보안 그룹을 최소 허용 형태로 재구성하는 흐름을 설명하는 이미지가 들어갈 자리입니다.

    4-3. 특정 Floating IP 직접 지정 권한 줄이기

    Neutron 정책 문서를 보면 create_floatingip:floating_ip_address 권한을 따로 제어할 수 있어요. 이게 중요한 이유가 있거든요. Launchpad에 2022년 등록된 논의에서는, 사용자가 특정 IP를 수동 지정할 때 외부 네트워크의 게이트웨이 IP와 같은 값을 요청할 수 있는 운영 리스크가 지적됐어요. 이건 문서상 “무조건 취약점”으로 확정된 CVE는 아니지만, 운영 사고로 번질 수 있는 위험한 설계 포인트가 맞아요.

    그래서 실무에서는 보통 임의의 공인 IP 지정 권한을 일반 사용자에게 열어두지 않는 쪽이 낫더라고요.

    # /etc/neutron/policy.yaml
    create_floatingip: "(rule:admin_only) or (role:member and project_id:%(project_id)s)"
    create_floatingip:floating_ip_address: "rule:admin_only"
    update_floatingip: "(rule:admin_only) or (role:member and project_id:%(project_id)s)"
    delete_floatingip: "(rule:admin_only) or (role:member and project_id:%(project_id)s)"

    이렇게 하면 일반 테넌트 사용자는 Floating IP 자체는 할당받되, 특정 공인 IP를 집어서 요청하는 행위는 막을 수 있어요. OpenStack 보안 강화 관점에서 생각보다 효과가 커요.

    4-4. 예외 기능 점검하기: Port Security와 Allowed Address Pairs

    여기서 많이 놓치는 게 Port Security(포트 보안)예요. 어떤 포트가 --disable-port-security 상태면 보안 그룹 기대치가 달라질 수 있거든요. 그리고 OpenStack API 문서에는 allowed-address-pairs를 특정 방식으로 쓰면, 같은 보안 그룹을 쓰는 포트들에 대해 source IP 제한 성격의 룰 우회가 가능하다는 경고도 있어요.

    openstack port show <PORT_ID> -f yaml
    openstack port list --long
    openstack port set --enable-port-security <PORT_ID>

    물론 실제 적용 전에는 LB(Load Balancer, 로드밸런서), VRRP, VIP 같은 예외 설계가 있는지 꼭 확인하셔야 해요. 이 부분 모르고 일괄 적용하면 서비스가 바로 흔들려요. 저도 HA 테스트하다가 VIP가 안 떠서 한참 봤던 기억이 있네요.

    4-5. 침해 대응 절차는 “FIP 분리”로 끝내지 않기

    이 부분이 제일 중요해요. OSSN-0020 기준으로는, Neutron L3 agent 환경에서 Floating IP를 분리해도 기존 연결이 남을 수 있거든요. 그러니까 의심 세션 차단이 목적이라면 절차를 이렇게 가져가야 한다는 뜻이에요:

    1. 인스턴스 상태 확인
    2. 필요 시 인스턴스 정지 또는 종료
    3. 그 다음 Floating IP 분리
    4. 재기동 후 필요한 보안 그룹만 재적용
    openstack server stop <SERVER_NAME>
    openstack server remove floating ip <SERVER_NAME> <FLOATING_IP>
    openstack server start <SERVER_NAME>

    환경에 따라 완전 종료 대신 격리 네트워크로 포트를 옮기는 방식도 쓰지만, 최소한 Floating IP만 떼고 끝났다 판단하는 건 위험해요.

    5. ⚠️ 실제 운영에서 자주 겪는 문제와 해결법

    • 문제 1: 보안 그룹 룰은 지웠는데 세션이 살아 있어요.
      해결: 기존 연결 추적 상태를 의심해야 해요. 긴급 대응이면 인스턴스 정지/격리까지 포함해 절차를 바꾸는 게 안전해요.
    • 문제 2: 특정 테넌트가 이상한 공인 IP를 요청해요.
      해결: create_floatingip:floating_ip_address 권한을 축소하고, 직접 지정 대신 자동 할당만 허용하세요.
    • 문제 3: 포트 보안 예외 때문에 정책 검증이 안 맞아요.
      해결: port_security_enabled, allowed_address_pairs, 보안 그룹 바인딩 상태를 같이 점검하세요.
    • 문제 4: “기본 보안 그룹이 있으니 괜찮겠지”라고 생각해요.
      해결: 기본 그룹은 출발점일 뿐이에요. 워크로드별 전용 그룹으로 분리하는 게 맞아요.

    혹시 이런 경험 있으신가요? 콘솔에는 아무 문제 없어 보이는데 실제 네트워크는 다르게 움직이는 상황이요. OpenStack 네트워킹은 특히 이런 “보이는 상태와 실제 데이터 플레인 상태의 차이”가 자주 나타나거든요.

    6. 검증: 강화 후 무엇을 확인해야 하나요

    설정하고 끝내면 안 돼요. 검증이 없으면 보안은 그냥 희망사항이거든요.

    openstack floating ip list --long
    openstack security group rule list web-tight
    openstack port show <PORT_ID> -f yaml
    openstack server show <SERVER_NAME>
    1. Floating IP가 정말 필요한 인스턴스에만 붙어 있는지 확인하세요.
    2. 보안 그룹 Ingress 규칙이 최소 범위인지 다시 봐요.
    3. Port Security가 예외 없이 켜져 있는지 점검해요.
    4. 의심 인스턴스는 FIP 제거 후 기존 세션이 끊겼는지 운영 절차로 검증하세요.

    추가로 가능하다면 FWaaS(Firewall-as-a-Service, 서비스형 방화벽)나 외부 방화벽 계층을 같이 두는 것도 좋아요. 보안 그룹만으로 모든 걸 해결하려고 하면 경계 보안이 얇아져요. 특히 클라우드 보안은 “한 겹 더”가 생각보다 큰 차이를 낸다고 느껴봤거든요.

    OpenStack 보안 그룹 취약점 대응 후 Floating IP 보안 검증 결과 대시보드

    적용 전후로 외부 노출 범위가 어떻게 줄었는지 보여주는 결과 검증 이미지가 들어갈 자리입니다.

    7. 운영 기준으로 정리하는 Floating IP 보안 원칙

    원칙 권장 여부 이유
    모든 VM에 Floating IP 부여 비권장 공격 표면이 불필요하게 넓어져요.
    특정 공인 IP 직접 지정 허용 제한 권장 외부 네트워크와 충돌할 여지를 줄일 수 있어요.
    보안 그룹 최소 허용 구성 강력 권장 실수 범위를 가장 확실하게 줄여요.
    Port Security 예외 최소화 강력 권장 정책 일관성이 깨지는 걸 막아요.
    침해 대응 시 인스턴스 정지 포함 권장 기존 연결 잔존 위험에 대응할 수 있어요.

    제가 직접 운영하면서 느낀 건, Floating IP 보안은 네트워크 팀 일만도 아니고, 클라우드 플랫폼 팀 일만도 아니라는 거예요. 권한 정책, 라우팅/NAT 동작, 테넌트 가이드, 대응 플레이북이 같이 맞물려야 드디어 안정된다는 느낌이 들어요. 드디어 됐다 싶을 때도 꼭 한 번 더 검증하는 게 좋거든요.

    8. 자주 묻는 질문과 마무리

    Q1. Floating IP를 떼면 외부 접근은 즉시 끝나는 것 아닌가요?

    그렇지 않아요. 최소한 OSSN-0020에서 설명된 Neutron L3 agent 동작 기준으로는 기존 연결이 남을 수 있거든요.

    Q2. 이 이슈가 곧바로 최신 CVE라는 뜻인가요?

    그건 아니에요. 이 글은 공식 보안 노트와 문서화된 동작, 그리고 운영상 재현 가능한 위험 지점을 분석한 글이거든요.

    Q3. 가장 먼저 적용할 한 가지는 뭔가요?

    제라면 특정 Floating IP 직접 지정 권한 제한과 0.0.0.0/0 Ingress 축소부터 하겠어요. 체감 효과가 정말 커요.

    OpenStack 보안 그룹 취약점과 Floating IP 보안 대응 전략 요약 인포그래픽

    보안 그룹 최소 허용, 정책 권한 제한, 포트 보안 점검, 대응 절차 개선을 요약한 인포그래픽이 들어갈 자리입니다.

    정리해보면, OpenStack 보안 그룹 취약점을 볼 때 핵심은 “보안 그룹 룰이 있느냐”가 아니라 “그 룰이 실제 연결 종료와 권한 통제까지 보장하느냐”예요. Floating IP는 정말 편해요. 근데 편한 만큼 공격 표면도 넓어지거든요. 이번 기회에 외부 노출 인스턴스 목록, 보안 그룹 예외, policy.yaml 권한까지 한 번에 점검해보시면 좋겠어요.

    다음 글에서는 OpenStack 보안 강화 관점에서 RBAC(Role-Based Access Control, 역할 기반 접근 제어)와 프로젝트별 네트워크 분리 전략도 이어서 다뤄볼 계획이에요. 이전 글에서 다뤘던 bastion 구조와 함께 보시면 더 이해가 잘 될 겁니다.

  • [OpenStack] OpenStack Designate 마이그레이션: 기존 DNS 연동 전략

    [OpenStack] OpenStack Designate 마이그레이션: 기존 DNS 연동 전략

    [OpenStack] OpenStack Designate 마이그레이션: 기존 DNS 연동 전략

    OpenStack Designate 마이그레이션 이야기는 생각보다 단순한 DNS 이전 작업이 아니더라고요. 특히 이미 운영 중인 기존 DNS와 엮여 있는 환경에서는 더 그렇습니다. 저도 처음엔 "Designate 서비스만 띄우고 존(zone) 넘기면 끝나는 거 아닌가?" 싶었는데, 실제로 해보니 권한 위임(delegate), 레코드 동기화, 테넌트별 운영 정책까지 한 번에 정리해야 해서 삽질 좀 했습니다 ㅎㅎ. 혹시 지금 퍼블릭 클라우드 DNS는 아니고 프라이빗 클라우드 DNS 구조를 손보려는 상황이신가요? 그렇다면 이 글이 꽤 도움이 되실 겁니다.

    이번 글에서는 OpenStack Designate 마이그레이션을 할 때 기존 BIND 같은 전통적인 DNS와 어떻게 연동 전략을 세우면 좋은지, 그리고 다운타임을 줄이면서 옮기는 흐름을 제 경험 기준으로 풀어보겠습니다. 특히 DNS 연동 전략, Designate 서비스, 클라우드 DNS 운영 관점에서 정리해볼게요.

    기존 권한 DNS와 Designate 서비스의 역할 분리, 위임 경계를 한눈에 보여주는 아키텍처 이미지입니다.

    1. 왜 OpenStack Designate 마이그레이션이 까다로운가

    쉽게 말해 Designate는 OpenStack에서 제공하는 DNSaaS(DNS as a Service, 서비스형 DNS) 역할을 합니다. 테넌트나 프로젝트 단위로 존을 관리하고, API 기반으로 레코드를 자동 생성할 수 있게 해주죠. 문제는 현실 운영 환경이 그렇게 깔끔하지 않다는 데 있습니다.

    • 기존 DNS가 이미 사내 표준으로 굳어져 있는 경우가 많습니다.
    • 외부 공개용 존과 내부 서비스용 존이 섞여 있기도 합니다.
    • 애플리케이션이 특정 네이밍 규칙에 강하게 묶여 있는 경우도 있습니다.
    • 역방향 조회(Reverse DNS, PTR 기반 역조회) 체계가 따로 굴러가는 경우도 흔합니다.

    제가 직접 해보니 마이그레이션에서 제일 중요한 건 "무엇을 Designate로 옮길지"보다 "무엇을 남길지"를 먼저 정하는 거였습니다. 모든 존을 한 번에 넘기려 하면 실패 확률이 확 올라갑니다. 특히 운영 DNS는 한 번 실수하면 장애 공지가 바로 나가거든요.

    2. Designate 서비스와 기존 DNS의 역할 분리 개념

    여기서 중요한 포인트가 있습니다. Designate를 기존 DNS의 완전한 대체재로 볼 수도 있지만, 실제 운영에서는 공존 전략이 더 현실적일 때가 많습니다.

    2-1. 쉽게 말해 이런 구조입니다

    기존 DNS는 기업 전체 표준 체계를 유지하고, Designate는 OpenStack 내부 워크로드의 민첩한 DNS 관리를 맡는 방식입니다. 예를 들어 이런 식이죠.

    구성 요소 주요 역할 운영 포인트
    기존 권한 DNS 루트 또는 상위 존 관리 조직 표준, 외부 연계, 보안 정책 유지
    OpenStack Designate 하위 존 자동화 관리 프로젝트별 셀프서비스 DNS 운영
    Backend DNS 실제 존 파일/응답 처리 BIND 또는 다른 백엔드와 연동
    Neutron 연동 인스턴스/포트 생성 시 레코드 자동화 동적 등록 정책 정리 필요

    저는 처음에 Designate가 DNS 서버 자체를 모두 대체해줄 거라고 생각했었는데, 정확히는 DNS 운영을 오케스트레이션(orchestration, 자동 조정)해주는 계층으로 이해하는 게 맞더라고요.

    2-2. 연동 전략은 보통 세 가지로 나뉩니다

    1. 하위 존 위임 방식: 기존 DNS가 상위 존을 유지하고, 특정 서브도메인만 Designate로 넘깁니다.
    2. 신규 존 전용 방식: 기존 존은 그대로 두고, 새 프로젝트부터 Designate를 사용합니다.
    3. 점진적 전환 방식: 읽기/검증 기간을 두고 순차적으로 존을 이전합니다.

    운영 리스크를 생각하면 대부분은 1번이나 3번이 무난했습니다. 저도 실제로는 하위 존 위임 방식부터 시작했어요.

    3. OpenStack Designate 마이그레이션 전 체크리스트

    마이그레이션 전에 아래 항목은 꼭 확인하시는 걸 권합니다. 이 단계에서 대충 넘어가면 나중에 TXT, MX, PTR 같은 레코드에서 꼭 터집니다.

    • 존 소유권: 어떤 팀이 어떤 존을 관리하는지 정리
    • 레코드 유형: A, AAAA, CNAME, MX, TXT, SRV, PTR 사용 현황 파악
    • TTL(Time To Live, 캐시 유지 시간): 전환 전 TTL 축소 계획 수립
    • 권한 위임: NS 레코드와 glue record 필요 여부 확인
    • 자동화 연계: IaC(Infrastructure as Code, 코드형 인프라) 또는 CI/CD 연결 여부
    • 역방향 조회: Reverse zone을 누가 관리할지 정의
    • 장애 복구: 롤백 가능한 이전 절차 문서화

    특히 TTL은 진짜 중요합니다. 저도 예전에 TTL을 충분히 낮추지 않고 작업했다가, 수정한 레코드가 바로 반영되지 않아서 괜히 애플리케이션 팀하고 서로 눈치 봤던 적이 있습니다. DNS는 설정 바꾸는 것보다 캐시가 언제 사라지느냐가 더 중요할 때가 많습니다.

    4. 실전 구현: 기존 DNS와 Designate를 연동하는 단계

    이제 실제 흐름으로 가보겠습니다. 여기서는 가장 현실적인 하위 존 위임 기반 OpenStack Designate 마이그레이션 시나리오를 기준으로 설명할게요.

    4-1. 마이그레이션 대상 존 선정

    예를 들어 기존 DNS가 corp.example.com을 운영 중이고, OpenStack 워크로드는 cloud.corp.example.com으로 분리한다고 가정해보겠습니다.

    # 현재 관리 중인 존과 레코드 확인
    dig NS corp.example.com
    dig AXFR corp.example.com @ns1.corp.example.com
    
    # 마이그레이션 대상 하위 존 계획
    # cloud.corp.example.com -> Designate 관리

    여기서 중요한 건 상위 존 전체를 옮기지 않는 겁니다. 작은 범위로 잘라서 성공 경험을 만든 다음 넓혀가야 합니다.

    4-2. Designate 존 생성

    Designate CLI나 OpenStack 통합 CLI로 존을 먼저 만듭니다.

    openstack zone create --email [email protected] cloud.corp.example.com.
    
    openstack recordset create --type A --record 10.10.20.15 \
      cloud.corp.example.com. api.cloud.corp.example.com.
    
    openstack recordset create --type CNAME --record api.cloud.corp.example.com. \
      cloud.corp.example.com. dashboard.cloud.corp.example.com.

    끝에 붙는 점(.) 때문에 처음엔 헷갈리실 수 있습니다. 저도 그랬거든요. FQDN(Fully Qualified Domain Name, 전체 도메인 이름) 처리 방식 차이 때문에 CLI 입력값이 예상과 다르게 해석될 수 있어서, 운영 표준을 미리 정해두는 게 좋습니다.

    Designate 존 생성과 레코드셋 등록 흐름을 보여주는 구성 다이어그램

    프로젝트가 Designate API를 통해 존과 레코드를 만들고, 백엔드 DNS로 반영되는 흐름을 설명하는 이미지입니다.

    4-3. 기존 DNS에서 하위 존 위임

    기존 권한 DNS에서는 상위 존에 NS 레코드를 추가해 하위 존을 Designate 네임서버로 넘깁니다.

    zone: corp.example.com
    records:
      - name: cloud.corp.example.com.
        type: NS
        value: ns1.designate.example.net.
      - name: cloud.corp.example.com.
        type: NS
        value: ns2.designate.example.net.

    BIND 스타일로 보면 대략 이런 느낌입니다.

    cloud.corp.example.com.   IN NS ns1.designate.example.net.
    cloud.corp.example.com.   IN NS ns2.designate.example.net.

    만약 위임 대상 네임서버 이름이 같은 존 내부에 있다면 glue record도 검토해야 합니다. 이 부분 놓치면 질의가 빙빙 돌다가 실패할 수 있습니다.

    4-4. 백엔드 DNS와의 동기화 확인

    Designate는 내부적으로 백엔드 DNS에 존을 반영합니다. 백엔드가 BIND든 다른 방식이든, 실제 응답 서버에 레코드가 생성됐는지 확인해야 합니다.

    openstack zone list
    openstack recordset list cloud.corp.example.com.
    
    dig NS cloud.corp.example.com
    dig A api.cloud.corp.example.com
    dig CNAME dashboard.cloud.corp.example.com

    제가 직접 해보니 CLI에서 "ACTIVE"로 보여도 실제 권한 서버 응답은 아직 반영 중인 경우가 있었습니다. 그래서 API 상태만 보지 말고 dig로 끝까지 확인하시는 게 좋습니다.

    4-5. 자동화 파이프라인 연결

    운영 환경이면 수동 등록에서 끝나면 안 됩니다. Terraform 같은 IaC로 존과 레코드셋 생성 흐름을 묶어두면 훨씬 안정적입니다.

    # 예시 흐름
    # 1) 프로젝트 생성
    # 2) 네트워크/포트 생성
    # 3) VM 배포
    # 4) Designate 레코드 등록
    # 5) 검증 스크립트 실행

    여기서 중요한 포인트! DNS 등록이 인스턴스 배포 성공보다 먼저 끝나면, 아직 서비스가 뜨기 전에 이름부터 노출될 수 있습니다. 반대로 너무 늦으면 헬스체크나 서비스 디스커버리(service discovery, 서비스 위치 탐색)와 타이밍이 어긋나죠. 그래서 저는 보통 배포 후 검증 단계에서 DNS 등록을 최종 승인하도록 설계합니다.

    5. DNS 연동 전략 비교: 한 번에 이전 vs 단계적 이전

    마이그레이션 방식은 조직 성격에 따라 달라집니다. 아래 비교표를 보시면 판단이 조금 쉬워집니다.

    전략 장점 단점 추천 상황
    한 번에 전체 이전 구조 단순화가 빠름 장애 영향 범위 큼 신규 환경, 레거시 의존도 낮음
    하위 존 위임 리스크 낮음, 검증 쉬움 일시적으로 운영 체계 이원화 대부분의 운영 환경
    신규 서비스만 전환 기존 서비스 영향 적음 표준 통일이 늦어짐 조직 조율이 어려운 경우
    병행 운영 후 절체 비교 검증 가능 운영 비용 증가 규모 크고 보수적인 조직

    제 경험상, DNS는 공격적으로 바꾸는 것보다 지루할 정도로 보수적으로 가져가는 쪽이 결과가 좋았습니다. 특히 클라우드 DNS 쪽은 자동화가 잘 되니까 오히려 너무 쉽게 건드리게 되는데, 그게 함정이더라고요.

    6. ⚠️ 실제 겪었던 문제와 트러블슈팅

    이 섹션은 진짜 실무에서 많이 부딪히는 부분입니다. 저도 처음엔 이게 뭔가 싶었는데, 결국 하나씩 확인하는 수밖에 없었습니다.

    6-1. NS 위임은 했는데 조회가 안 되는 경우

    • 상위 존 NS 반영은 됐지만 glue record가 빠졌을 수 있습니다.
    • 방화벽에서 TCP/UDP 53 포트가 막혀 있을 수 있습니다.
    • Designate 백엔드 네임서버가 외부 또는 상위 DNS에서 도달 불가일 수 있습니다.
    dig NS cloud.corp.example.com
    dig @ns1.designate.example.net api.cloud.corp.example.com
    dig +trace api.cloud.corp.example.com

    dig +trace 결과를 보면 어디서 끊기는지 감이 옵니다. 처음엔 로그만 뒤졌는데, 나중엔 trace가 훨씬 빠르더라고요.

    6-2. 레코드는 있는데 응답이 예전 값으로 나오는 경우

    • 기존 TTL이 길게 잡혀 있었을 가능성이 큽니다.
    • 중간 리졸버(resolver, 질의 대행 DNS)가 캐시를 오래 들고 있을 수 있습니다.
    • 애플리케이션 컨테이너 내부 DNS 캐시도 확인해야 합니다.

    이 문제 때문에 저는 전환 전 며칠 동안 TTL을 단계적으로 낮추는 습관이 생겼습니다. 급하게 하려면 꼭 사고가 나더라고요.

    6-3. PTR 역방향 조회가 누락되는 경우

    정방향만 보고 끝내면 안 됩니다. 메일 시스템, 보안 장비, 일부 운영 도구는 PTR을 꽤 중요하게 봅니다. Reverse DNS를 기존 DNS가 계속 맡을지, Designate 쪽으로 넘길지 미리 정해야 합니다.

    dig -x 10.10.20.15
    openstack recordset list cloud.corp.example.com.

    6-4. 프로젝트별 권한 분리가 애매한 경우

    Designate의 장점은 프로젝트 기반 분리인데, 운영 표준이 없으면 오히려 혼란이 생깁니다. 예를 들어 어떤 프로젝트는 직접 A 레코드를 만들고, 어떤 팀은 CNAME만 쓰게 하면 나중에 정책 충돌이 납니다.

    그래서 저는 보통 이렇게 정리합니다.

    • 플랫폼 팀: 상위 존, 위임 정책, 공통 레코드 관리
    • 서비스 팀: 하위 존 내부 레코드 관리
    • 보안 팀: 외부 공개 존 검토 및 감사

    역할이 분명해지면 장애 분석도 훨씬 빨라집니다.

    DNS 위임 오류, TTL 캐시 문제, 역방향 조회 누락 등을 점검하는 트러블슈팅 대시보드 화면

    질의 경로 추적, 캐시 상태, 레코드 일치 여부를 점검하는 검증용 화면을 표현한 이미지입니다.

    7. 검증과 결과 확인: 마이그레이션이 끝났는지 판단하는 기준

    마이그레이션이 끝났다고 말하려면 단순히 레코드가 생성된 것만으로는 부족합니다. 아래 기준으로 확인해보시면 됩니다.

    1. 권한 위임 확인: 상위 존에서 하위 존 NS가 올바르게 보이는지
    2. 직접 질의 확인: Designate 백엔드 네임서버가 기대한 응답을 주는지
    3. 재귀 조회 확인: 일반 클라이언트 환경에서도 새 레코드가 조회되는지
    4. 애플리케이션 확인: 실제 서비스 연결이 문제없는지
    5. 로그 확인: 오류 응답이나 SERVFAIL 증가가 없는지
    # 권한 서버 직접 확인
    dig @ns1.designate.example.net api.cloud.corp.example.com
    
    # 일반 경로 확인
    dig api.cloud.corp.example.com
    
    # 역방향 확인
    dig -x 10.10.20.15
    
    # 추적 확인
    dig +trace api.cloud.corp.example.com

    여기까지 정상이라면 거의 다 온 겁니다. 저는 여기에 더해 서비스 배포 파이프라인에서 헬스체크까지 붙여놓는 편입니다. DNS가 살아 있어도 실제 앱 엔드포인트가 아직 준비 안 됐으면 결국 사용자 입장에선 장애니까요.

    운영 후에는 이런 성과가 체감됩니다.

    • 신규 서비스 DNS 발급 속도가 빨라집니다. ✅
    • 플랫폼 팀이 수동 등록 요청 처리하느라 끌려다니는 시간이 줄어듭니다. ✅
    • 프로젝트 단위 셀프서비스가 가능해집니다. 🎉
    • 클라우드 DNS 운영 표준을 문서화하기 쉬워집니다. 💡

    8. 정리: OpenStack Designate 마이그레이션은 기술보다 경계 설계가 먼저입니다

    OpenStack Designate 마이그레이션은 단순히 DNS 제품을 바꾸는 작업이 아니라, 누가 어떤 존을 어떤 책임으로 운영할지를 다시 설계하는 과정이었습니다. 저도 처음엔 기능 중심으로만 봤었는데, 실제로 써보니까 성공 여부는 권한 위임 경계와 운영 정책에서 갈리더라고요.

    정리해보면 이렇습니다.

    • 처음부터 전체 이전하지 말고 하위 존부터 시작합니다.
    • TTL, NS 위임, reverse zone을 반드시 사전에 정리합니다.
    • CLI 상태만 믿지 말고 dig 기반 검증을 끝까지 합니다.
    • 자동화는 빠를수록 좋지만, 승인 지점은 신중하게 둡니다.

    혹시 지금 Designate 서비스 도입을 검토 중이시라면, 다음 글에서는 Neutron 연동과 인스턴스 생성 시 DNS 자동 등록 흐름도 이어서 다뤄볼 예정입니다. 이전 글에서 다뤘던 네트워크 분리 전략과 함께 보시면 더 이해가 잘 되실 거예요.

    기존 DNS와 Designate 운영 방식을 비교한 요약 인포그래픽

    한 번에 이전, 하위 존 위임, 병행 운영 전략의 차이를 요약해서 보여주는 마무리용 인포그래픽입니다.

    9. 자주 묻는 질문 FAQ

    Q1. Designate로 모든 DNS를 옮겨야 하나요?

    아닙니다. 실제로는 기존 DNS와 공존하는 구조가 더 현실적일 때가 많습니다. 특히 조직 공통 존은 그대로 두고, OpenStack 워크로드용 하위 존만 넘기는 방식이 안전합니다.

    Q2. 기존 BIND를 꼭 버려야 하나요?

    그럴 필요 없습니다. Designate는 운영 자동화 계층으로 보고, 기존 권한 DNS 또는 백엔드 DNS와 함께 쓰는 접근도 충분히 실무적입니다.

    Q3. 가장 먼저 줄여야 할 리스크는 무엇인가요?

    저는 TTL과 위임 구조라고 봅니다. 레코드 자체보다 캐시와 권한 위임 오류가 실제 장애로 이어지는 경우가 더 많았습니다.

    Q4. OpenStack Designate 마이그레이션에서 가장 추천하는 시작점은?

    신규 서비스용 하위 존 하나를 잘라서 위임해보는 겁니다. 작게 시작해서 검증 패턴을 만든 다음 넓히는 게 제일 덜 아픕니다.

  • [OpenStack] OpenStack Placement 벤치마크: 대규모 자원 할당 성능 분석

    [OpenStack] OpenStack Placement 벤치마크: 대규모 자원 할당 성능 분석

    [OpenStack] OpenStack Placement 벤치마크: 대규모 자원 할당 성능 분석

    OpenStack Placement 벤치마크를 처음 제대로 돌려본 건, 스케줄러가 이상하게 느려지는 순간 때문이었습니다. VM 몇 대 수준에서는 티가 안 나는데, 컴퓨트 노드 수가 늘고 자원 요청(Resource Request)이 복잡해지면 갑자기 API 응답이 늘어지고, 결국 사용자는 “왜 인스턴스 생성이 이렇게 오래 걸리죠?”라고 묻게 되거든요. 저도 처음엔 Nova Scheduler(노바 스케줄러) 쪽만 의심했었는데, 실제로 뜯어보니 Placement 서비스가 병목으로 보이는 구간이 있더라고요. 그래서 이번 글에서는 OpenStack Placement 벤치마크를 어떤 식으로 설계하고, 무엇을 봐야 하며, 결과를 어떻게 해석해야 하는지 제 경험 기준으로 정리해보겠습니다.

    특히 자원 할당 성능, OpenStack 인프라, Placement 서비스를 운영 관점에서 보고 싶은 분들께 도움이 될 겁니다. 숫자를 지어내는 식의 벤치마크는 의미가 없어서, 이번 글은 재현 가능한 테스트 절차와 해석 포인트 위주로 풀어보겠습니다. 혹시 운영 환경에서 “CPU는 남는데 스케줄링이 느리다” 같은 경험 있으신가요? 여기서 중요한 포인트가 바로 Placement입니다.

    Placement 서비스, Nova Scheduler, 데이터베이스, 컴퓨트 노드가 연결된 전체 벤치마크 아키텍처 개요입니다.

    1. 왜 OpenStack Placement 벤치마크가 중요한가

    쉽게 말해 Placement는 “이 요청을 만족할 수 있는 자원이 어디에 있나”를 빠르게 찾는 역할을 합니다. 예전에는 자원 조회 로직이 여러 군데 흩어져 있어서 복잡했는데, Placement가 그 책임을 상당 부분 분리해줬죠. 문제는 조회 대상이 커지면, 즉 Resource Provider(리소스 프로바이더, 자원 제공 주체) 수가 많아지고 Traits(트레이트, 자원 특성)나 Aggregate(애그리게이트, 그룹화 정보) 조건이 겹치면 성능 특성이 확 달라진다는 게 핵심이더라고요.

    제가 직접 해보니 단순 조회는 꽤 잘 버티는데, 아래 조건이 섞이면 체감 성능이 달라졌습니다.

    • 컴퓨트 노드가 많아져 Resource Provider 수가 크게 증가한 경우
    • NUMA, PCI passthrough, SR-IOV 같은 추가 조건이 붙는 경우
    • 동시 API 요청이 몰리는 경우
    • Inventory(인벤토리, 제공 가능한 자원량)와 Allocation(할당 상태) 갱신이 계속되는 경우

    운영에서는 이게 곧 사용자 경험으로 이어집니다. 인스턴스 생성 지연, 오토스케일 지연, 배치 작업 실패로 연결될 수 있거든요. 그래서 OpenStack Placement 벤치마크는 단순한 성능 놀이가 아니라, 실제 운영 여유치(headroom)를 확인하는 절차라고 보는 게 맞습니다.

    2. Placement 서비스 핵심 개념 정리

    저도 처음엔 용어 때문에 좀 헷갈렸는데, 이 부분만 정리되면 뒤가 훨씬 쉬워집니다.

    2-1. Resource Provider와 Inventory

    Resource Provider는 CPU, RAM, DISK 같은 자원을 제공하는 대상입니다. 보통 컴퓨트 노드가 대표적이지만, 구조상 더 세분화된 단위도 가능합니다. Inventory는 “이 노드가 얼마나 제공 가능한가”에 대한 정보고, Allocation은 “그 중 얼마가 이미 사용 중인가”에 가깝습니다.

    2-2. Trait와 Aggregate

    Trait는 특성 태그라고 생각하면 편합니다. 예를 들어 SSD, 특정 CPU 기능, 가상화 확장 여부 같은 성격을 표현할 때 씁니다. Aggregate는 여러 Resource Provider를 묶는 논리 그룹입니다. Availability Zone과 비슷하게 느껴질 수 있는데 쓰임은 조금 다르죠.

    2-3. Allocation Candidate

    벤치마크에서 자주 보게 되는 개념입니다. Allocation Candidate(할당 후보)는 요청 조건을 만족하는 자원 조합 후보인데, 결국 스케줄링 전에 “가능한 곳 리스트”를 만든다고 보면 됩니다. 이 후보 계산이 커질수록 Placement 서비스의 응답 시간도 영향을 받습니다.

    개념 쉽게 말한 의미 성능에 미치는 영향
    Resource Provider 자원을 제공하는 대상 대상이 많아질수록 조회 범위 증가
    Inventory 제공 가능한 총 자원 갱신 빈도와 조회 비용에 영향
    Allocation 이미 할당된 자원 상태 동시성 충돌과 상태 일관성에 영향
    Trait 자원 특성 태그 필터 조건 증가로 쿼리 복잡도 상승 가능
    Aggregate 리소스 그룹 묶음 후보군 축소 또는 조인 비용 증가 가능
    Allocation Candidate 요청 만족 후보 세트 대규모 환경에서 핵심 병목 포인트

    3. 벤치마크 설계: 뭘 측정해야 의미가 있나

    여기서 제일 많이 하는 실수가, 단순히 초당 요청 수만 보는 겁니다. 물론 Requests Per Second(RPS, 초당 요청 수)도 중요하지만, 운영 관점에서는 그것만 보면 안 되더라고요. 저는 보통 아래 항목을 함께 봅니다.

    1. 응답 시간 분포: 평균보다 P95, P99 같은 꼬리 지연(tail latency)이 더 중요합니다.
    2. 동시 요청 처리량: 단일 요청보다 burst 상황을 봐야 합니다.
    3. 오류율: 5xx 응답, 타임아웃, 충돌 응답 여부를 확인합니다.
    4. DB 부하: Placement 자체보다 백엔드 DB가 먼저 한계에 닿는 경우가 많습니다.
    5. 스케줄링 체감: Placement API만 빠르고 실제 인스턴스 생성은 느릴 수도 있습니다.

    벤치마크 시나리오도 분리하는 게 좋습니다. 제가 추천하는 기준은 이렇습니다.

    • 단순 조회 시나리오: traits 없이 기본 자원만 요청
    • 조건부 조회 시나리오: trait, aggregate, resource class 조건 추가
    • 대규모 후보 시나리오: 후보군이 매우 많도록 구성
    • 갱신 혼합 시나리오: allocation/inventory 업데이트와 조회를 동시에 수행

    사실 운영 장애는 마지막 시나리오에서 많이 튀어나옵니다. 읽기만 있는 테스트는 예쁘게 나오는데, 쓰기와 섞는 순간 이야기가 달라지거든요.

    OpenStack Placement 벤치마크의 리소스 프로바이더 토폴로지 이미지

    리소스 프로바이더 토폴로지와 요청 흐름, 후보 계산 경로를 보여주는 구성 다이어그램입니다.

    4. 홈랩 기준 실전 벤치마크 환경 구성

    제 홈랩에서도 완전히 똑같은 운영 환경을 만들 수는 없었지만, 패턴을 확인하는 데는 충분했습니다. 중요한 건 절대적인 숫자보다 병목이 어디서 시작되는지를 보는 겁니다.

    4-1. 테스트 전 체크리스트

    • Placement API 엔드포인트 접근 가능 여부 확인
    • 테스트용 프로젝트와 인증 토큰 준비
    • 백엔드 DB 상태 확인
    • 벤치마크 중 로그 레벨을 너무 과하게 올리지 않기
    • 테스트 시간대 분리: 운영 트래픽과 겹치지 않게

    4-2. 기본 확인 명령

    source admin-openrc.sh
    openstack endpoint list --service placement
    openstack resource provider list
    openstack --os-placement-api-version 1.0 resource provider list
    

    CLI가 환경마다 조금 다를 수 있어서, 저는 먼저 엔드포인트와 인증이 정상인지부터 확인합니다. 여기서 막히면 뒤 테스트는 전부 헛수고가 되더라고요. 삽질 좀 했습니다 ㅎㅎ

    4-3. API 직접 조회 예시

    export TOKEN=$(openstack token issue -f value -c id)
    export PLACEMENT_URL=$(openstack endpoint list --service placement -f value -c URL | head -n 1)
    
    curl -s -H "X-Auth-Token: ${TOKEN}" \
         -H "OpenStack-API-Version: placement 1.0" \
         "${PLACEMENT_URL}/resource_providers" | jq .
    

    이렇게 직접 보면 중간 계층 없이 Placement 서비스의 응답만 확인하기 좋습니다. 벤치마크는 가능하면 레이어를 나눠서 보세요. Nova까지 한 번에 보면 편하긴 한데, 원인 분리가 어려워집니다.

    4-4. 간단한 부하 스크립트 예시

    제가 자주 쓰는 방식은 Python(파이썬)으로 요청 수, 동시성, 헤더를 명시하는 간단한 스크립트를 먼저 만드는 겁니다. 전문 부하도구를 써도 되지만, 초기에 API 동작 확인은 직접 짠 스크립트가 오히려 빠를 때가 많습니다.

    import os
    import time
    import statistics
    import concurrent.futures
    import requests
    
    TOKEN = os.environ["TOKEN"]
    PLACEMENT_URL = os.environ["PLACEMENT_URL"].rstrip("/")
    HEADERS = {
        "X-Auth-Token": TOKEN,
        "OpenStack-API-Version": "placement 1.0",
    }
    URL = f"{PLACEMENT_URL}/allocation_candidates?resources=VCPU:2,MEMORY_MB:4096,DISK_GB:20"
    
    
    def fetch():
        start = time.perf_counter()
        r = requests.get(URL, headers=HEADERS, timeout=10)
        elapsed = time.perf_counter() - start
        return r.status_code, elapsed
    
    
    def run(total=100, workers=10):
        results = []
        with concurrent.futures.ThreadPoolExecutor(max_workers=workers) as ex:
            futures = [ex.submit(fetch) for _ in range(total)]
            for f in concurrent.futures.as_completed(futures):
                results.append(f.result())
    
        latencies = [elapsed for status, elapsed in results if status == 200]
        errors = [status for status, _ in results if status != 200]
    
        print("total=", len(results))
        print("success=", len(latencies))
        print("errors=", len(errors))
        if latencies:
            print("avg=", round(statistics.mean(latencies), 4))
            print("max=", round(max(latencies), 4))
    
    
    if __name__ == "__main__":
        run(total=300, workers=30)
    

    이 스크립트는 아주 기본형입니다. 운영에서 쓰려면 요청 경로를 더 나누고, P95/P99 계산도 붙이고, 결과를 파일로 남기면 좋습니다.

    5. 단계별 OpenStack Placement 벤치마크 진행 방법

    이제 실제 진행 순서입니다. 여기서는 벤치마크 결과를 왜곡하지 않도록, 시나리오를 점진적으로 키우는 방식이 좋습니다.

    1. 기준선(Baseline) 측정
      아무 조건 없는 조회부터 시작합니다. Resource Provider 수가 적은 상태에서 먼저 응답 시간을 봅니다.
    2. 조건 추가
      Trait와 Aggregate 조건을 하나씩 늘려봅니다. 어떤 조건이 급격한 지연을 만드는지 확인합니다.
    3. 동시성 증가
      workers 값을 점진적으로 올립니다. 갑자기 10배로 올리면 원인 파악이 힘듭니다.
    4. 데이터 규모 증가
      리소스 프로바이더와 할당 데이터를 늘린 상태에서 다시 측정합니다.
    5. 읽기/쓰기 혼합
      조회만이 아니라 할당 갱신 요청과 함께 테스트합니다.

    여기서 중요한 포인트! 한 번에 하나씩만 바꾸세요. 저도 예전에 노드 수, 동시성, 조건을 한꺼번에 바꿨다가 뭐가 원인인지 한참 못 찾았거든요.

    5-1. allocation_candidates 요청 예시

    curl -s -H "X-Auth-Token: ${TOKEN}" \
         -H "OpenStack-API-Version: placement 1.0" \
         "${PLACEMENT_URL}/allocation_candidates?resources=VCPU:4,MEMORY_MB:8192,DISK_GB:40" | jq .
    

    5-2. trait 조건 포함 예시

    curl -s -H "X-Auth-Token: ${TOKEN}" \
         -H "OpenStack-API-Version: placement 1.0" \
         "${PLACEMENT_URL}/allocation_candidates?resources=VCPU:4,MEMORY_MB:8192&required=CUSTOM_SSD" | jq .
    

    5-3. 결과 저장 예시

    for w in 1 5 10 20 30; do
      echo "workers=${w}" >> placement-bench.txt
      python3 placement_bench.py --workers ${w} --total 200 >> placement-bench.txt
      sleep 2
    done
    

    실제로 써보니까 중간중간 쿨다운을 조금 넣는 게 결과 해석에 편했습니다. 연속 폭격만 하면 캐시, DB 커넥션, 시스템 부하가 뒤섞여서 패턴이 흐려질 수 있거든요.

    OpenStack Placement 벤치마크 실행 과정 이미지

    터미널에서 Placement API 벤치마크를 실행하는 장면과 요청 흐름을 시각화한 이미지입니다.

    6. ⚠️ 실제로 겪은 문제와 트러블슈팅

    이 섹션은 진짜 중요합니다. 벤치마크는 돌렸는데 결과를 믿을 수 없는 경우가 생각보다 많거든요.

    6-1. 인증 토큰 만료

    장시간 테스트에서 은근 자주 나옵니다. 처음엔 성능 저하인 줄 알았는데, 알고 보니 중간부터 401이 섞이더라고요. 그래서 저는 토큰 재발급 루틴을 넣거나, 테스트 시간을 짧게 끊어서 돌립니다.

    6-2. DB가 먼저 병목이 되는 경우

    Placement 서비스만 보고 있으면 놓치기 쉽습니다. API 프로세스 CPU는 여유 있는데 응답 시간이 늘어난다면, DB 슬로우 쿼리(slow query)를 꼭 보셔야 합니다. 특히 후보 계산 관련 조회가 커지는 구간에서 차이가 보일 수 있습니다.

    6-3. 로그 레벨 때문에 성능이 왜곡되는 경우

    디버그 로그를 켜고 벤치마크 돌리면, 그 자체가 부하가 됩니다. 저도 “왜 오늘따라 이렇게 느리지?” 했다가 로그 설정부터 다시 봤던 적이 있습니다. 디버깅과 성능 측정은 분리하는 게 맞습니다.

    6-4. 캐시 효과로 첫 번째와 두 번째 결과가 다른 경우

    이건 꽤 흔합니다. 첫 실행과 반복 실행 결과를 구분해서 기록해두세요. 워밍업(warm-up) 구간을 따로 두는 이유가 있습니다.

    증상 의심 포인트 확인 방법
    응답 시간 급증 DB 병목 DB 모니터링, 슬로우 쿼리 로그 확인
    간헐적 실패 토큰 만료 또는 타임아웃 HTTP 상태 코드 분리 기록
    반복할수록 빨라짐 캐시 또는 워밍업 효과 초기 구간과 본 측정 구간 분리
    노드 수 증가 후 급격히 느려짐 후보 계산 복잡도 증가 조건별 시나리오 재실행

    7. 검증과 결과 해석: 숫자보다 패턴을 보세요

    벤치마크 결과를 볼 때 저는 보통 세 가지 질문을 던집니다.

    1. 동시성이 올라갈 때 지연 시간이 선형적으로 늘어나는가?
    2. 특정 조건(trait, aggregate)에서만 갑자기 악화되는가?
    3. Placement API 응답 시간과 실제 인스턴스 생성 지연이 같이 움직이는가?

    예를 들어 평균 응답 시간은 괜찮아 보여도, P99가 튄다면 운영 체감은 이미 나빠졌을 수 있습니다. 반대로 수치가 조금 높아도 일관되게 유지되면 운영상 더 다루기 쉽습니다. 결국 중요한 건 안정성 있는 자원 할당 성능입니다.

    제가 직접 해보니 결과 해석은 아래 순서가 제일 실용적이었습니다.

    • API 응답 시간 분포 확인
    • 오류율 확인
    • DB와 서비스 프로세스 리소스 사용량 확인
    • 실제 스케줄링 체감과 비교
    grep -E "avg|max|errors|workers" placement-bench.txt
    

    가능하다면 결과는 시각화해두세요. 작은 차이도 그래프로 보면 패턴이 보입니다. 특히 worker 수 증가에 따른 지연 변화는 선 그래프로 보면 바로 감이 오더라고요.

    OpenStack Placement 벤치마크 결과 대시보드 이미지

    응답 시간, 오류율, 동시성 변화가 한눈에 보이는 벤치마크 결과 대시보드 이미지입니다.

    8. 정리와 다음 단계

    OpenStack Placement 벤치마크는 단순히 API를 두드려보는 테스트가 아닙니다. 대규모 OpenStack 인프라에서 실제 스케줄링 여유치를 확인하고, 병목이 Placement 서비스 자체인지, DB인지, 아니면 상위 스케줄링 로직인지 구분하는 과정에 가깝습니다. 처음엔 좀 복잡해 보여도, 시나리오를 잘게 나누고 한 번에 하나씩 바꾸면 훨씬 명확해집니다.

    이번 글의 핵심만 다시 묶어보면 이렇습니다.

    • 평균값보다 분포를 보세요. 특히 꼬리 지연이 중요합니다.
    • 조회와 갱신을 분리해서도 보고, 섞어서도 보세요.
    • Placement만 보지 말고 DB와 실제 스케줄링 체감도 함께 보세요.
    • 결과 숫자보다 병목이 시작되는 패턴을 찾으세요.

    다음 글에서는 Nova Scheduler(노바 스케줄러)와 Placement 서비스의 상호작용을 조금 더 깊게 다뤄볼 예정입니다. 이전 글에서 다뤘던 API 응답 시간 분석 방법이 있다면 같이 보셔도 흐름이 잘 연결될 겁니다. 혹시 지금 운영 중인 환경에서 Placement 성능이 의심된다면, 오늘 소개한 최소 구성 벤치마크부터 먼저 돌려보세요. 생각보다 빨리 단서가 나옵니다. 드디어 됐다! 하는 순간이 오더라고요 🎉

    벤치마크 시나리오별 관찰 포인트와 튜닝 우선순위를 요약한 인포그래픽입니다.

    FAQ: 자주 묻는 질문

    Q1. Placement API만 빠르면 스케줄링도 무조건 빠른가요?

    그건 아닙니다. Placement는 중요한 구성요소지만 전부는 아니거든요. Nova Scheduler, MQ, DB, 하이퍼바이저 상태까지 같이 봐야 합니다.

    Q2. 작은 환경에서도 벤치마크가 의미가 있나요?

    네, 있습니다. 절대 수치보다 패턴을 보는 데 의미가 큽니다. 홈랩에서도 병목 시작 지점을 찾는 연습이 충분히 됩니다.

    Q3. 어느 수치가 정상인가요?

    환경마다 다르기 때문에 단일 기준을 말하기는 어렵습니다. 그래서 더더욱 동일 환경에서 조건별 상대 비교가 중요합니다.

    Q4. 튜닝은 어디부터 시작하면 될까요?

    제 경험상 무작정 서비스 파라미터부터 건드리기보다, 요청 패턴 분리, DB 관찰, 후보 계산이 무거운 조건 파악부터 하는 게 훨씬 효율적이었습니다.