본문으로 건너뛰기

07 · OpenStack on Kubernetes — 컨트롤 플레인은 파드로, VM은 여전히 베어메탈의 KVM으로

OpenStack on Kubernetes에서 Kubernetes가 배포하는 대상은 VM을 관리하는 OpenStack 서비스입니다. OpenStack-Helm에서는 API·scheduler·conductor와 MariaDB·RabbitMQ가 파드로 실행되고, VM은 컴퓨트 노드의 libvirt와 QEMU/KVM이 실행합니다. VM 하나를 호스트의 QEMU 프로세스 하나에 대응시킨 설명은 libvirt 문서를 바탕으로 한 이 글의 정리입니다.

이 구성이 모두 같은 배포 방식을 뜻하지는 않습니다. OpenStack-Helm은 컴퓨트 노드의 nova-compute와 libvirt도 파드로 배포합니다. RHOSO(Red Hat OpenStack Services on OpenShift)는 업스트림 문서 기준으로 컨트롤 플레인만 Kubernetes에 두고 컴퓨트 노드는 별도로 관리합니다. RHOSO 제품 문서 본문은 확인하지 못했습니다.

조사 기준일은 2026-10-05이며 Nova 문서는 latest(34.1.0.dev22), OpenStack-Helm 소스는 GitHub 미러의 master를 읽었습니다. ✓는 원문 직접 확인, Ⓥ는 벤더·프로젝트 주장, Ⓑ는 벤치마크 수치, ≈는 눈대중·역산, Σ는 여러 사실을 이은 종합 추론, ?는 미확인입니다. 각 절의 접힌 표에 출처와 세부 조건을 두었으며, 소스에서 읽은 설계 의도와 실제 동작을 시험한 결과를 구분합니다. KubeVirt 자체의 구성은 04 KubeVirt에서 다룹니다.

1. 무엇이 파드가 되고 무엇이 호스트에 남는가

OpenStack-Helm은 VM 관리 서비스를 파드로 배포하지만 VM 자체를 Kubernetes 객체로 만들지는 않습니다. 컴퓨트 노드에서 하이퍼바이저를 조작하는 nova-compute와 QEMU를 생성·감독하는 libvirtd도 파드에 포함됩니다. libvirt는 호스트에서 QEMU 바이너리를 실행합니다.

OpenStack-Helm형 배치입니다. 위쪽 컨트롤 서비스는 Kubernetes 위의 파드이고, 아래쪽 컴퓨트 노드에서는 nova-compute와 libvirt가 DaemonSet 파드로 돌지만 VM 자체는 QEMU 프로세스입니다. 컴퓨트 노드의 QEMU는 파드 cgroup 밖으로 빼도록 되어 있어 kubelet이 관리하는 대상이 아닙니다 Σ.
도식 텍스트
  • Kubernetes 위의 컨트롤 서비스 파드
  • 베어메탈 컴퓨트 노드
  • nova-api — Deployment
  • RabbitMQ — StatefulSet
  • scheduler · conductor — Deployment
  • MariaDB — StatefulSet
  • kubelet — 컴퓨트 노드 라벨
  • nova-compute — DaemonSet 파드
  • libvirtd — DaemonSet 파드 · privileged
  • QEMU 프로세스 = VM — /dev/kvm · 파드 cgroup 밖
  • RPC
  • RPC
  • 기록
  • RPC
  • libvirt
  • 실행
  • 파드 기동
컴포넌트하는 일형태(OpenStack-Helm 소스)
nova-apiREST 요청을 받아 큐로 넘김Deployment
nova-scheduler인스턴스를 놓을 호스트 선택Deployment(StatefulSet 템플릿도 있음)
nova-conductor생성·리사이즈처럼 조율이 필요한 요청 처리, 컴퓨트 노드 대신 DB 접근Deployment(StatefulSet 템플릿도 있음)
Placement호스트별 자원 재고와 사용량 추적별도 차트(placement)
MariaDB컨트롤 서비스의 DB. 기본 3개 복제본StatefulSet
RabbitMQ서비스 사이 RPC 메시지 큐. 기본 2개 복제본StatefulSet
nova-compute컴퓨트 노드마다 하나. 큐에서 요청을 받아 하이퍼바이저를 조작DaemonSet. hostNetwork·hostPID·hostIPC·privileged
libvirtdQEMU 프로세스의 생성·감독DaemonSet. hostNetwork·hostPID·hostIPC·privileged
Open vSwitch, OVN controller, neutron OVS agentVM 네트워크 데이터 경로DaemonSet. hostNetwork
QEMU/KVM 프로세스VM 하나의 CPU·메모리 실행호스트 프로세스

API·scheduler·conductor는 DB와 큐를 이용하고 RPC(다른 프로세스의 기능을 호출하는 방식)로 통신합니다. 이 특성상 컨트롤 서비스를 Deployment나 StatefulSet으로 다루기 쉬울 것으로 해석했습니다. 컴퓨트 노드에서는 kubelet이 nova-compute와 libvirt 파드를 띄우지만, 시작 스크립트에는 QEMU의 수명을 파드와 분리하려는 설정이 있습니다. 파드 재시작의 영향과 이 해석의 한계는 4절에서 다룹니다.

컴퓨트 서비스 파드는 호스트 자원에 접근해야 합니다. DaemonSet은 대상 노드마다 파드를 띄우고, hostNetwork는 노드의 네트워크 네임스페이스를 쓰게 하며, hostPID는 노드의 프로세스를 파드에서 볼 수 있게 합니다. libvirt 문서에 따르면 KVM을 쓰려면 /dev/kvm도 필요합니다.

