---
title: "GPU 서버 통합을 위한 OpenStack Nova Compute 노드 설치 및 설정 완벽 가이드"
description: "GPU 서버를 OpenStack에 통합하기 위해 새 Nova Compute 노드를 설정하고, 호스트네임·시간 동기화·OVS 네트워크(DVR)·Nova 및 Neutron 서비스·Ceph RBD 연동·GPU PCI Passthrough를 포함한 주요 구성 요소들을 단계별로 안내한다. 설치 후 서비스 시작, 노드 등록, 검증 절차와 주의사항을 제시한다."
date: "2025-03-27"
last_modified: "2026-08-06T00:36:00.000Z"
type: "Post"
tags:
  - "openstack"
  - "gpu"
  - "ceph"
  - "install"
  - "network"
  - "ubuntu"
categories:
  - "📗 Docs"
series:
  - "오픈스택 운영"
canonical_url: "https://blog.pieroot.xyz/nova-compute-guide"
markdown_url: "https://blog.pieroot.xyz/nova-compute-guide.md"
---

# GPU 서버 통합을 위한 OpenStack Nova Compute 노드 설치 및 설정 완벽 가이드

GPU 서버를 OpenStack에 통합하기 위해 새 Nova Compute 노드를 설정하고, 호스트네임·시간 동기화·OVS 네트워크(DVR)·Nova 및 Neutron 서비스·Ceph RBD 연동·GPU PCI Passthrough를 포함한 주요 구성 요소들을 단계별로 안내한다. 설치 후 서비스 시작, 노드 등록, 검증 절차와 주의사항을 제시한다.

연구실에 있던 GPU 서버들을 이제 OpenStack으로 통합하기 시작했다. 이번에 새로운 Compute 노드를 확장하면서, 그동안 정리하지 못했던 **Nova Compute 노드 설치 방법을 처음부터 끝까지** 서술하려 한다. ~~매번 기억에 의존하다가 삽질하는 건 이제 그만~~

> **이 글에서 다루는 내용**
> 
> - hostname 및 NTP 시간 동기화 설정
> 
> - OVS 네트워크 구성 (DVR 모드)
> 
> - Nova Compute 설치 및 `nova.conf` 상세 설정
> 
> - Neutron OVS Agent, L3 Agent, ML2 설정
> 
> - Ceph RBD 연동 (libvirt secret 포함)
> 
> - PCI Passthrough (GPU) 설정
> 
> - 서비스 시작 및 노드 등록 검증

