---
title: "OpenStack의 저장소 부족 문제를 Ceph RBD로 해결하는 완벽 가이드"
description: "OpenStack 컨트롤러 노드의 디스크 용량 부족을 Ceph RBD로 해결하기 위해, Ceph 클라이언트 설치·전용 사용자 권한 설정·Data Pool 및 500 GB RBD 이미지 생성·이미지 매핑·XFS 포맷·fstab 등록·rsync를 이용한 기존 OpenSearch 데이터 이전·Kolla Ansible 설정 수정·서비스 재배포 과정을 단계별로 안내하고, exclusive‑lock 사용 시 발생하는 Permission Denied 문제 해결을 위해 mon 권한에 blocklist 명령을 추가하고, 재부팅 시 자동 매핑·마운트를 위한 rbdmap 서비스 설정까지 포함한다."
date: "2026-01-22"
last_modified: "2026-08-06T00:36:00.000Z"
type: "Post"
tags:
  - "openstack"
  - "ceph"
  - "kolla ansible"
  - "troubleshooting"
  - "storage"
categories:
  - "📗 Docs"
series:
  - "오픈스택 운영"
canonical_url: "https://blog.pieroot.xyz/openstack-ceph-rbd"
markdown_url: "https://blog.pieroot.xyz/openstack-ceph-rbd.md"
---

# OpenStack의 저장소 부족 문제를 Ceph RBD로 해결하는 완벽 가이드

OpenStack 컨트롤러 노드의 디스크 용량 부족을 Ceph RBD로 해결하기 위해, Ceph 클라이언트 설치·전용 사용자 권한 설정·Data Pool 및 500 GB RBD 이미지 생성·이미지 매핑·XFS 포맷·fstab 등록·rsync를 이용한 기존 OpenSearch 데이터 이전·Kolla Ansible 설정 수정·서비스 재배포 과정을 단계별로 안내하고, exclusive‑lock 사용 시 발생하는 Permission Denied 문제 해결을 위해 mon 권한에 blocklist 명령을 추가하고, 재부팅 시 자동 매핑·마운트를 위한 rbdmap 서비스 설정까지 포함한다.

## 서론

Kolla Ansible로 배포한 OpenStack Controller 노드에서 **용량 부족 문제**가 발생했다. 문제의 원인은 단순했다. 디스크 용량이 250GB밖에 되지 않았고, 이 제한된 공간에 각종 로그들이 OpenSearch를 통해 지속적으로 수집되고 있었기 때문이다.