nova-compute가 DB에 직접 접근하지 않고 conductor를 거치는 이유는 업그레이드 때의 통신 호환성입니다. Nova 문서는 DB 접근을 conductor가 맡으면 컨트롤 플레인을 먼저 업그레이드해도 이전 릴리스의 컴퓨트 노드와 통신할 수 있다고 설명합니다.

근거와 측정 조건
주장수치·조건출처근거
nova-api의 역할과 배포 형태REST 요청을 받아 큐로 넘김. DeploymentNova 문서(역할), OpenStack-Helm 소스(배포 형태·기본값)✓
nova-scheduler의 역할과 배포 형태인스턴스를 놓을 호스트 선택. Deployment이며 StatefulSet 템플릿도 있음Nova 문서(역할), OpenStack-Helm 소스(배포 형태·기본값)✓
nova-conductor의 역할과 배포 형태생성·리사이즈처럼 조율이 필요한 요청 처리, 컴퓨트 노드 대신 DB 접근. Deployment이며 StatefulSet 템플릿도 있음Nova 문서(역할), OpenStack-Helm 소스(배포 형태·기본값)✓
Placement의 역할과 배포 형태호스트별 자원 재고와 사용량 추적. 별도 차트(placement)Nova 문서(역할), OpenStack-Helm 소스(배포 형태·기본값)✓
MariaDB의 역할과 기본값컨트롤 서비스의 DB. StatefulSet, 기본 3개 복제본Nova 문서(역할), OpenStack-Helm 소스(배포 형태·기본값)✓
RabbitMQ의 역할과 기본값서비스 사이 RPC 메시지 큐. StatefulSet, 기본 2개 복제본Nova 문서(역할), OpenStack-Helm 소스(배포 형태·기본값)✓
nova-compute의 역할과 배포 형태컴퓨트 노드마다 하나. 큐에서 요청을 받아 하이퍼바이저를 조작. DaemonSet, hostNetwork·hostPID·hostIPC·privilegedNova 문서(역할), OpenStack-Helm 소스(DaemonSet·호스트 설정)✓
libvirtd의 역할과 배포 형태QEMU 프로세스의 생성·감독. DaemonSet, hostNetwork·hostPID·hostIPC·privilegedNova 문서(역할), OpenStack-Helm 소스(DaemonSet·호스트 설정)✓
VM 네트워크 데이터 경로의 배포 형태Open vSwitch, OVN controller, neutron OVS agent. DaemonSet, hostNetworkOpenStack-Helm 소스✓
QEMU/KVM 프로세스와 VM의 관계VM 하나의 CPU·메모리 실행을 담당하는 호스트 프로세스라는 정리libvirt 문서✓ ≈
libvirt의 QEMU 실행 방식과 KVM 사용 조건QEMU 바이너리 하나를 실행하는 방식. KVM을 쓰려면 /dev/kvm 필요libvirt 문서✓

2. VM 하나가 만들어지는 경로

VM 생성 요청은 컨트롤 서비스 파드 사이를 큐로 오가다가 선택된 컴퓨트 노드의 nova-compute에 도착합니다. 아래 순서는 Nova 문서에 나온 개별 컴포넌트의 역할을 연결한 종합이며, 이 요청 경로에는 Kubernetes API가 등장하지 않습니다.

VM 생성 요청이 지나는 순서입니다. 이 순서에 Kubernetes API는 한 번도 나오지 않습니다. 여러 문서의 컴포넌트 정의를 이은 종합입니다 Σ.
도식 텍스트
  • nova-api
  • nova-conductor
  • scheduler · Placement
  • nova-compute
  • libvirtd · QEMU
  1. REST 요청 수신 · 인스턴스를 DB에 기록
  2. 1. 생성 요청 (큐)
  3. 2. 호스트 선택 요청
  4. Placement로 후보 조회 · 후보 중 호스트 선택
  5. 3. 선택한 호스트
  6. 4. 빌드 요청 (큐)
  7. 5. 도메인 정의·시작
  8. QEMU 프로세스 실행 · = VM
  9. 6. 상태 갱신 (DB는 conductor 경유)

Placement는 호스트의 자원 재고와 사용량을 기록해 후보를 제공하고, scheduler가 인스턴스를 놓을 호스트를 고릅니다. conductor는 생성·리사이즈를 조율하며 컴퓨트 노드 대신 DB에 접근합니다.

요청을 받은 nova-compute는 하이퍼바이저가 있는 노드에서 동작합니다. Nova 문서의 기본 구성에서는 libvirt를 거쳐 KVM·QEMU를 사용합니다. 문서는 conductor를 nova-compute와 같은 노드에 두지 않도록 안내합니다.

컴퓨트 노드를 나누는 단위도 Nova가 관리합니다.

단위누가 보는가하는 일
cell운영자컴퓨트 노드를 샤딩. 셀마다 DB·큐·conductor가 따로 있음
availability zone(AZ)사용자사용자가 고르는 논리 구역. aggregate에 메타데이터를 붙여 정의
host aggregate운영자임의의 특성으로 호스트를 나눔. 운영자가 flavor와 연결

Nova 문서는 AZ 자체가 장애 도메인을 뜻하지는 않는다고 명시합니다. region 아래의 cell과 AZ를 서로 다른 축으로, host aggregate를 AZ 아래에 붙는 묶음으로 설명한 것은 이 글의 종합입니다.

cell·AZ·host aggregate는 Nova DB의 레코드입니다. Kubernetes 쪽에서 배포 대상을 지정할 때는 OpenStack-Helm과 MOSK의 openstack-compute-node=enabled 노드 라벨이나 RHOSO의 OpenStackDataPlaneNodeSet CR(사용자 정의 리소스)을 사용합니다. 이 차이를 종합하면 라벨과 CR은 nova-compute를 설치할 노드를 정하고, 그 뒤 개별 VM을 배치할 호스트는 Nova가 정하는 관계입니다.