![OpenStack Nova Compute 노드 통합 구조](https://blog.pieroot.xyz/api/image-proxy?id=3d14506a-d234-4ffe-9815-c04b7f362eab&kind=s3&pageId=30d067c0-15d0-80ac-9a5e-f3647167c13c&source=block&blockId=db54a39c-5ae0-415b-a969-2a84ca9720a2)

---

### 🖥️ hostname 설정

OpenStack에서는 내부 통신을 IP로도 하지만, 주로 **`/etc/hosts`****에 기록된 호스트네임으로 통신하는 경우가 많다**. RabbitMQ, Keystone, Placement 등 거의 모든 서비스가 호스트네임 기반으로 동작하기 때문에, 노드를 추가하기 전에 이 설정을 먼저 해야 한다.

#### 호스트네임 변경

```bash
# 호스트네임 설정 (새 컴퓨트 노드에서 실행)
sudo hostnamectl set-hostname dms-compute5

# 적용 확인
hostname
```

#### /etc/hosts 수정

컨트롤러와 기존 컴퓨트 노드들, 그리고 새로 추가할 노드의 정보를 모든 노드의 `/etc/hosts`에 추가한다.

```bash
sudo vi /etc/hosts
```

```javascript
# OpenStack Nodes
172.30.0.11   dms-controller
172.30.0.101  dms-compute1
172.30.0.102  dms-compute2
172.30.0.103  dms-compute3
172.30.0.104  dms-compute4
172.30.0.105  dms-compute5   # 새로 추가하는 노드
```

아래 사진은 우리 환경에서의 controller와 compute 노드 구성이다.

![image](https://blog.pieroot.xyz/api/image-proxy?id=d50cc20f-3bcb-476d-a840-6dc99cae0bd4&kind=s3&pageId=30d067c0-15d0-80ac-9a5e-f3647167c13c&source=block&blockId=30d067c0-15d0-80f5-919c-e77304af1cfa)

> **중요**: `/etc/hosts` 수정은 **새 노드뿐만 아니라 기존 모든 노드(컨트롤러 포함)**에도 반영해야 한다. 안 그러면 컨트롤러가 새 컴퓨트 노드를 호스트네임으로 찾지 못해 통신이 안 된다.

---

### ⏰ 시간 동기화 (Chrony)

컨트롤러와 시간이 맞지 않으면 인증 토큰 만료, 스케줄링 충돌 등 온갖 문제가 발생한다. **NTP 동기화는 OpenStack 운영의 기본 중의 기본**이다.

여기서는 컨트롤러에 이미 NTP(Chrony) 서버가 설치되어 있는 상태를 전제로 진행한다.

#### Chrony 설치

```bash
sudo apt install chrony
```

#### 컨트롤러를 NTP 서버로 지정

`/etc/chrony/chrony.conf` 파일을 열고 맨 아래에 컨트롤러를 NTP 소스로 추가한다.

```bash
sudo vi /etc/chrony/chrony.conf
```

```bash
# 기존 pool/server 라인은 주석 처리하거나 제거
# pool ntp.ubuntu.com        iburst maxsources 4

# 컨트롤러를 NTP 서버로 지정
server dms-controller iburst
```

> **`iburst`**** 옵션이란?**
> 
> 일반적인 NTP 폴링은 간격이 길어서 초기 동기화에 시간이 걸린다. `iburst`를 사용하면 서비스 시작 시 **빠른 연속 요청(burst)**을 보내 초기 동기화를 빠르게 완료한다. 서버 환경에서는 거의 필수 옵션이다.

#### 서비스 재시작 및 동기화 확인

```bash
# Chrony 재시작
sudo systemctl restart chrony

# 동기화 상태 확인
chronyc sources
```

정상적으로 동기화되면 컨트롤러 앞에 `^*` 표시가 나타난다.

```bash
# 예상 출력
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^* dms-controller                3   6    17    23   -124us[ -124us] +/-   25ms
```

> **동기화 상태 기호 설명**
> 
> - `^*`: 현재 동기화 중인 소스 (정상)
> 
> - `^+`: 사용 가능한 양호한 소스
> 
> - `^-`: 사용 가능하지만 다른 소스와 조합이 안 맞는 소스
> 
> - `^?`: 연결이 안 되거나 확인 중인 소스 → 이게 나오면 네트워크 확인 필요

---

### 🌐 OVS 네트워크 설정

OpenStack에서는 OVS(Open vSwitch)로 인터페이스를 컨트롤한다. OVS 설정을 통해 **self-service 네트워크와 provider 네트워크**를 구성해야 하는데, 우리 환경에서는 다음 3개를 구성한다:

- **tenant**: VLAN 기반 테넌트 네트워크 (인스턴스 간 통신)

- **provider (public)**: 외부 접근용 flat 네트워크

- **vpn (private)**: 내부 관리용 flat 네트워크 (management 네트워크 겸용)

> **OVS 브릿지 매핑 구조**
> 
> ```javascript
> 물리 NIC → OVS Bridge → OpenStack 네트워크
> enp2s0   → br-provider → provider (flat)
> (veth)   → br-vpn      → vpn (flat)
> enp10s0  → br-tenant   → tenant (vlan)
> ```

OVS 브릿지 생성과 포트 연결에 대한 상세한 내용은 아래 링크에서 다루고 있다.

![OVS 브릿지 매핑 구조](https://blog.pieroot.xyz/api/image-proxy?id=31c72a20-6885-4e1d-8588-ca865dc393d0&kind=s3&pageId=30d067c0-15d0-80ac-9a5e-f3647167c13c&source=block&blockId=be1ac827-88bd-485d-962e-c96ae7d9dd15)

[Untitled](https://app.notion.com/p/38c4e8f5fee44d5993202939fd2b5ba3) 

---

### 📦 Nova Compute 설치

#### OpenStack 저장소 추가

Ubuntu에서 OpenStack 패키지를 설치하려면 먼저 **Cloud Archive 저장소**를 추가해야 한다. 우리는 **Caracal** 릴리즈를 사용한다.

```bash
sudo add-apt-repository cloud-archive:caracal
sudo apt update
```

#### KVM 지원 확인

Nova Compute를 설치하기 전에, **하드웨어 가상화(KVM)를 지원하는지** 확인한다. GPU 서버라면 보통 지원하지만, 확인은 필수다.

```bash
egrep -c '(vmx|svm)' /proc/cpuinfo
```

> **결과 해석**
> 
> - **1 이상**: KVM 하드웨어 가속 지원 → `virt_type = kvm` 사용 (성능 최적)
> 
> - **0**: 하드웨어 가속 미지원 → `virt_type = qemu` 사용 (소프트웨어 에뮬레이션, 느림)
> 
> - Intel CPU는 `vmx`, AMD CPU는 `svm` 플래그로 확인된다

#### Nova Compute 패키지 설치

```bash
sudo apt install nova-compute
```

---

### ⚙️ Nova 설정 (nova.conf)

Nova의 핵심 설정 파일이다. 아래와 같이 수정하되, **각 환경에 맞게 비밀번호와 IP를 변경**해야 한다.

```bash
sudo vi /etc/nova/nova.conf
```

> **설정 전 반드시 확인할 것**
> 
> - `CHANGEPASSWORD`로 표기된 부분은 **컨트롤러의 Keystone에 설정한 실제 비밀번호**로 변경해야 한다
> 
> - `my_ip`는 **현재 설정 중인 컴퓨트 노드의 IP**로 변경해야 한다
> 
> - `rbd_secret_uuid`는 **기존 컴퓨트 노드들과 동일한 UUID**를 사용해야 한다

```bash
[DEFAULT]
log_dir = /var/log/nova
lock_path = /var/lock/nova
state_path = /var/lib/nova
transport_url = rabbit://openstack:CHANGEPASSWORD@dms-controller:5672/
# 컨트롤러의 keystone 에 설정한대로 반영
my_ip = 172.30.0.105
# 이 설정파일을 설정한 노드의 IP 로 변경

[api]
auth_strategy = keystone

[api_database]
connection = mysql+pymysql://nova:CHANGEPASSWORD@dms-controller/nova_api
# 컨트롤러의 keystone 에 설정한대로 반영

[barbican]
[barbican_service_user]
[cache]

[cinder]
os_region_name = RegionOne
# storage 노드 설정할때 반영한 데이터로 변경

[compute]
[conductor]
[console]
[consoleauth]
[cors]
[cyborg]

[database]
connection = mysql+pymysql://nova:CHANGEPASSWORD@dms-controller/nova
# 컨트롤러의 keystone 에 설정한대로 반영

[devices]
[ephemeral_storage_encryption]

[filter_scheduler]
enabled_filters = PciPassthroughFilter
available_filters = nova.scheduler.filters.all_filters

[glance]
api_servers = http://dms-controller:9292
# 실제 glance 서버의 아이피로 변경 - 현재 컨트롤러에 같이 있음

[guestfs]
[healthcheck]
[image_cache]
[ironic]
[key_manager]
[keystone]

[keystone_authtoken]
www_authenticate_uri = http://dms-controller:5000/
auth_url = http://dms-controller:5000/
memcached_servers = dms-controller:11211
auth_type = password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = nova
password = CHANGEPASSWORD 
# 컨트롤러의 keystone 에 설정한대로 반영

[libvirt]
cpu_mode = host-passthrough
virt_type = kvm

images_type = rbd
images_rbd_pool = vms
images_rbd_ceph_conf = /etc/ceph/ceph.conf
rbd_user = nova
rbd_secret_uuid = <CHANGE_NOVA_RBD_SECRET_UUID>
disk_cachemodes="network=writeback"
inject_password = false
inject_key = false
inject_partition = -2
live_migration_flag="VIR_MIGRATE_UNDEFINE_SOURCE,VIR_MIGRATE_PEER2PEER,VIR_MIGRATE_LIVE,VIR_MIGRATE_PERSIST_DEST,VIR_MIGRATE_TUNNELLED"
hw_disk_discard = unmap
# 컨트롤러의 ceph 연결을 반영
# rbd_user=nova 로 설정된 다른 노드들과 같은 UUID 를 공유해야함

[metrics]
[mks]

[neutron]
auth_url = http://dms-controller:5000
auth_type = password
project_domain_name = Default
user_domain_name = Default
region_name = RegionOne
project_name = service
username = neutron
password = CHANGEPASSWORD
# 컨트롤러의 keystone 에 설정한대로 반영
service_metadata_proxy = true
metadata_proxy_shared_secret = CHANGEPASSWORD
# 컨트롤러의 keystone 에 설정한대로 반영 - neutron metadata 가 설치되어있어야함

[notifications]
[os_vif_linux_bridge]
[os_vif_ovs]

[oslo_concurrency]
lock_path = /var/lib/nova/tmp

[oslo_limit]
[oslo_messaging_amqp]
[oslo_messaging_kafka]
[oslo_messaging_notifications]
[oslo_messaging_rabbit]
[oslo_middleware]
[oslo_policy]
[oslo_reports]
[oslo_versionedobjects]

[pci]
passthrough_whitelist = [{"vendor_id":"10de", "product_id":"1b06"},{"vendor_id":"10de", "product_id":"10ef"}]
alias = { "vendor_id":"10de", "product_id":"17c2", "name":"GTX-TITAN-X" }
alias = { "vendor_id":"10de", "product_id":"0fb0", "name":"GM200-audio" }
alias = { "vendor_id":"10de", "product_id":"1b06", "name":"GTX-1080ti" }
alias = { "vendor_id":"10de", "product_id":"1b00", "name":"TITAN-X" }
alias = { "vendor_id":"10de", "product_id":"10ef", "name":"GP102-audio" }
# gpu passthrough 를 위해 필요한 설정이다.
# alias 는 현재 노드의 정보만 추가해도 무당하긴 함
# passthrough_whitelist 는 현재 노드의 실제 device 정보를 기록해야함
# 같은 정보가 컨트롤러에도 있어야 정상 동작

[placement]
region_name = RegionOne
project_domain_name = Default
project_name = service
auth_type = password
user_domain_name = Default
auth_url = http://dms-controller:5000/v3
username = placement
password = CHANGEPASSWORD
# 컨트롤러의 keystone 에 설정한대로 반영

[privsep]
[profiler]
[quota]
[remote_debug]

[scheduler]
discover_hosts_in_cells_interval = 300
# 이건 nova scheduler 에서 사용하는 옵션이라 컴퓨트에는 그닥 필요하지 않음

[serial_console]

[service_user]
send_service_user_token = true
auth_url = http://dms-controller:5000/
# openstack install guide 대로 따라하면 https 로 구성할텐데 ssl 반영 안했다면 http 로 바꾸고 url 도 수정해야함
auth_strategy = keystone
auth_type = password
project_domain_name = Default
project_name = service
user_domain_name = Default
username = nova
password = CHANGEPASSWORD
# 컨트롤러의 keystone 에 설정한대로 반영

[spice]
[upgrade_levels]
[vault]
[vendordata_dynamic_auth]
[vmware]

[vnc]
enabled = true
server_listen = 0.0.0.0
server_proxyclient_address = $my_ip
novncproxy_base_url = https://novnc.dmslab.xyz/vnc_auto.html
# 현재 노드에 있는 인스턴스는 위 base_url 로 들어왔을때 리다이렉트 해줌
# 컨트롤러의 도메인과 url 을 동기화하면 됨
ssl_only = false
# 이거 켜져있으면 로컬에서 접속이 힘들수도?

[workarounds]
[wsgi]
[zvm]

# 아래 얘들은 그냥 기본값이 이거더라구요 
[cells]
enable = False

[os_region_name]
openstack = 
```

#### 주요 섹션별 해설

![nova.conf 핵심 설정과 외부 서비스 연결 관계](https://blog.pieroot.xyz/api/image-proxy?id=be1bd0d9-7d81-4c51-94c0-fbe74101e114&kind=s3&pageId=30d067c0-15d0-80ac-9a5e-f3647167c13c&source=block&blockId=0a6b8631-a675-4b0b-b302-647f2dff8900)

> **\[libvirt\] 섹션 - Ceph RBD + KVM 설정**
> 
> - `cpu_mode = host-passthrough`: 호스트 CPU 기능을 그대로 VM에 전달한다. GPU Passthrough 사용 시 필수
> 
> - `virt_type = kvm`: KVM 하드웨어 가속 사용. `egrep` 결과가 0이면 `qemu`로 변경
> 
> - `images_type = rbd`: VM 이미지를 Ceph RBD에 저장한다. 로컬 디스크 대신 분산 스토리지 활용
> 
> - `rbd_secret_uuid`: libvirt가 Ceph에 인증할 때 사용하는 시크릿 UUID. **모든 컴퓨트 노드에서 동일해야 한다**
> 
> - `disk_cachemodes = "network=writeback"`: 네트워크 디스크(RBD)에 writeback 캐시 적용. 성능 향상에 도움
> 
> - `hw_disk_discard = unmap`: VM에서 삭제한 블록을 Ceph에 알려 실제 공간을 회수한다 (thin provisioning 효과)

> **\[pci\] 섹션 - GPU Passthrough 설정**
> 
> - `passthrough_whitelist`: 이 컴퓨트 노드에서 **실제로 패스스루할 PCI 디바이스** 목록이다. `vendor_id`와 `product_id`는 `lspci -nn` 명령으로 확인할 수 있다
> 
> - `alias`: GPU 이름을 사람이 읽기 쉬운 별칭으로 매핑한다. 인스턴스 생성 시 flavor extra\_specs에서 이 이름을 사용
> 
> - **NVIDIA GPU는 그래픽 디바이스와 오디오 디바이스가 쌍으로** 존재한다. 둘 다 whitelist에 등록해야 정상 동작한다
> 
> - **같은 alias 정보가 컨트롤러의 ****`nova.conf`****에도 있어야** 스케줄러가 올바르게 동작한다

> **\[vnc\] 섹션 - 콘솔 접속 설정**
> 
> - `server_listen = 0.0.0.0`: 모든 인터페이스에서 VNC 연결을 수신
> 
> - `server_proxyclient_address = $my_ip`: VNC 프록시가 이 노드에 접속할 때 사용할 IP
> 
> - `novncproxy_base_url`: 브라우저에서 noVNC로 접속할 URL. **컨트롤러의 도메인과 일치**시켜야 한다

---

### 🔌 Neutron 설정

Compute 노드에서도 Neutron 에이전트가 필요하다. OVS Agent가 인스턴스의 네트워크를 관리하고, L3 Agent가 **DVR(Distributed Virtual Routing)** 모드로 라우팅을 처리한다.

#### 패키지 설치

```bash
sudo apt install neutron-openvswitch-agent
sudo apt install neutron-l3-agent neutron-plugin-ml2
```
*이것도 귀찮아서 다른 서버에서 설정 파일 가져올 예정*

> **왜 Compute 노드에 L3 Agent가 필요한가?**
> 
> 일반적인 중앙 집중식 라우팅에서는 모든 트래픽이 네트워크 노드를 거쳐야 한다. 하지만 **DVR 모드**를 사용하면 각 컴퓨트 노드에서 직접 라우팅을 처리할 수 있어, 네트워크 노드의 부하를 분산시키고 **East-West 트래픽의 지연 시간을 크게 줄일 수 있다**.

#### neutron.conf

`/etc/neutron/neutron.conf` 파일을 수정한다.

```bash
sudo vi /etc/neutron/neutron.conf
```

```bash
[DEFAULT]
core_plugin = ml2
service_plugins = router

transport_url = rabbit://openstack:CHANGEPASSWORD@dms-controller1
notify_nova_on_port_status_changes = true
notify_nova_on_port_data_changes = true

auth_strategy = keystone

router_distributed = true
# dvr 모드 활성화
[agent]
root_helper = "sudo /usr/bin/neutron-rootwrap /etc/neutron/rootwrap.conf"

[cache]
[cors]

[database]
connection = mysql+pymysql://neutron:CHANGEPASSWORD@dms-controller1/neutron

[designate]
[experimental]
[healthcheck]
[ironic]

[keystone_authtoken]
www_authenticate_uri = http://dms-controller1:5000
auth_url = http://dms-controller1:5000
memcached_servers = dms-controller1:11211
auth_type = password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = neutron
password = CHANGEPASSWORD

[nova]
auth_url = http://dms-controller1:5000
auth_type = password
project_domain_name = Default
user_domain_name = Default
region_name = RegionOne
project_name = service
username = nova
password = CHANGEPASSWORD

[oslo_concurrency]
lock_path = /var/lib/neutron/tmp

[oslo_messaging_amqp]
[oslo_messaging_kafka]
[oslo_messaging_notifications]
[oslo_messaging_rabbit]
[oslo_middleware]
[oslo_policy]
[oslo_reports]
[oslo_versionedobjects]
[placement]
[privsep]
[profiler]
[quotas]
[ssl]
```

#### l3\_agent.ini

`/etc/neutron/l3_agent.ini` 파일을 수정한다. DVR 모드의 핵심 설정이다.

```bash
sudo vi /etc/neutron/l3_agent.ini
```

```bash
[DEFAULT]
interface_driver = openvswitch
agent_mode = dvr_snat
# dvr 활성화

[agent]
[metadata_rate_limiting]
[network_log]
[ovs]
```
*l3\_agent.ini*

> **`agent_mode`**** 옵션 설명**
> 
> - `dvr_snat`: DVR + SNAT 기능을 모두 수행한다. 컨트롤러/네트워크 노드에서 사용하거나, 우리처럼 모든 노드가 SNAT도 처리하는 구조에서 사용
> 
> - `dvr`: DVR만 수행하고 SNAT는 네트워크 노드에 위임. 순수 컴퓨트 전용 노드에 적합
> 
> - `legacy`: 기존 중앙 집중식 라우팅. DVR 미사용

#### ml2\_conf.ini

`/etc/neutron/plugins/ml2/ml2_conf.ini` 파일을 수정한다.

```bash
sudo vi /etc/neutron/plugins/ml2/ml2_conf.ini
```

```bash
[DEFAULT]

[ml2]
type_drivers = flat,vlan
# 우리는 tenant 는 vlan, provider 는 flat 을 사용
tenant_network_types = vlan
mechanism_drivers = openvswitch
extension_drivers = port_security

[ml2_type_flat]
flat_networks = provider,vpn
# flat network 에 provider 와 vpn 을 사용
[ml2_type_geneve]
[ml2_type_gre]

[ml2_type_vlan]
network_vlan_ranges = tenant:100:4000

[ml2_type_vxlan]
[ovn]
[ovn_nb_global]

[ovs]
bridge_mappings = provider:br-provider,vpn:br-vpn,tenant:br-tenant
# 위 네트워크 장치들을 설정할때 ovs 실제 이름과 openstack 에서 인식할 이름을 매핑

[ovs_driver]
[securitygroup]
[sriov_driver]
```

#### openvswitch\_agent.ini

`/etc/neutron/plugins/ml2/openvswitch_agent.ini` 파일을 수정한다.

```bash
sudo vi /etc/neutron/plugins/ml2/openvswitch_agent.ini
```

```bash
[DEFAULT]
enable_distributed_routing = True

[agent]
l2_population = true
enable_distributed_routing = true

[dhcp]
[metadata]
[network_log]

[ovs]
bridge_mappings = provider:br-provider,vpn:br-vpn,tenant:br-tenant
# 위 네트워크 장치들을 설정할때 ovs 실제 이름과 openstack 에서 인식할 이름을 매핑

[securitygroup]
firewall_driver = openvswitch
enable_security_group = true
```
*plugins/ml2/openvswitch\_agent.ini*

> **Neutron 설정 파일 정리**

---

### 💾 Ceph 연결

위 파일들을 다 반영했으면 이제 **Ceph를 연결**해야 한다. Nova가 VM 이미지와 ephemeral 디스크를 Ceph RBD에 저장하려면, 컴퓨트 노드에서 Ceph 클러스터에 접근할 수 있어야 한다.

Ceph 클러스터 구성 자체는 별도 페이지에서 정리했으니 아래 링크를 참고하고, 여기서는 **Nova 컴퓨트 노드에서 Ceph를 연결하는 방법**만 다룬다.

[Untitled](https://app.notion.com/p/2082a86843de80c58e55e356020328e6)

![Ceph RBD 연동과 libvirt secret 등록 흐름](https://blog.pieroot.xyz/api/image-proxy?id=6a636e4d-7cb5-49fe-ae07-f5842bcd7a94&kind=s3&pageId=30d067c0-15d0-80ac-9a5e-f3647167c13c&source=block&blockId=dcf8015f-c881-4c4e-98c1-5af0fe64ea4d)

#### ceph-common 설치

```bash
sudo apt install ceph-common
```

#### Ceph 설정 파일 복사

Ceph 클러스터의 설정 파일과 키링을 컴퓨트 노드로 복사한다. **기존에 동작하는 컴퓨트 노드에서 가져오는 것이 가장 확실하다.**

```bash
# Ceph 클러스터 설정 파일 복사 (Ceph 노드 또는 기존 컴퓨트에서)
scp /etc/ceph/ceph.conf dms-compute5:/etc/ceph/
scp /etc/ceph/ceph.client.nova.keyring dms-compute5:/etc/ceph/
scp /etc/ceph/ceph.client.cinder.keyring dms-compute5:/etc/ceph/
```

> **필요한 파일 목록**
> 
> - `/etc/ceph/ceph.conf`: Ceph 클러스터 설정 (MON 주소 등)
> 
> - `/etc/ceph/ceph.client.nova.keyring`: Nova가 Ceph에 인증할 때 사용하는 키
> 
> - `/etc/ceph/ceph.client.cinder.keyring`: Cinder 볼륨 접근용 키

#### 키링 권한 설정

```bash
# nova 사용자가 읽을 수 있도록 권한 설정
sudo chown ceph:nova /etc/ceph/ceph.client.nova.keyring
sudo chmod 640 /etc/ceph/ceph.client.nova.keyring

sudo chown ceph:cinder /etc/ceph/ceph.client.cinder.keyring
sudo chmod 640 /etc/ceph/ceph.client.cinder.keyring
```

#### libvirt Secret 등록

Nova(libvirt)가 Ceph RBD에 접근하려면 **libvirt secret**을 등록해야 한다. 이 시크릿은 libvirt가 RBD 볼륨을 마운트할 때 인증 정보로 사용된다.

먼저 secret 정의 XML 파일을 생성한다.

```xml
<!-- nova.xml -->
<secret ephemeral='no' private='no'>
  <uuid><CHANGE_NOVA_RBD_SECRET_UUID></uuid>
  <usage type='ceph'>
    <name>client.nova secret</name>
  </usage>
</secret>
```

```xml
<!-- cinder.xml -->
<secret ephemeral='no' private='no'>
  <uuid><CHANGE_CINDER_RBD_SECRET_UUID></uuid>
  <usage type='ceph'>
    <name>client.cinder secret</name>
  </usage>
</secret>
```

> **UUID는 반드시 기존 노드와 동일해야 한다!**
> 
> 위 UUID들은 `nova.conf`의 `rbd_secret_uuid`와 일치해야 하고, **기존에 운영 중인 다른 컴퓨트 노드들과도 동일한 값**을 사용해야 한다. UUID가 다르면 라이브 마이그레이션이 실패하거나 볼륨 연결에 문제가 생긴다.

secret을 등록하고 키 값을 설정한다.

```bash
# Secret 정의
sudo virsh secret-define --file nova.xml
sudo virsh secret-define --file cinder.xml

# 키 값 설정 (Ceph keyring에서 키 추출하여 적용)
sudo virsh secret-set-value --secret <CHANGE_NOVA_RBD_SECRET_UUID> --base64 $(cat client.nova.key)
sudo virsh secret-set-value --secret <CHANGE_CINDER_RBD_SECRET_UUID> --base64 $(cat client.cinder.key)
```

> **키 파일이 없다면?**
> 
> 키링 파일에서 직접 키를 추출할 수 있다.
> 
> ```bash
> # keyring 파일에서 key 값 추출
> ceph auth get-key client.nova > client.nova.key
> ceph auth get-key client.cinder > client.cinder.key
> ```
> 
> 또는 기존 컴퓨트 노드에서 `virsh secret-get-value <uuid>` 명령으로 현재 등록된 키 값을 확인할 수도 있다.

#### Ceph 연결 확인

```bash
# Ceph 클러스터 상태 확인
sudo ceph -s --id nova

# RBD 풀 접근 확인
sudo rbd ls -p vms --id nova
```

정상이면 Ceph 클러스터 상태와 RBD 이미지 목록이 출력된다. ~~여기서 에러 나면 키링부터 다시 확인하자~~

---

### 🚀 서비스 시작 및 노드 등록

모든 설정이 완료되었으면 서비스를 시작하고, 컨트롤러에서 새 노드를 인식시켜야 한다.

#### 컴퓨트 노드에서 서비스 시작

```bash
# Nova Compute 서비스 시작
sudo systemctl restart nova-compute
sudo systemctl enable nova-compute

# Neutron OVS Agent 시작
sudo systemctl restart neutron-openvswitch-agent
sudo systemctl enable neutron-openvswitch-agent

# Neutron L3 Agent 시작
sudo systemctl restart neutron-l3-agent
sudo systemctl enable neutron-l3-agent

# libvirtd 재시작 (Ceph secret 반영)
sudo systemctl restart libvirtd
```

#### 컨트롤러에서 새 노드 발견

Nova는 주기적으로 새 컴퓨트 노드를 자동 발견하지만(기본 300초 간격), **즉시 등록**하려면 컨트롤러에서 직접 실행한다.

```bash
# 컨트롤러에서 실행
sudo nova-manage cell_v2 discover_hosts --verbose
```

> **cell\_v2 discover\_hosts란?**
> 
> OpenStack Nova는 **Cells v2** 아키텍처를 사용하여 대규모 환경에서 컴퓨트 노드들을 관리한다. 새로운 컴퓨트 노드가 추가되면, 해당 노드를 cell에 매핑하는 과정이 필요한데 이게 바로 `discover_hosts`다. 이 과정을 거쳐야 스케줄러가 새 노드에 인스턴스를 배치할 수 있다.
> 
> `nova.conf`의 `[scheduler] discover_hosts_in_cells_interval = 300` 옵션을 설정하면 5분마다 자동으로 수행되지만, 노드 추가 직후에는 수동 실행이 빠르다.

#### 등록 확인

```bash
# Nova 서비스 목록 확인
openstack compute service list

# 예상 출력 (새 노드가 보여야 함)
+----+----------------+----------------+----------+---------+-------+
| ID | Binary         | Host           | Zone     | Status  | State |
+----+----------------+----------------+----------+---------+-------+
|  1 | nova-scheduler | dms-controller | internal | enabled | up    |
|  2 | nova-conductor | dms-controller | internal | enabled | up    |
|  6 | nova-compute   | dms-compute1   | nova     | enabled | up    |
|  7 | nova-compute   | dms-compute2   | nova     | enabled | up    |
| .. | nova-compute   | dms-compute5   | nova     | enabled | up    | ← 새 노드!
+----+----------------+----------------+----------+---------+-------+
```

```bash
# Neutron Agent 목록 확인
openstack network agent list

# Hypervisor 목록 확인 (리소스 할당 상태)
openstack hypervisor list
openstack hypervisor show dms-compute5
```

> **State가 ****`down`****으로 나온다면?**
> 
> 1. 컴퓨트 노드에서 `nova-compute` 서비스가 실행 중인지 확인: `systemctl status nova-compute`
> 
> 1. 로그 확인: `tail -f /var/log/nova/nova-compute.log`
> 
> 1. RabbitMQ 연결 확인: `transport_url`의 호스트네임/IP와 비밀번호가 정확한지 확인
> 
> 1. 방화벽 확인: AMQP 포트(5672)가 열려있는지 확인

#### GPU Passthrough 확인

PCI Passthrough를 설정했다면, 새 노드의 GPU가 정상 인식되는지도 확인한다.

```bash
# PCI 디바이스 목록 확인
openstack resource provider list
openstack resource provider inventory list <provider_uuid>
```

---

### ✅ 핵심 정리

✅ **hostname + /etc/hosts**: 모든 노드에 동일하게 설정. OpenStack 내부 통신의 기본

✅ **Chrony 시간 동기화**: 컨트롤러를 NTP 소스로 지정. 토큰 만료 방지

✅ **OVS 네트워크**: provider(flat) + tenant(vlan) 구조. DVR 모드로 라우팅 분산

✅ **Nova Compute**: KVM 지원 확인 후 설치. `nova.conf`에서 인증, Ceph, PCI 설정

✅ **Neutron Agent**: OVS Agent + L3 Agent(DVR). 4개 설정 파일 모두 반영 필수

✅ **Ceph RBD 연동**: `ceph-common` 설치 → 설정/키링 복사 → libvirt secret 등록

✅ **GPU Passthrough**: `passthrough_whitelist`에 실제 디바이스 정보 기록. 컨트롤러에도 동일한 alias 필요

✅ **노드 등록**: `nova-manage cell_v2 discover_hosts`로 즉시 등록. `openstack compute service list`로 확인

### ⚠️ 주의사항

⚠️ **비밀번호 일관성**: `CHANGEPASSWORD` 부분은 반드시 컨트롤러 Keystone 설정과 동일해야 한다. 하나라도 틀리면 인증 실패

⚠️ **UUID 동기화**: `rbd_secret_uuid`는 모든 컴퓨트 노드에서 동일해야 한다. 라이브 마이그레이션 시 UUID가 다르면 실패

⚠️ **PCI 디바이스 확인**: `passthrough_whitelist`의 `vendor_id`/`product_id`는 반드시 `lspci -nn`으로 **현재 노드의 실제 값**을 확인하고 기록해야 한다

⚠️ **OVS 브릿지 순서**: OVS 브릿지가 먼저 생성되어 있어야 Neutron Agent가 정상 시작된다. 서비스 시작 전 `ovs-vsctl show`로 확인하자

⚠️ **HTTP vs HTTPS**: OpenStack Install Guide 기본은 HTTPS지만, SSL 미적용 환경에서는 모든 URL을 `http://`로 변경해야 한다

⚠️ **로그 확인 습관**: 문제 발생 시 `/var/log/nova/nova-compute.log`와 `/var/log/neutron/*.log`를 가장 먼저 확인하자

### 📚 참고 자료

- [OpenStack Nova Compute 설치 공식 문서 (Latest)](https://docs.openstack.org/nova/latest/install/compute-install.html)

- [Ceph Block Devices and OpenStack 연동 가이드](https://docs.ceph.com/en/reef/rbd/rbd-openstack)

- [Neutron OVS DVR 구성 가이드](https://docs.openstack.org/neutron/latest/admin/deploy-ovs-ha-dvr.html)

- [OpenStack Caracal 릴리즈 노트](https://releases.openstack.org/caracal/index.html)

- [Nova PCI Passthrough 설정 가이드](https://docs.openstack.org/nova/latest/admin/pci-passthrough.html)