![image](https://blog.pieroot.xyz/api/image-proxy?id=f75ff0a5-bb5c-41ff-a6bd-578663d1de8b&kind=s3&pageId=2f0067c0-15d0-807e-a88e-d41b1c6def62&source=block&blockId=2f5067c0-15d0-8090-a783-f36e968f2b00)

잔여 용량이 30GB 남은 시점에서 대안을 찾아야 했다. 별도의 스토리지로 사용할 수 있는 옵션은 Ceph 뿐이었다. 따라서 이 글에서는 **Ceph RBD(RADOS Block Device)를 Controller 노드에 마운트하고, OpenSearch 데이터 볼륨을 해당 위치로 이전**하는 전체 과정을 다룬다.

> **RBD(RADOS Block Device)란?**
> 
> RBD는 Ceph의 분산 블록 스토리지 기능으로, 가상 블록 디바이스를 제공한다. 씬 프로비저닝(thin-provisioning)을 지원하여 실제 사용량만큼만 물리적 공간을 점유하며, 스냅샷과 클론 기능을 통해 데이터 보호와 복제가 가능하다. OpenStack Cinder, Kubernetes PV 등 다양한 환경에서 백엔드 스토리지로 활용된다.

---

### 1. Ceph 클라이언트 설치 (Controller 노드)

Controller 노드에서 Ceph 클러스터에 접근하기 위해서는 먼저 기본 라이브러리 설치가 필요하다. 아래 명령어를 통해 ceph-common 패키지를 설치한다.

```bash
# Ubuntu/Debian
sudo apt-get update && sudo apt-get install -y ceph-common

# RHEL/CentOS/Rocky/Alma
sudo dnf install -y ceph-common
```

설치가 완료되면 `/etc/ceph` 디렉토리가 자동으로 생성된다. 이 디렉토리는 Ceph 연결에 필요한 설정 파일과 인증 키를 저장하는 위치이다.

```bash
cd /etc/ceph
```

![모두 작업하고 캡쳐하여 필요한 내용이 모두 담겨있다](https://blog.pieroot.xyz/api/image-proxy?id=272531c6-6980-4768-b561-28460276934e&kind=s3&pageId=2f0067c0-15d0-807e-a88e-d41b1c6def62&source=block&blockId=2f5067c0-15d0-8087-aa6e-d0375367fc7a)

---

### 2. Ceph 연결용 User 생성 (Ceph Cluster)

각 Controller에서 Ceph 클러스터에 접근하기 위한 전용 사용자를 생성해야 한다.

![image](https://blog.pieroot.xyz/api/image-proxy?id=35ae4b48-5e9a-4461-bc89-01d7d1568549&kind=s3&pageId=2f0067c0-15d0-807e-a88e-d41b1c6def62&source=block&blockId=2f0067c0-15d0-80a1-bc07-fc4e347046ba)

Ceph 대시보드를 통해 사용자를 생성할 수도 있지만, 향후 대시보드 인터페이스가 변경될 경우를 대비하여 CLI 명령어를 통해 진행하는 것을 권장한다.

> 이 가이드에서는 **cephadm**을 통해 Ceph를 설치한 환경을 기준으로 설명한다. 다른 방법(ceph-deploy, manual 설치 등)으로 설치한 경우에는 관리자 권한을 통해 원격 설정이나 직접 터미널에 접속 가능한 환경을 마련해야 한다.
> 
> [Ceph 클러스터 설치 및 구성: 분산 스토리지 시스템 마스터하기](https://blog.pieroot.xyz/ceph-cluster-setup)

#### 2.1 Ceph 관리자 터미널 접속

아래 명령어를 통해 Ceph 관리자 터미널에 접근한다.

```bash
sudo cephadm shell
```

![image](https://blog.pieroot.xyz/api/image-proxy?id=6d3bda86-f39f-4367-a1ef-82c0645e14f0&kind=s3&pageId=2f0067c0-15d0-807e-a88e-d41b1c6def62&source=block&blockId=2f5067c0-15d0-801c-b7c6-c25173507cbb)

#### 2.2 사용자 및 권한 설정

Controller에서 RBD에 접근하기 위한 사용자와 최소 권한을 설정한다.

```bash
sudo ceph auth get-or-create client.opensearch2rbd \
  mon 'allow r' \
  osd 'allow rwx pool=opensearch_data' \
  mgr 'allow r' \
  -o /etc/ceph/ceph.client.opensearch2rbd.keyring
```

> #### Ceph 권한 구성 요소 상세 설명
> 
> **mon (Monitor)**
> 
> - **역할**: Ceph 클러스터의 상태를 추적하고 관리하는 핵심 데몬. 클러스터 맵(cluster map)을 유지하며, 클러스터의 토폴로지와 상태 정보를 포함한다.
> 
> - **권한 옵션**:
>   - `allow r`: 읽기 권한. 클러스터 맵과 상태 정보 조회 가능.
>   - `allow rw`: 읽기/쓰기 권한. 클러스터 설정 변경 가능.
>   - `allow *`: 모든 권한. Monitor 데몬 완전 제어.
> 
> **osd (Object Storage Daemon)**
> 
> - **역할**: 실제 데이터를 저장하고 복제, 복구, 재조정 등의 작업을 수행하는 데몬. 각 물리적 디스크마다 하나의 OSD가 실행된다.
> 
> - **권한 옵션**:
>   - `allow r`: 데이터 읽기만 가능.
>   - `allow w`: 데이터 쓰기만 가능.
>   - `allow x`: 실행 권한. RADOS 클래스 메서드 실행 가능.
>   - `allow rwx`: 읽기/쓰기/실행 모든 권한.
>   - `pool=<name>`: 특정 풀에만 권한을 제한.
> 
> **mgr (Manager)**
> 
> - **역할**: 클러스터 모니터링, 통계 수집, 대시보드 제공 등의 관리 기능을 담당하는 데몬. 런타임 메트릭과 클러스터 상태를 제공한다.
> 
> - **권한 옵션**:
>   - `allow r`: 클러스터 통계와 상태 정보 읽기 가능.
>   - `allow rw`: 관리 명령 실행 및 설정 변경 가능.
>   - `allow *`: 모든 관리 작업 수행 가능.
> 
> **위 명령어에서 설정한 권한 분석**:
> 
> - `mon 'allow r'`: 클러스터 상태 조회만 가능
> 
> - `osd 'allow rwx pool=opensearch_data'`: opensearch\_data 풀에서 읽기/쓰기/실행 모든 작업 가능
> 
> - `mgr 'allow r'`: 클러스터 통계 및 메트릭 조회만 가능
> 
> 이러한 권한 설정은 **최소 권한 원칙(Principle of Least Privilege)**을 따르며, opensearch2rbd 사용자가 필요한 작업(데이터 저장/조회)만 수행할 수 있도록 제한한다.

생성된 keyring 파일은 `/etc/ceph` 위치에 저장된다.

![image](https://blog.pieroot.xyz/api/image-proxy?id=23846293-ef07-4dee-a94b-03c20e38b85a&kind=s3&pageId=2f0067c0-15d0-807e-a88e-d41b1c6def62&source=block&blockId=2f0067c0-15d0-80f3-9f35-c217a2476f2a)

해당 키를 각 Controller 노드의 동일 위치에 복사해둔다.

---

### 3. Data Pool 생성 (Ceph Cluster)

Controller에서 접근할 Data Pool을 생성해야 한다. Data Pool은 Ceph에서 제공하는 RADOS(Reliable Autonomic Distributed Object Store) 위에 생성되는 **논리적 파티션**이라고 이해하면 된다.

```bash
# Data Pool 생성
ceph osd pool create opensearch_data

# 복제본(Replicas) 개수 지정 (기본값: 3)
ceph osd pool set opensearch_data size 3

# 어떤 애플리케이션이 사용하는 Pool인지 지정 (RBD가 사용)
ceph osd pool application enable opensearch_data rbd

# PG(Placement Group) 개수 지정
ceph osd pool set opensearch_data pg_num 8
```

> **PG(Placement Group) 수 계산 공식**
> 
> 적절한 PG 수는 클러스터 성능에 직접적인 영향을 미친다. Ceph 공식 문서에서 권장하는 계산 공식은 다음과 같다:
> 
> $$
> PG_{total} = \frac{OSD_{count} \times 100}{replica\_size}
> $$
> 
> 예를 들어, OSD가 10개이고 복제본이 3개인 경우:
> 
> - $PG_{total} = \frac{10 \times 100}{3} \approx 333$
> 
> - 가장 가까운 2의 거듭제곱인 256 또는 512를 선택
> 
> 소규모 테스트 환경에서는 8~32개의 PG로 시작하고, 운영 환경에서는 위 공식을 참고하여 설정하는 것을 권장한다.

---

### 4. RBD 이미지 생성 (Ceph Cluster)

위에서 생성한 Pool에 500GB의 실제 볼륨(이미지)을 생성한다. 이미지 이름은 `opensearch1`으로 지정했다.

```bash
rbd create opensearch_data/opensearch1 --size 512000 --image-feature layering,exclusive-lock,object-map,fast-diff
rbd info opensearch_data/opensearch1
```

![image](https://blog.pieroot.xyz/api/image-proxy?id=016227d1-b168-461a-b6de-467ef2277560&kind=s3&pageId=2f0067c0-15d0-807e-a88e-d41b1c6def62&source=block&blockId=2f0067c0-15d0-80b1-aaea-f5ab919f029f)

> **RBD 이미지 기능(Feature) 설명**
> 
> - **layering**: 스냅샷 기반 클론 생성 지원. Copy-on-Write 방식으로 효율적인 복제 가능.
> 
> - **exclusive-lock**: 동시 쓰기 방지를 위한 배타적 잠금. 단일 클라이언트만 쓰기 가능.
> 
> - **object-map**: 할당된 객체 추적. 스냅샷 생성, 내보내기 등의 작업 속도 향상.
> 
> - **fast-diff**: 스냅샷 간 차이 계산 고속화. object-map과 함께 사용 시 효과적.
> 
> **주의**: 일부 커널 버전에서는 특정 기능을 지원하지 않을 수 있다. 호환성 문제 발생 시 `rbd feature disable` 명령어로 비활성화할 수 있다.

---

### 5. Ceph 연결 확인 (Controller 노드)

Controller 노드로 돌아와서 연결 작업을 진행한다.

#### 5.1 설정 파일 복사

앞서 생성한 `ceph.client.opensearch2rbd.keyring` 파일과 Ceph 클러스터의 `ceph.conf` 파일을 Controller 노드로 복사한다.

![image](https://blog.pieroot.xyz/api/image-proxy?id=c725e8c4-d452-4a93-afa8-3e5ba3630e81&kind=s3&pageId=2f0067c0-15d0-807e-a88e-d41b1c6def62&source=block&blockId=2f0067c0-15d0-80c6-bde7-d8067db59445)

#### 5.2 연결 테스트

복사한 keyring과 conf 파일로 실제 연결과 인증이 가능한지 테스트한다.

```bash
ceph -c /etc/ceph/ceph.conf -n client.opensearch2rbd -k /etc/ceph/ceph.client.opensearch2rbd.keyring -s
```

![image](https://blog.pieroot.xyz/api/image-proxy?id=4d1c3b2d-81ea-4136-9667-9684e520f4bd&kind=s3&pageId=2f0067c0-15d0-807e-a88e-d41b1c6def62&source=block&blockId=2f5067c0-15d0-804b-b648-e14dc8c05a35)

위 명령어 실행 결과, 클러스터 상태가 정상적으로 출력되면 연결이 성공한 것이다. 만약 통신이 실패한다면 다음 사항들을 확인한다:

- 네트워크 연결 상태 (방화벽, 포트 개방 여부)

- 계정 정보와 Pool 설정

- keyring 파일 권한 (600 권장)

#### 5.3 RBD 이미지 매핑

Ceph RBD 이미지를 현재 호스트에 매핑한다. 매핑된 디바이스는 `/dev/rbd/<pool>/<image>` 경로에 생성된다.

```bash
sudo rbd map --pool opensearch_data opensearch1 --id opensearch2rbd
```

![image](https://blog.pieroot.xyz/api/image-proxy?id=6e27db65-c84a-4fac-9f6f-cdc380fa2cd7&kind=s3&pageId=2f0067c0-15d0-807e-a88e-d41b1c6def62&source=block&blockId=2f0067c0-15d0-80aa-afaa-f7f073ab4a04)

#### 5.4 파일시스템 포맷

매핑된 이미지를 사용하기 위해 파일시스템으로 포맷한다. 대용량 데이터 저장에 적합한 **XFS**를 사용한다.

```bash
sudo mkfs.xfs -f /dev/rbd/opensearch_data/opensearch1
```

![image](https://blog.pieroot.xyz/api/image-proxy?id=6858d35a-eafc-484a-97d7-ffa2cdb308ed&kind=s3&pageId=2f0067c0-15d0-807e-a88e-d41b1c6def62&source=block&blockId=2f0067c0-15d0-80fe-9b90-d547e2902f50)

> **XFS vs EXT4 선택 기준**
> 
> OpenSearch와 같이 대용량 로그 데이터를 다루는 경우 **XFS**가 더 적합하다.

#### 5.5 마운트 및 fstab 등록

실제 사용할 위치에 마운트를 진행한다. 재부팅 시에도 자동으로 마운트되도록 **fstab**에 등록한다.

```bash
sudo mkdir -p /srv/rbd/opensearch
echo "/dev/rbd/opensearch_data/opensearch1 /srv/rbd/opensearch xfs noatime,_netdev,nofail,x-systemd.requires=network-online.target,x-systemd.automount,x-systemd.idle-timeout=10min 0 2" | sudo tee -a /etc/fstab

sudo systemctl daemon-reload
sudo mount /srv/rbd/opensearch

df -h
```

![image](https://blog.pieroot.xyz/api/image-proxy?id=86142f5a-c903-43ac-9c33-fb781a8c5abd&kind=s3&pageId=2f0067c0-15d0-807e-a88e-d41b1c6def62&source=block&blockId=2f0067c0-15d0-803e-8477-d021570853f7)

> **fstab 옵션 설명**
> 
> - `noatime`: 파일 접근 시간 기록 비활성화. I/O 성능 향상.
> 
> - `_netdev`: 네트워크 장치임을 표시. 네트워크 연결 후 마운트 시도.
> 
> - `nofail`: 마운트 실패 시에도 부팅 계속 진행.
> 
> - `x-systemd.requires=`[`network-online.target`](http://network-online.target/): systemd에서 네트워크 활성화 후 마운트.
> 
> - `x-systemd.automount`: 자동 마운트 활성화.
> 
> - `x-systemd.idle-timeout=10min`: 유휴 시 자동 언마운트 시간.

---

### 6. 기존 OpenSearch 데이터 이전 (Controller 노드)

기존 Docker 볼륨에 존재하던 데이터를 새로 마운트한 위치로 이전한다. 단순 `cp` 명령어 대신 **rsync**를 사용하여 권한, 메타데이터를 보존하면서 안전하게 이전한다.

```bash
rsync -aHAX --numeric-ids --info=progress2 \
  /var/lib/docker/volumes/opensearch/_data/  \
  /srv/rbd/opensearch/
```

#### rsync 옵션 상세 설명

**`-aHAX`**** 옵션 조합**:

- `-a` (archive): 권한, 소유자, 타임스탬프, 심볼릭 링크 등 대부분의 메타데이터를 유지하면서 복사

- `-H`: 하드 링크 보존. 같은 inode를 공유하던 파일 구조 유지

- `-A`: ACL(접근 제어 목록) 보존

- `-X`: 확장 속성(xattr) 보존. SELinux 컨텍스트 등도 유지

이 조합은 **원본을 최대한 그대로 옮기기 위한 옵션**이다. Docker 볼륨의 권한, 소유자, 라벨이 변경되면 컨테이너가 오동작할 수 있기 때문에 반드시 사용해야 한다.

**`--numeric-ids`**:

- 사용자/그룹을 이름이 아니라 **UID/GID 숫자 그대로** 복사

- 마이그레이션 대상 서버에서 `/etc/passwd` 계정명이 다르더라도 UID/GID가 같으면 권한이 유지됨

- 컨테이너 UID 매핑을 고려할 때 안전한 선택

**`--info=progress2`**:

- 전송 진행률을 요약 형식으로 표시

- 전체 전송 속도, 남은 파일 수, 예상 완료 시간 등을 실시간으로 표시

- 대용량 데이터 이동 시 진행 상황 모니터링에 유용

이전이 완료되면 `rbd0` 볼륨에 기존 데이터가 정상적으로 올라간 것을 확인할 수 있다. *250GB 중 142GB가 OpenSearch 데이터였으니 용량 부족이 발생할 수밖에 없었다.*

![image](https://blog.pieroot.xyz/api/image-proxy?id=11c31980-d692-4e8c-b867-0b2cc1825b49&kind=s3&pageId=2f0067c0-15d0-807e-a88e-d41b1c6def62&source=block&blockId=2f5067c0-15d0-8095-a97e-f12b3e0eeb51)

---

### 7. Kolla Ansible globals.yml 수정

Kolla Ansible로 OpenSearch를 배포했기 때문에, 컨테이너의 볼륨 위치를 변경하려면 `globals.yml` 파일을 수정해야 한다.

변경 사항은 간단하다. 다음 한 줄을 추가하면 된다:

```yaml
opensearch_datadir_volume: "/srv/rbd/opensearch"
```

OpenSearch의 기본 볼륨 설정은 다음과 같이 구성되어 있다:

```bash
opensearch_default_volumes:
  - " node_config_directory /opensearch/: container_config_directory /"
  - "/etc/localtime:/etc/localtime:ro"
  - " '/etc/timezone:/etc/timezone:ro' if ansible_facts.os_family == 'Debian' else '' "
  - " opensearch_datadir_volume :/var/lib/opensearch/data"
  - "kolla_logs:/var/log/kolla/"
```

`opensearch_datadir_volume` 변수만 수정하면 원하는 위치를 데이터 볼륨 경로로 마운트할 수 있다.

---

### 8. 서비스 재배포

마지막으로 다음 순서로 작업을 완료한다:

1. Controller 노드의 OpenSearch 컨테이너 종료

1. `rsync` 명령어로 최종 백업 진행 (데이터 정합성 보장)

1. Kolla Ansible로 재배포

```bash
kolla-ansible reconfigure -i multinode --limit control
```

---

### 9. 삽질의 역사: 재부팅 후 rbd map Permission Denied 😭

모든 설정을 마치고 안심하며 Controller 노드를 재부팅했다. 그런데 `rbd map`을 수행하면 **Permission Denied** 오류가 발생했다.

```bash
sudo rbd map --pool opensearch_data opensearch1 --id opensearch2rbd
rbd: sysfs write failed
In some cases useful info is found in syslog - try "dmesg | tail".
rbd: map failed: (13) Permission denied
```

`ceph -s` 명령어로 클러스터 연결은 정상적으로 확인되는데, map만 실패하는 상황이었다. `dmesg | tail`을 확인해보니 원인이 명확했다.

```bash
[58508.476702] rbd: rbd0: breaking header lock owned by client92169142
[58508.477394] rbd: rbd0: failed to blocklist client92169142: -13
[58508.477399] rbd: rbd0: failed to acquire lock: -13
```

#### 9.1 원인 분석

RBD 이미지에 `exclusive-lock` 기능이 활성화되어 있기 때문에, 한 번에 하나의 클라이언트만 쓰기 lock을 잡을 수 있다. 재부팅 전에 `client92169142`가 lock을 보유하고 있었는데, 재부팅 과정에서 lock이 정상적으로 해제되지 않은 채 남아있었다.

새로운 클라이언트가 map을 시도하면서 이전 lock holder를 **blocklist에 추가**하려고 했지만, 이 blocklist 작업은 **Monitor에 명령을 보내는 것**이다. 문제는 `opensearch2rbd` 사용자의 mon 권한이 `allow r`(읽기 전용)이라서 **blocklist 명령을 실행할 권한이 없었던 것**이다.

> **핵심 포인트**: `exclusive-lock` 기능을 사용하는 RBD 이미지를 커널 클라이언트(krbd)로 map하는 경우, lock 경합 시 이전 holder를 blocklist하기 위한 mon 권한이 **반드시** 필요하다. 처음 map할 때는 lock을 잡고 있는 이전 클라이언트가 없었기 때문에 blocklist 요청 자체가 필요 없어서 문제가 드러나지 않았다.

#### 9.2 해결 방법

Ceph 클러스터(cephadm shell)에서 `opensearch2rbd` 사용자의 **mon 권한에 blocklist 명령 허용**을 추가한다.

```bash
sudo cephadm shell
```

```bash
ceph auth caps client.opensearch2rbd \
  mon 'allow r, allow command "osd blocklist"' \
  osd 'allow rwx pool=opensearch_data' \
  mgr 'allow r'
```

> **주의**: `ceph auth caps`는 기존 권한을 **전체 덮어쓰기**한다. 따라서 기존 osd, mgr 권한도 반드시 함께 명시해야 한다. 누락하면 해당 권한이 사라진다.

권한 변경 후 Controller 노드에서 다시 map을 시도하면 정상적으로 동작한다.

```bash
sudo rbd map --pool opensearch_data opensearch1 --id opensearch2rbd
```

---

### 10. 재부팅 시 자동 RBD 매핑: rbdmap 서비스

위 문제를 해결한 뒤, 한 가지 더 고민이 남았다. 매번 재부팅할 때마다 수동으로 `rbd map`을 실행할 수는 없다. `ceph-common` 패키지에 포함된 **`rbdmap`**** 서비스**를 활용하면 부팅 시 자동으로 RBD 이미지를 map/mount하고, 종료 시 unmount/unmap을 처리해준다.

#### 10.1 `/etc/ceph/rbdmap` 파일 설정

`rbdmap` 서비스는 `/etc/ceph/rbdmap` 설정 파일을 파싱하여 어떤 이미지를 map할지 결정한다. 형식은 `IMAGESPEC    RBDOPTS`이며, 탭이나 공백으로 구분한다.

```bash
sudo vi /etc/ceph/rbdmap
```

다음 내용을 추가한다:

```javascript
opensearch_data/opensearch1    id=opensearch2rbd,keyring=/etc/ceph/ceph.client.opensearch2rbd.keyring
```

> **rbdmap 설정 파일 형식**
> 
> ```javascript
> IMAGESPEC    RBDOPTS
> ```
> 
> - **IMAGESPEC**: `<pool>/<image>` 형식으로 RBD 이미지를 지정
> 
> - **RBDOPTS**: `rbd map` 명령에 전달할 옵션들을 쉼표로 구분하여 지정
>   - `id`: Ceph 사용자 이름 (client. 접두사 제외)
>   - `keyring`: 인증 키링 파일 경로
>   - `lock_on_read`, `queue_depth` 등 추가 옵션도 지정 가능

#### 10.2 fstab 수정

`rbdmap` 서비스는 map 후 fstab에서 `noauto` 옵션이 설정된 항목을 찾아 자동으로 mount해준다. 따라서 기존 fstab 항목을 수정해야 한다.

```bash
sudo vi /etc/fstab
```

기존 항목을 다음과 같이 변경한다:

```bash
# 기존 항목 (삭제 또는 주석처리)
# /dev/rbd/opensearch_data/opensearch1 /srv/rbd/opensearch xfs noatime,_netdev,nofail,x-systemd.requires=network-online.target,x-systemd.automount,x-systemd.idle-timeout=10min 0 2

# rbdmap 서비스와 연동하는 새 항목
/dev/rbd/opensearch_data/opensearch1 /srv/rbd/opensearch xfs noauto,noatime 0 0
```

> **왜 ****`noauto`****로 변경하는가?**
> 
> rbdmap 서비스가 RBD map → fstab의 `noauto` 항목 mount → 종료 시 unmount → unmap 순서를 자동으로 처리해준다. 기존의 `_netdev`, `x-systemd.*` 옵션들은 rbdmap 서비스가 대신 관리하므로 더 이상 필요하지 않다.

#### 10.3 rbdmap 서비스 활성화

```bash
sudo systemctl enable rbdmap.service
```

#### 10.4 동작 확인

현재 매핑을 해제한 뒤 rbdmap 서비스로 다시 map/mount가 되는지 테스트한다.

```bash
# 현재 매핑 해제
sudo umount /srv/rbd/opensearch
sudo rbd unmap /dev/rbd/opensearch_data/opensearch1

# rbdmap 서비스로 map + mount
sudo systemctl start rbdmap.service

# 확인
rbd showmapped
df -h | grep rbd
```

> **rbdmap 서비스 동작 흐름**
> 
> ```javascript
> 부팅 → 네트워크 활성화 → rbdmap.service 시작
>   → /etc/ceph/rbdmap 파싱
>   → rbd map 수행
>   → /etc/fstab에서 noauto 항목 찾아서 mount
>   → 종료 시 자동 unmount + unmap
> ```
> 
> shutdown 시 자동으로 `unmap`이 수행되므로, 다음 재부팅 때 이전 lock holder가 남아있는 문제(9장의 blocklist 이슈)가 발생할 확률이 크게 줄어든다.

---

### 마무리

이 가이드에서는 Ceph RBD를 활용하여 OpenStack Controller 노드의 용량 부족 문제를 해결하는 방법을 다루었다. 핵심 단계를 요약하면 다음과 같다:

1. **Ceph 클라이언트 설치**: Controller 노드에 ceph-common 패키지 설치

1. **사용자 권한 설정**: 최소 권한 원칙에 따른 전용 사용자 생성

1. **Pool 및 RBD 이미지 생성**: 논리적 저장 공간 구성

1. **마운트 및 데이터 이전**: rsync를 통한 안전한 데이터 마이그레이션

1. **Kolla Ansible 설정 변경**: 새로운 볼륨 경로 반영

1. **Ceph 사용자 권한 보완**: exclusive-lock 사용 시 blocklist 권한 추가

1. **rbdmap 서비스 설정**: 재부팅 시 자동 RBD 매핑/마운트 구성

이 방법은 OpenSearch뿐만 아니라 다른 서비스의 데이터 볼륨 확장에도 동일하게 적용할 수 있다.

---

### 참고 자료

- [Ceph 공식 문서 - RBD Exclusive Locks](https://docs.ceph.com/en/reef/rbd/rbd-exclusive-locks/)

- [Ceph 공식 문서 - rbdmap](https://docs.ceph.com/en/reef/man/8/rbdmap/)

- [Red Hat Ceph Storage - Block Device Guide: rbdmap 서비스](https://docs.redhat.com/en/documentation/red_hat_ceph_storage/4/html/block_device_guide/ceph-block-device-commands)