근거와 측정 조건
주장수치·조건출처근거
nova-compute의 실행 위치와 기본 하이퍼바이저하이퍼바이저가 있는 노드에서 한 프로세스씩 실행. 기본 하이퍼바이저는 libvirt를 거친 KVM·QEMU. nova.conf 설정은 compute_driver = libvirt.LibvirtDriver, virt_type = kvmNova 문서✓
Kubernetes 쪽의 노드 지정 수단OpenStack-Helm과 MOSK의 openstack-compute-node=enabled 노드 라벨, RHOSO의 OpenStackDataPlaneNodeSet CROpenStack-Helm prerequisites 문서, MOSK 문서, openstack-operator 업스트림 문서✓

3. 컴퓨트 노드를 Kubernetes에 넣는가

OpenStack-Helm에서는 컴퓨트 노드의 kubelet이 nova-compute와 libvirt 파드를 실행합니다. RHOSO에서는 Kubernetes 안에서 실행한 Ansible이 외부 RHEL 노드에 접속해 컴퓨트 서비스를 배포합니다. RHOSO 설명은 업스트림 저장소의 asciidoc을 근거로 했으며 RHOSO 18 제품 문서 본문은 확인하지 못했습니다.

구분전부 Kubernetes컨트롤만 Kubernetes
대표OpenStack-Helm, MOSK, YaookRHOSO
컴퓨트 노드의 kubelet있음. 노드 라벨로 대상 선택없음. RHEL 노드를 Ansible로 관리
nova-compute·libvirtOpenStack-Helm은 DaemonSet 파드. Yaook의 배포 단위는 아래 구현 표 참조호스트의 RPM 또는 podman 컨테이너
컴퓨트 노드 배포helm 또는 오퍼레이터가 파드를 만듦OpenStackDataPlaneDeployment가 Ansible을 실행해 SSH로 접속
노드 유지보수kubectl drain은 맞지 않음. DaemonSet 파드는 drain 대상이 아니고 VM은 Kubernetes 객체가 아님. Atmosphere 문서는 nova host-evacuate-live 사용확인하지 못함
근거직접 확인직접 확인·미확인

OpenStack-Helm의 컴퓨트 파드는 호스트 접근 권한을 넓게 사용합니다. 소스에는 nova-compute와 libvirt 모두 호스트의 네트워크·프로세스·IPC 네임스페이스를 쓰고 privileged로 실행하도록 설정되어 있습니다. libvirt는 호스트 경로도 양방향으로 마운트합니다. Yaook 문서는 privileged를 제거할 수 있는지 검토했지만, /dev/kvm 접근과 nova·libvirt 사이의 소켓 통신, 양방향 마운트 때문에 불가능하다고 결론 냈습니다.

RHOSO는 컨트롤 플레인과 데이터 플레인을 다른 수단으로 관리합니다. openstack-operator가 컨트롤 플레인 CR을 맞추고, 데이터 플레인 노드에는 Ansible이 SSH로 접속합니다. 업스트림 설계 문서는 이 경로에서 Ansible이 Deployment·Pod 같은 워크로드 API와 kubelet을 대신한다고 설명합니다. 노드에 설치되는 소프트웨어는 RPM 또는 podman 컨테이너입니다.

서비스를 파드로 배포해도 VM 이동은 별도로 처리해야 합니다. DaemonSet 파드는 drain 대상이 아니고 VM도 Kubernetes 객체가 아니므로, kubectl drain으로 컴퓨트 노드를 유지보수하기는 적합하지 않다는 판단입니다. Atmosphere 문서는 VM을 옮길 때 nova host-evacuate-live를 사용합니다. RHOSO의 해당 절차는 확인하지 못했습니다.

다른 구현은 확인한 배포 범위가 서로 달라 한 구성으로 묶기 어렵습니다. Atmosphere의 컴퓨트가 파드인지, Yaook의 nova-compute가 노드별 StatefulSet인지는 추정입니다.

구현컨트롤 플레인컴퓨트 쪽상태·근거
Canonical SunbeamKubernetes 위 Charmed Operator, Rock 이미지호스트의 snap문서 확인. snap 이름 미확인
Mirantis MOSKRockoon 오퍼레이터가 CR을 OpenStack-Helm values로 변환노드 라벨, privileged·hostPID 파드문서 확인. 호스트 접근을 설명하는 서술도 문서에 있음(4절)
VEXXHOST AtmosphereAnsible 컬렉션으로 배포libvirt에 Helm values를 넘김컴퓨트가 파드라는 것은 추정
Yaook오퍼레이터와 라벨·taint 스케줄링NovaComputeNode CR, 노드별 StatefulSet으로 보임추정
StarlingXKubernetes 위에 OpenStack을 애플리케이션으로 설치차트가 OpenStack-Helm 기반인지 불명미확인
Airship베어메탈부터 Kubernetes와 차트 배포까지확인하지 않음사이트 최신 언급이 2021년. 현재 상태 미확인
Kolla·kolla-ansibleAnsible이 컨테이너를 배포. Kubernetes 아님같음직접 확인

Kolla 계열은 Ansible이 컨테이너를 배포하므로 Kubernetes 배포 구성에 포함하지 않습니다. 2018-05-02 은퇴한 kolla-kubernetes의 README는 OpenStack-Helm을 대안으로 안내합니다.

근거와 측정 조건
주장수치·조건출처근거
Atmosphere의 컴퓨트 노드 유지보수nova host-evacuate-live 사용Atmosphere 문서✓
OpenStack-Helm nova-compute의 배포·권한 설정DaemonSet. hostNetwork, hostPID, hostIPC가 모두 true. 컨테이너는 privilegedOpenStack-Helm 소스✓
OpenStack-Helm libvirt의 배포·권한·마운트 설정DaemonSet. nova-compute와 같은 호스트 네임스페이스·권한 설정. /var/lib/libvirt와 /var/lib/nova를 mountPropagation: Bidirectional로 마운트OpenStack-Helm 소스✓
Yaook이 privileged를 제거할 수 없다고 판단한 이유/dev/kvm 접근, nova와 libvirt의 소켓 통신, Bidirectional 마운트 필요Yaook 문서✓
RHOSO 컨트롤 플레인과 데이터 플레인의 관리 경로openstack-operator가 컨트롤 플레인 CR을 맞춤. 데이터 플레인은 RHEL 노드. Ansible이 Deployment·Pod 같은 워크로드 API와 kubelet을 대신함. Ansible 실행은 클러스터 안의 워크로드이며 데이터 플레인 노드에는 SSH로 접속openstack-operator 업스트림 저장소의 설계 문서·asciidoc✓
Canonical Sunbeam의 구성컨트롤 플레인은 Kubernetes 위 Charmed Operator와 Rock 이미지. 컴퓨트는 호스트의 snapCanonical Sunbeam 문서✓
Canonical Sunbeam의 snap 이름확인하지 못함—?
Mirantis MOSK의 구성Rockoon 오퍼레이터가 CR을 OpenStack-Helm values로 변환. 컴퓨트는 노드 라벨과 privileged·hostPID 파드 사용. 호스트 접근을 설명하는 문장은 4절 참조Mirantis MOSK 문서✓
VEXXHOST Atmosphere의 구성Ansible 컬렉션으로 배포. libvirt에 Helm values를 넘김Atmosphere 문서—
VEXXHOST Atmosphere의 추정 범위컴퓨트가 파드라는 것—≈
Yaook의 구성과 추정 범위오퍼레이터와 라벨·taint 스케줄링, NovaComputeNode CR 사용. 노드별 StatefulSet으로 보임—≈
StarlingX의 구성과 미확인 범위Kubernetes 위에 OpenStack을 애플리케이션으로 설치. 차트가 OpenStack-Helm 기반인지는 불명—?
Airship의 범위와 확인 한계베어메탈부터 Kubernetes와 차트 배포까지 다룸. 컴퓨트 쪽은 확인하지 않음. 사이트 최신 언급은 2021년Airship 사이트?
Kolla·kolla-ansible의 배포 방식Ansible이 컨트롤 플레인과 컴퓨트의 컨테이너를 배포. Kubernetes를 쓰는 계열이 아님—✓
kolla-kubernetes의 은퇴와 대안 안내2018-05-02 은퇴. README는 OpenStack-Helm을 대안으로 안내governance legacy.yaml(은퇴 날짜), kolla-kubernetes README(대안 안내)✓

4. 얻는 것과 어려운 곳

아래 표는 프로젝트와 벤더가 내세우는 이점이며 이 글이 검증한 것은 아닙니다.

주장누가내용
롤링 업데이트OpenStack-HelmOpenStack-Helm이 설명하기로는 모든 업그레이드를 Helm으로 하고, 이미지 변경은 컨테이너 롤링 교체로 처리
설정 변경도 롤링OpenStack-HelmOpenStack-Helm이 설명하기로는 차트의 configmap에 annotation을 달아 설정 변경이 롤링을 일으킴. 기본값은 max_unavailable: 1, max_surge: 3
자동 복구AirshipAirship이 설명하기로는 모든 서비스가 컨테이너이고 Kubernetes 감독으로 복구됨
선언형 조정MOSK, YaookMOSK와 Yaook이 설명하기로는 CR을 값으로 바꿔 계속 맞춤. Yaook은 변경이 없어도 주기적으로 조정한다고 설명
Day 2 운영Red Hat 보도자료Red Hat 보도자료에 따르면 컨트롤 플레인 운영이 쉬워짐. “컴퓨트 노드 배포가 17.1보다 4배 빠르다"는 측정 조건이 공개되지 않음

이 글에서는 이점이 컨트롤 플레인에 집중된다고 해석합니다. API·scheduler·conductor가 상태를 DB와 큐에 두는 방식은 롤링 재시작과 수평 확장에 맞아 보입니다. 컴퓨트 노드에서는 DaemonSet으로 에이전트 버전을 맞출 수 있지만, VM 프로세스와 네트워크에 미치는 영향까지 파드 교체만으로 해결되지는 않습니다.

libvirt 파드와 VM의 수명

OpenStack-Helm 시작 스크립트는 libvirtd를 파드의 cgroup(프로세스의 자원을 묶어 관리하는 커널 단위) 밖에서 실행합니다. 호스트 프로세스와 경로에 접근하는 설정까지 함께 보면, 파드를 정리할 때 QEMU가 종료되지 않게 하려는 장치로 해석됩니다. 실제로 libvirt 파드를 삭제해 VM이 살아남는지는 시험하지 않았고, libvirtd 재시작이 게스트를 유지한다는 libvirt 공식 문장도 확인하지 못했습니다.

컨트롤 플레인 중단과 VM 중단도 구분해야 합니다. Nova 업그레이드 문서는 VM 중단이 없어야 한다고 적으며 nova-compute를 제외한 서비스를 내렸다 올리는 절차를 안내합니다. 여기에 VM 실행 경로에는 API·scheduler·DB·큐가 없다는 점을 연결하면, 생성·삭제·마이그레이션이 멈춰도 실행 중인 VM은 계속 돈다고 추론할 수 있습니다. 컨트롤 플레인 중단 상황을 그대로 설명한 공식 문장은 확인하지 못했습니다. 호스트 재부팅 뒤 게스트를 다시 켜는 동작은 별도 설정인 resume_guests_state_on_host_boot가 정합니다.

네트워크 파드의 교체 영향

OpenStack-Helm의 OVS·Neutron 관련 파드는 호스트 네트워크를 사용합니다. 설치 설정은 노드 NIC를 브리지에 붙이고 IP도 옮깁니다. 해당 NIC에 Kubernetes 노드 IP가 있다면 kubelet과 CNI(컨테이너 네트워크 인터페이스)가 쓰는 주소도 이동한다는 해석이 가능합니다. 테스트 환경은 CNI로 Calico를 설치하므로 한 노드에 파드용·VM용 데이터 경로가 함께 있다고 추정할 수 있습니다.

VEXXHOST는 OVS 자체에 변화가 없어도 이미지 갱신에 따른 DaemonSet 재시작이 모든 노드의 데이터 경로를 끊었다고 보고했습니다. 컴퓨트 서비스의 롤아웃을 VM 트래픽과 별개로 볼 수 없는 사례입니다. CNI와 Neutron의 공존·충돌을 설명하는 공식 문장은 확인하지 못했습니다.

DB·큐와 기반 클러스터

Galera·RabbitMQ는 StatefulSet으로 배포하지만 스토리지는 구현마다 다르게 선택합니다. MOSK와 Atmosphere는 서비스별 RabbitMQ를 사용합니다. 스토리지 차이는 5절에서 다룹니다.

OpenStack이 실행될 Kubernetes도 먼저 준비해야 합니다. OpenStack-Helm은 Kubernetes 설치를 범위 밖으로 둡니다. 설치할 OpenStack의 Nova로 그 아래 Kubernetes의 노드를 만들 수는 없으므로 별도 수단이 필요하며, 같은 의존 관계를 적용하면 Ceph도 OpenStack보다 먼저 떠 있어야 한다고 추정됩니다. Airship과 MOSK는 베어메탈 프로비저닝부터 맡는다고 설명합니다. RHOSO는 OpenShift의 Cluster Baremetal Operator와 Ironic을 사용합니다. 순환 의존 자체를 직접 다룬 공식 문장은 확인하지 못했습니다.

파드 교체 외에 남는 업그레이드 절차

Nova 문서는 Placement를 nova 서비스보다 먼저 올리도록 안내합니다. 새 코드로 DB를 동기화(cell0 포함)한 뒤 conductor를 먼저 시작하고 API를 마지막에 올리는 것이 가장 안전하다는 순서입니다. DB 다운그레이드는 지원하지 않으므로 Helm으로 이미지를 되돌려도 스키마는 돌아오지 않을 것으로 예상됩니다. Kubernetes가 파드를 차례로 교체하더라도 이 서비스 순서와 DB 작업은 차트·오퍼레이터에 반영해야 한다는 것이 문서들을 종합한 판단입니다.

MOSK 문서는 Kubernetes의 역할을 주로 오케스트레이션과 의존성 격리로 설명합니다. 여러 OpenStack 서비스가 호스트의 프로세스·네트워크에 접근하는 privileged 컨테이너로 실행된다는 설명도 함께 적고 있습니다.

근거와 측정 조건
주장수치·조건출처근거
롤링 업데이트 주장모든 업그레이드를 Helm으로 수행. 이미지 변경은 컨테이너 롤링 교체로 처리OpenStack-HelmⓋ
설정 변경에 따른 롤링차트의 configmap에 annotation을 달아 설정 변경이 롤링을 일으킴. 기본값은 max_unavailable: 1, max_surge: 3OpenStack-HelmⓋ ✓
자동 복구 주장모든 서비스가 컨테이너이며 Kubernetes 감독으로 복구됨AirshipⓋ
선언형 조정CR을 값으로 바꿔 계속 맞춤. Yaook은 변경이 없어도 주기적으로 조정MOSK, YaookⓋ
Day 2 운영과 배포 속도 주장컨트롤 플레인 운영이 쉬워진다는 설명. “컴퓨트 노드 배포가 17.1보다 4배 빠르다"는 측정 조건 비공개Red Hat 보도자료Ⓥ
스크립트의 주석과 마지막 명령“changing CGROUP is required as restart of the pod will cause domains restarts”. 마지막 줄은 cgexec -g ...:/osh-libvirt systemd-run --scope --slice=system libvirtd --listenOpenStack-Helm libvirt 시작 스크립트✓
cgroup 용어와 명령 해설cgroup은 프로세스가 쓰는 자원을 묶는 커널 단위. 명령은 cgroup을 새로 만들어 libvirtd를 kubepods.slice 밖의 system 슬라이스에서 실행——
파드 재시작과 QEMU 수명을 분리하려는 의도로 해석cgroup 처리, hostPID, /run·/var/lib/libvirt 호스트 경로 마운트를 함께 보면 QEMU가 컨테이너 정리에 휩쓸리지 않게 하려는 장치로 읽힘—Σ
기존 libvirtd 프로세스 처리호스트에 이미 실행 중인 libvirtd가 보이면 kill -9로 종료하기도 함OpenStack-Helm libvirt 시작 스크립트✓
Nova 업그레이드 문서의 무중단 안내“There should be no VM downtime when you upgrade Nova”. nova-compute를 뺀 서비스를 모두 내렸다 올리는 절차가 있음Nova 업그레이드 문서✓
호스트 재부팅 뒤 게스트 재시작 설정resume_guests_state_on_host_boot가 결정. 기본 FalseNova 설정 옵션 문서✓
네트워크 파드의 호스트 접근OVS, neutron OVS agent, OVN controller 파드는 모두 hostNetwork. vswitchd는 privileged로 고정OpenStack-Helm 소스✓
노드 NIC와 IP의 브리지 이동auto_bridge_add가 노드 NIC를 br-ex 브리지에 붙이고 인터페이스의 IP를 브리지로 옮김OpenStack-Helm 설치 문서✓
파드용·VM용 데이터 경로의 공존OpenStack-Helm 테스트 환경은 CNI로 Calico를 설치하므로 한 노드에 파드용과 VM용 데이터 경로가 함께 있다는 종합OpenStack-Helm 테스트 환경Σ
OVS DaemonSet 롤아웃의 데이터 경로 영향Kubernetes가 갱신된 이미지를 감지해 롤아웃. Open vSwitch에 변화가 없어도 재시작이 모든 노드에서 데이터 경로 끊김을 일으켰다는 보고VEXXHOST 블로그Ⓥ
RHOSO의 OVN 업데이트 순서컨트롤 플레인과 데이터 플레인의 OVN을 먼저 올린 뒤 나머지 데이터 플레인 서비스를 업데이트openstack-operator 업스트림 저장소의 데이터 플레인 업데이트 문서(asciidoc)✓
MOSK의 DB·큐 구성서비스마다 RabbitMQ 인스턴스를 따로 두고 Galera는 3개 이상으로 구성MOSK 문서✓
Atmosphere의 큐 구성서비스별 RabbitMQ 사용Atmosphere 문서✓
아래층 Kubernetes의 책임 범위Kubernetes 설치는 OpenStack-Helm 범위 밖. 예시로 든 kubeadm과 Ansible은 “not production-ready”OpenStack-Helm 문서✓
베어메탈 프로비저닝 범위베어메탈 프로비저닝부터 맡는다는 설명Airship, MOSKⓋ
RHOSO의 베어메탈 프로비저닝OpenShift의 Cluster Baremetal Operator와 Ironic 사용—✓
RHOSO에서 먼저 쓰는 Ironic의 소속설치할 OpenStack의 Ironic이 아닌 플랫폼의 Ironic이라는 해석—Σ
Nova의 업그레이드 순서Placement를 nova 서비스보다 먼저 업데이트. 새 코드로 DB 동기화하며 cell0 포함. conductor를 먼저 시작하고 API를 마지막에 올리는 것이 가장 안전하다는 안내Nova 업그레이드 문서✓
Nova 릴리스 공존과 DB 다운그레이드N과 N-2 릴리스의 nova-compute가 같은 배포에 공존하는 것까지 지원. DB 다운그레이드는 지원하지 않음Nova 문서✓
차트 업그레이드에서 남는 문제이미 끝난 db_sync Job을 새 이미지로 다시 실행해야 하는 문제. 롤링 설정이 PodDisruptionBudget과 충돌할 수 있음OpenStack-Helm 문서✓
MOSK가 설명하는 Kubernetes 사용 범위“uses Kubernetes mostly for orchestration and dependency isolation. As a result, multiple OpenStack services are running as privileged containers with host PIDs and Host Networking enabled.”MOSK 문서✓

5. 스토리지는 어디서 정해지는가

컨트롤 플레인의 DB·큐는 Kubernetes StorageClass를 사용합니다. VM의 임시 디스크와 영구 볼륨은 Nova와 Cinder 설정을 따릅니다. 따라서 Kubernetes에 어떤 StorageClass를 두는지와 VM 디스크를 어디에 저장하는지는 별도로 결정됩니다.

대상정하는 곳OpenStack-Helm 기본값
컨트롤 플레인 DB·큐Kubernetes StorageClassgeneral. 문서가 Ceph를 전제
VM 임시 디스크컴퓨트 노드 nova.conf의 [libvirt] images_typeqcow2(로컬 디스크). rbd로 바꾸면 Ceph
VM 영구 볼륨Cinder의 enabled_backends와 드라이버rbd(rbd1)

OpenStack-Helm 문서는 MariaDB·RabbitMQ의 PV(퍼시스턴트 볼륨) 백엔드로 Ceph를 전제하고, StatefulSet이 general이라는 StorageClass를 찾는다고 설명합니다. MOSK 문서는 다른 선택을 보여 줍니다. Ceph CSI를 사용하지만 일부 워크로드에는 네트워크 스토리지의 지연이 맞지 않아, local-volume-provisioner의 별도 StorageClass에 Galera 파일을 둡니다. 로컬 PV는 DB 파드를 노드에 묶습니다. 이 조건을 보면 노드를 잃었을 때 Galera 복제가 필요하고, MOSK가 요구하는 최소 복제본 수와도 연결된다고 해석할 수 있습니다.

OpenStack 설계 문서는 VM 삭제와 함께 사라지는 임시 디스크와 Cinder가 맡는 영구 볼륨을 구분합니다. OpenStack-Helm의 Nova 기본값은 로컬 qcow2이고 Cinder 기본값은 RBD 드라이버입니다. libvirt 차트는 시작할 때 Ceph 키를 libvirt secret으로 등록합니다. 이 설정으로부터 VM의 RBD 볼륨은 QEMU가 Ceph에 직접 접근하며 Kubernetes CSI(컨테이너 스토리지 인터페이스)를 지나지 않는다고 해석했습니다.

이 경로에서 VM 디스크를 Kubernetes PV·PVC와 별개로 봅니다. VM 디스크 경로는 02 VM 디스크 경로에서, 로컬 디스크를 쓸 때의 가용성은 03 로컬 디스크 HA에서 다룹니다.

설정 지점이 달라도 저장소는 같을 수 있습니다. 같은 Rook-Ceph 클러스터가 컨트롤 플레인 PV와 VM의 RBD를 공급한다면, DB와 테넌트 디스크가 한 장애 도메인을 공유한다고 추정할 수 있습니다.

근거와 측정 조건
주장수치·조건출처근거
컨트롤 플레인 DB·큐의 스토리지 결정 지점Kubernetes StorageClass. OpenStack-Helm 기본값은 general이며 문서는 Ceph를 전제OpenStack-Helm 문서✓
VM 임시 디스크의 결정 지점과 기본값컴퓨트 노드 nova.conf의 [libvirt] images_type. OpenStack-Helm 기본값은 qcow2(로컬 디스크). rbd로 바꾸면 CephNova KVM 문서(결정 지점), nova 차트(기본값)✓
VM 영구 볼륨의 결정 지점과 기본값Cinder의 enabled_backends와 드라이버. OpenStack-Helm 기본값은 rbd(rbd1)OpenStack-Helm✓
컨트롤 플레인 PV의 백엔드와 StorageClassCeph를 MariaDB·RabbitMQ 같은 서비스의 PV 백엔드로 사용. StatefulSet이 general이라는 StorageClass를 찾음OpenStack-Helm 문서✓
mariadb 차트 기본값복제본 3개, 볼륨 5Gimariadb 차트✓
MOSK의 Galera 스토리지 선택Ceph CSI를 쓰지만 일부 워크로드에는 지연 때문에 네트워크 스토리지가 맞지 않는다고 설명. local-volume-provisioner를 별도 StorageClass로 두고 Galera 파일을 저장MOSK 문서✓
로컬 PV와 Galera 복제의 관계로컬 PV를 쓰면 DB 파드가 노드에 묶임. 노드를 잃었을 때 Galera 복제로 버텨야 한다는 추론이며, MOSK가 최소 3개를 요구하는 조건과 연결—Σ
Nova·Cinder 차트의 디스크 기본값nova 차트는 images_type: qcow2, cinder 차트는 RBD 드라이버nova·cinder 차트✓
RBD 접근 경로libvirt 차트는 시작할 때 Ceph 키를 libvirt secret으로 등록. 이를 바탕으로 VM의 RBD 볼륨에 QEMU가 Ceph로 직접 접근하고 Kubernetes CSI를 지나지 않는다고 설명libvirt 차트✓ Σ

6. KubeVirt 비교와 Kubernetes on OpenStack

KubeVirt에서는 kube-scheduler가 virt-launcher 파드를 노드에 배치합니다. OpenStack-Helm 구성에서는 nova-scheduler가 VM의 호스트를 고르고, kube-scheduler는 nova-compute DaemonSet 파드를 배치합니다. VM을 나타내는 객체도 KubeVirt의 VMI와 Nova DB의 instance로 다릅니다.

VM의 배치를 누가 정하는지로 세 구도를 나란히 놓았습니다. 위 두 줄은 VM의 배치를 kube-scheduler가 정하느냐 nova-scheduler가 정하느냐가 다르고, 셋째 줄은 방향이 반대입니다. 근거는 KubeVirt 문서와 OpenStack-Helm 소스, Magnum·CAPO 문서입니다 ✓. 칸 사이의 대비는 종합입니다 Σ.
도식 텍스트
  • KubeVirt: Kubernetes가 VM을 돌린다
  • OpenStack on Kubernetes: Kubernetes가 OpenStack을 돌린다
  • Kubernetes on OpenStack: OpenStack이 Kubernetes를 돌린다
  • VMI 객체 — Kubernetes CR
  • kube-scheduler — 파드를 노드에 배치
  • virt-launcher 파드 — VM마다 하나 · 안에 libvirtd
  • QEMU — 파드 cgroup 안
  • Nova API — instance는 Nova DB
  • nova-scheduler — 호스트를 선택
  • nova-compute 파드 — 노드당 하나 · libvirtd도 노드당 하나
  • QEMU — 파드 cgroup 밖
  • Magnum · CAPO — Kubernetes 클러스터 요청
  • Nova API — 노드 VM 생성
  • 컴퓨트 노드의 VM — 일반 OpenStack 경로
  • Kubernetes 노드 — 테넌트의 클러스터
  • 파드
  • 배치
  • 실행
  • 요청
  • 선택
  • 실행
  • API
  • 생성
  • 부팅
항목KubeVirtOpenStack on Kubernetes(OpenStack-Helm)
배치 결정kube-schedulernova-scheduler와 Placement
VM의 API 객체VMI(Kubernetes CR)Nova DB의 instance. Kubernetes는 VM을 모름
libvirtd 단위VM마다 하나(파드 안)컴퓨트 노드마다 하나
QEMU의 cgroup파드 cgroup 안파드 cgroup 밖으로 일부러 뺌
파드와 VM의 생사파드가 종료되면 VM 종료. virt-launcher가 VM 종료를 기다리며 파드 종료를 미룸libvirt 파드가 재시작해도 VM이 남도록 설계
네트워크·스토리지CNI·PVCNeutron·Cinder

KubeVirt 문서는 스케줄링·네트워크·스토리지를 Kubernetes에 맡기고 가상화 기능을 제공한다고 설명합니다. 이 글의 정리로는 KubeVirt에서 Kubernetes는 VM을 실행하고, OpenStack on Kubernetes에서는 VM 관리 소프트웨어를 실행합니다.

파드와 VM의 수명 관계도 이 구분에 연결됩니다. KubeVirt에서는 VM이 파드와 함께 종료되며 virt-launcher가 VM 종료를 기다립니다. OpenStack-Helm의 libvirt 스크립트는 파드가 재시작해도 VM이 남게 하려는 설계로 읽힙니다. 표의 후자는 소스에서 의도를 해석한 내용입니다. OpenStack on Kubernetes가 KubeVirt를 사용하지 않는다고 명시한 문장은 찾지 않았고, OpenStack-Helm과 RHOSO의 컴퓨트 경로에 KubeVirt 컴포넌트가 없다는 점만 소스와 문서에서 확인했습니다.

OpenStack 위에 만드는 Kubernetes

그림의 마지막 줄인 Kubernetes on OpenStack은 OpenStack on Kubernetes와 배포 방향이 반대입니다. Magnum은 OpenStack의 VM·베어메탈 위에 Kubernetes 클러스터를 만드는 API입니다. Cluster API Provider OpenStack(CAPO)은 Cluster API가 OpenStack API를 호출해 노드 VM을 만들게 합니다.

한 시스템에 양쪽 방향이 함께 나타날 수도 있습니다. OpenStack-Helm에는 magnum 차트가 있고, Atmosphere는 Magnum용 Cluster API 드라이버를 소개합니다. 문서들을 종합하면 OpenStack을 실행하는 아래층 Kubernetes와 테넌트가 Magnum으로 만드는 위층 Kubernetes는 서로 다른 클러스터로 볼 수 있습니다. OpenStack Foundation 백서에 따르면 CERN은 Magnum으로 200개 이상의 Kubernetes 설치를 관리합니다. 이것도 Kubernetes on OpenStack 방향의 사례입니다.

근거와 측정 조건
주장수치·조건출처근거
libvirtd의 실행 단위KubeVirt는 VM마다 하나이며 파드 안에서 실행. OpenStack-Helm은 컴퓨트 노드마다 하나—✓
QEMU의 cgroup 위치KubeVirt는 파드 cgroup 안. OpenStack-Helm은 파드 cgroup 밖으로 일부러 빼려는 설계로 해석—✓ Σ
파드와 VM의 수명 관계KubeVirt는 파드가 종료되면 VM 종료. virt-launcher는 VM 종료를 기다리며 파드 종료를 미룸. OpenStack-Helm은 libvirt 파드가 재시작해도 VM이 남도록 설계된 것으로 해석—✓ Σ
네트워크·스토리지 경로KubeVirt는 CNI·PVC. OpenStack-Helm 구성은 Neutron·Cinder—✓ Σ
Magnum과 CAPO의 역할Magnum은 OpenStack VM·베어메탈 위에 Kubernetes 클러스터를 만드는 API. Cluster API Provider OpenStack(CAPO)은 Cluster API가 OpenStack API를 불러 노드 VM을 생성Magnum 문서, Cluster API Provider OpenStack README✓
양쪽 방향을 함께 구성하는 사례OpenStack-Helm에 magnum 차트가 있음. Atmosphere는 Magnum용 Cluster API 드라이버를 내세움OpenStack-Helm 차트·Atmosphere✓
CERN 사례의 방향과 규모Magnum으로 관리하는 200개 이상의 Kubernetes 설치. Kubernetes on OpenStack 방향의 사례OpenStack Foundation 백서Ⓥ

7. 확인하지 못한 것

항목상태
RHOSO 18 제품 문서 본문docs.redhat.com이 JS로 렌더링되어 읽지 못함. 업스트림 asciidoc과 보도자료로 대체 ?
컨트롤 플레인이 내려가도 VM이 돈다는 공식 문장업그레이드 문서의 “no VM downtime"과 실행 경로를 바탕으로 한 추론만 있음 ?
libvirtd 재시작이 실행 중 게스트를 건드리지 않는다는 libvirt 문장찾지 못함 ?
OpenStack-Helm에서 libvirt 파드를 지웠을 때 VM 생존소스에서 의도만 확인했으며 실행해 보지 않음 ?
CNI와 Neutron 데이터 경로의 공존·충돌 설명이를 설명하는 공식 문장을 찾지 못함 ?
순환 의존을 직접 다룬 문장, MAAS 조합의 1차 문서찾지 못함 ?
MOSK·Atmosphere의 libvirt cgroup 처리OpenStack-Helm 차트를 그대로 쓰는지 소스를 열어 보지 않음 ?
Sunbeam 하이퍼바이저 snap의 이름, Yaook nova-compute가 노드별 StatefulSet인지확인하지 못함 ?
StarlingX 차트의 기반, Airship의 현재 상태확인하지 못함. Airship 사이트의 최신 언급은 2021년이며 저장소 일부에는 2026-10에도 push가 있음 ?
운영 사례의 규모AT&T 사례는 2018년 무렵 재단 백서에 “still testing"으로 적힌 계획이며 현재 상태는 모름 Ⓥ ≈ ?. SAP는 sapcc/helm-charts 저장소가 있다는 점까지 확인 ✓. CERN은 on-Kubernetes 사례가 아님
OpenStack-Helm README의 “2025.2 (Dalmatian)” 표기2025.2의 코드명은 Flamingo이므로 오기로 보지만 확인하지 않음 ≈
Rook-Ceph 하나를 컨트롤 플레인 PV와 VM RBD가 함께 쓸 때 분리하라는 권고확인하지 않음 ?
성능 수치조건이 명시된 자료를 찾지 못해 싣지 않음. Red Hat의 “4x faster"는 조건 비공개 Ⓥ

참고 자료

마지막 수정 일자