
Nova는 Swift와 함께 OpenStack의 두 가지 Original 프로젝트 중 하나로, OpenStack의 컴퓨트 서비스를 제공
Nova는 인스턴스 수명 주기를 관리하며, 가상 머신의 생성, 크기 조정, 종료 등의 작업을 수행
Openstack은 일반적으로 Standard HW 위에서 빌드되고 수평적으로 확장가능하게 설계됨
Nova는 그 자체로 Hypoervisor는 아니지만 이러한 Hypervisor들을 지원하고 manage
Nova는 여러개의 Hypervisor들을 활용해 Cloud를 Orchestrate할 수 있음
Zone을 사용Nova는 KVM, Xen, VMware, Hyper-V 등 다양한 하이퍼바이저를 지원하여 높은 유연성과 적응성을 제공
KVM (Kernel-based Virtual Machine)
QEMU (Quick Emulator)
UML (User Mode Linux)
VMware
Xen
LXC (Linux Containers)
Bare Metal
Key Pair는 비밀번호 없이 공개 키-개인 키 암호화를 통해 안전한 인증 수단을 제공함Key Pair는 Cloud-Init 프로세스를 통해 인스턴스 이미지에 주입되어, 인스턴스 생성 시 자동으로 설정이 이루어짐
Nova는 분산된 컴포넌트 기반 아키텍처로 설계되어, 각각의 서비스가 독립적으로 동작하면서 상호 통신을 통해 클라우드 환경을 효율적으로 관리할 수 있음
RabbitMQ 또는 AMQP와 같은 메시지 버스를 사용하여 컴포넌트 간의 데이터 흐름을 조율하며, 대규모 클라우드 환경에서도 확장 가능하도록 설계
REST API:
RabbitMQ 또는 AMQP Message Bus:
nova-compute:
nova-scheduler:
nova-console: 인스턴스에 원격 접속을 위한 콘솔 서비스 제공
nova-database: Nova의 메타데이터와 상태 정보를 저장
nova-conductor: nova-compute와 데이터베이스 간의 요청을 중재하여 보안을 강화
nova-conductor를 통해 DB와 통신nova-consoleauth: 콘솔 인증 요청을 관리
Legacy Nova Networking:
nova-network를 사용하여 네트워크를 관리함L2 Agent:
Metadata Service:
Ceilometer Agent:
openstack-ceilometer-compute 에이전트를 사용하여 인스턴스의 메트릭과 사용량 데이터를 수집EC2 API:
nova-ec2를 통해 OpenStack에서 Amazon EC2 호환 API를 제공Console Auth and Proxies:
$ openstack flavor list
+----+-----------+-------+------+-----------+-------+-----------+
| ID | Name | RAM | Disk | Ephemeral | VCPUs | Is Public |
+----+-----------+-------+------+-----------+-------+-----------+
| 1 | m1.tiny | 512 | 1 | 0 | 1 | True |
| 2 | m1.small | 2048 | 20 | 0 | 1 | True |
| 20 | newflavor | 768 | 1 | 0 | 1 | True |
| 3 | m1.medium | 4096 | 40 | 0 | 2 | True |
| 4 | m1.large | 8192 | 80 | 0 | 4 | True |
| 5 | m1.xlarge | 16384 | 160 | 0 | 8 | True |
+----+-----------+-------+------+-----------+-------+-----------+
위와 같이 Openstack이 설치되면서 기본적으로 생성된 Flavor를 확인할 수 있다.
openstaack server create --image <image> \
--flavor <flavor> \
--network <network> \
<instance name>
Flavor가 인스턴스의 size를 결정Nwtwork는 인스턴스가 어디에 attach될지 결정Image는 인스턴스를 부팅한 OS Image 결정$ openstack image list
+--------------------------------------+---------+--------+
| ID | Name | Status |
+--------------------------------------+---------+--------+
| 9b7625df-f764-49a8-9373-6a8727530c7c | cirros3 | active |
| be315e95-ca18-46b4-8ca2-afb6738c7129 | cirros6 | active |
+--------------------------------------+---------+--------+
openstack image show cirros6
+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| checksum | c8fc807773e5354afe61636071771906 |
| container_format | bare |
| created_at | 2025-01-14T12:00:17Z |
| disk_format | qcow2 |
| file | /v2/images/be315e95-ca18-46b4-8ca2-afb6738c7129/file |
| id | be315e95-ca18-46b4-8ca2-afb6738c7129 |
| min_disk | 0 |
| min_ram | 0 |
| name | cirros6 |
| owner | 8dc84595f82b4e6dac4a18f990b05c6d |
| properties | os_hash_algo='sha512', os_hash_value='1103b92ce8ad966e41235a4de260deb791ff571670c0342666c8582fbb9caefe6af07ebb11d34f44f8414b609b29c1bdf1d72ffa6faa39c88e8721d09847952b', os_hidden='False', owner_specified.openstack.md5='', owner_specified.openstack.object='images/cirros6', owner_specified.openstack.sha256='', stores='file' |
| protected | False |
| schema | /v2/schemas/image |
| size | 21430272 |
| status | active |
| tags | |
| updated_at | 2025-01-14T12:00:17Z |
| virtual_size | 117440512 |
| visibility | public |
+------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
이미지를 선택할 때 가장 중요한 것은 min_disk, min_len이다.

$ openstack network list
+--------------------------------------+------------------+--------------------------------------+
| ID | Name | Subnets |
+--------------------------------------+------------------+--------------------------------------+
| 61af13ca-6eb4-4916-9fe7-2e28d401e2bd | external_network | 5a7d4bd3-011c-4c42-9f77-15c1fa9d8b83 |
| 7b34e663-7d34-4c5c-b037-a7d5b47187d2 | intnet | 204c4ca0-3cba-4668-8b55-2ab7e1a132a2 |
+--------------------------------------+------------------+--------------------------------------+
$ openstack server create --flavor 1 --image cirros6 --network intnet instance01
+-------------------------------------+------------------------------------------------+
| Field | Value |
+-------------------------------------+------------------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-AZ:availability_zone | |
| OS-EXT-SRV-ATTR:host | None |
| OS-EXT-SRV-ATTR:hypervisor_hostname | None |
| OS-EXT-SRV-ATTR:instance_name | |
| OS-EXT-STS:power_state | NOSTATE |
| OS-EXT-STS:task_state | scheduling |
| OS-EXT-STS:vm_state | building |
| OS-SRV-USG:launched_at | None |
| OS-SRV-USG:terminated_at | None |
| accessIPv4 | |
| accessIPv6 | |
| addresses | |
| adminPass | NsVLGSj8k6oL |
| config_drive | |
| created | 2025-01-15T05:03:57Z |
| flavor | m1.tiny (1) |
| hostId | |
| id | 4950a73f-064e-44d7-8040-074760bc577e |
| image | cirros6 (be315e95-ca18-46b4-8ca2-afb6738c7129) |
| key_name | None |
| name | instance01 |
| progress | 0 |
| project_id | 8dc84595f82b4e6dac4a18f990b05c6d |
| properties | |
| security_groups | name='default' |
| status | BUILD |
| updated | 2025-01-15T05:03:58Z |
| user_id | 40f117859e3c40178c2cef243e535777 |
| volumes_attached | |
+-------------------------------------+------------------------------------------------+
인스턴스 생성 요청을 위와 같이 보내면 위와 같은 상태임을 확인할 수 있다.
Scheduling:
None으로 표시됨Building:
building으로 표시됨1-1. 요청 파라미터 추출 및 검증
1-2. Flavor 참조 조회
1-3. 부팅 이미지 참조 조회
1-4. 초기 상태를 데이터베이스에 저장
1-5. 메시지 버스를 통해 Conductor로 요청 전달
1-6. 초기 상태 반환
BUILD, task 상태를 SCHEDULING으로 설정하여 반환 2-1. Conductor에서 스케줄러에 요청
2-2. 필터 스케줄러 활성화
2-3. Filter 적용
2-4. Weight 적용
2-5. 최적의 호스트 선택
No Valid Host Scenario
- 가용한 컴퓨트 노드에 요청된 Flavor에 맞는 리소스가 부족한 경우
- 스케줄러가 필터를 적용한 결과, 조건에 맞는 호스트를 찾을 수 없는 경우
2-6. 데이터베이스 업데이트
2-7. Conductor에서 nova-compute로 메시지 전달
3-1. 부팅 미디어 정보 조회
3-2. 네트워크 연결 요청
3-3. 볼륨 연결 요청
3-4. 구성 드라이브 설정
3-5. 하이퍼바이저와 통신
3-6. 인스턴스 상태 업데이트
Logical Group 제공
컴퓨트 노드의 하드웨어 구분
https://www.slideshare.net/slideshow/divide-and-conquer2/34638106

독립적인 OpenStack 배포
서비스 공유
기본 설정
타겟 Region 지정 필요

컴퓨트 노드의 논리적 그룹화
메타데이터로 노드의 기능 설명
다중 호스트 어그리게이트 포함 가능
User에게는 Host Aggregation이 보여지지 않지만, Implicitly Targetable(명시적 사용자 타겟팅)함
openstack aggregate create nodes-with-SSD
openstack aggregate set --property SSD=true nodes_with_ssd
openstack aggregate add host nodes_with_ssd host1
openstack flavor set --property SSD=true m1.large

AWS의 운영 방식에서 영감을 받음
Host Aggregates과 유사한 개념
호스트를 논리적으로 그룹화
주요 요소
명시적 사용자 타겟팅 가능
$ openstack server create --availability-zone AppServers1 ...Host Aggregate를 Availability Zone으로 정의하여 명시적으로 타겟팅 가능
$ openstack aggregate create --zone myzone myaggregaterack-row-1은 Aggregate 이름이며, DC1-rack-row-1은 AZ 이름 Host Aggregation과 다르게 Host는 Multiple AZ에 속할 수 없음
default하게 Host는 Default AZ의 일부임
$ openstack compute service list
+--------------------------------------+----------------+-----------------------+----------+---------+-------+----------------------------+
| ID | Binary | Host | Zone | Status | State | Updated At |
+--------------------------------------+----------------+-----------------------+----------+---------+-------+----------------------------+
| d5fc9f18-4d2a-4723-9139-de85ca14dbfc | nova-conductor | localhost.localdomain | internal | enabled | down | 2025-01-12T07:49:38.000000 |
| c37ce1ad-abdb-4a95-96ec-3b5a1c9c634b | nova-scheduler | localhost.localdomain | internal | enabled | down | 2025-01-12T07:49:35.000000 |
| f0ccd8eb-5715-4e26-807b-d26777e0e264 | nova-compute | localhost.localdomain | nova | enabled | down | 2025-01-12T07:49:35.000000 |
| 254e705f-967f-4f39-8445-df7a9d72ad86 | nova-conductor | localhost | internal | enabled | up | 2025-01-15T06:12:09.000000 |
| 42db026e-b332-4163-8459-cfa2f8be34b8 | nova-scheduler | localhost | internal | enabled | up | 2025-01-15T06:12:01.000000 |
| 6deb28a3-1d51-4d4f-ac4c-d2c53604743a | nova-compute | localhost | nova | enabled | up | 2025-01-15T06:12:05.000000 |
+--------------------------------------+----------------+-----------------------+----------+---------+-------+----------------------------+
우선 위와 같이 compute service들의 list를 확인한다
nova compute 노드의 경우 SIngle Openstack Cloud에 여러개 존재할 수 있다
$ openstack flavor create --id 10 --ram 256 --disk 2 --public m1.tinier
+----------------------------+-----------+
| Field | Value |
+----------------------------+-----------+
| OS-FLV-DISABLED:disabled | False |
| OS-FLV-EXT-DATA:ephemeral | 0 |
| description | None |
| disk | 2 |
| id | 10 |
| name | m1.tinier |
| os-flavor-access:is_public | True |
| properties | |
| ram | 256 |
| rxtx_factor | 1.0 |
| swap | |
| vcpus | 1 |
+----------------------------+-----------+
우선 위와 같이 flavor을 먼저 생성한다
$ openstack keypair create mykeypair >> mykeypair.key
keypair을 생성한 이후
$ openstack server create --image cirros6 --key-name mykeypair --flavor 10 --nic net-id=7b34e663-7d34-4c5c-b037-a7d5b47187d2 instance01
$ openstack server show instance01
+-------------------------------------+----------------------------------------------------------+
| Field | Value |
+-------------------------------------+----------------------------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-AZ:availability_zone | nova |
| OS-EXT-SRV-ATTR:host | localhost |
| OS-EXT-SRV-ATTR:hypervisor_hostname | localhost |
| OS-EXT-SRV-ATTR:instance_name | instance-0000000d |
| OS-EXT-STS:power_state | Running |
| OS-EXT-STS:task_state | None |
| OS-EXT-STS:vm_state | active |
| OS-SRV-USG:launched_at | 2025-01-15T06:24:03.000000 |
| OS-SRV-USG:terminated_at | None |
| accessIPv4 | |
| accessIPv6 | |
| addresses | intnet=10.5.5.29 |
| config_drive | |
| created | 2025-01-15T06:23:54Z |
| flavor | m1.tinier (10) |
| hostId | b4a90f32f5cb554a830f6618f15712a7e9834971293a230d69121ada |
| id | dfbe6675-32cf-468e-b21c-24e596a76d01 |
| image | cirros6 (be315e95-ca18-46b4-8ca2-afb6738c7129) |
| key_name | mykeypait |
| name | instance01 |
| progress | 0 |
| project_id | 8dc84595f82b4e6dac4a18f990b05c6d |
| properties | |
| security_groups | name='default' |
| status | ACTIVE |
| updated | 2025-01-15T06:24:03Z |
| user_id | 40f117859e3c40178c2cef243e535777 |
| volumes_attached | |
+-------------------------------------+----------------------------------------------------------+
이후 위와 같이 인스턴스를 생성허고 active 상태가 된 인스턴스의 정보를 확인할 수 있었다.
만약 여러개의 compute node가 존재한다면 nova-scheduler는 Filter와 Weight, 정책을 기반으로 가장 적합한 Compute Host를 선택한다
$ cat /etc/nova/nova.conf | grep filter
# not filtered. An empty string means that all levels are filtered (string
[filter_scheduler]
#available_filters=nova.scheduler.filters.all_filters
available_filters=nova.scheduler.filters.all_filters
#enabled_filters=ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter
# The default architecture to be used when using the image properties filter.
# Enable filter traces that contain error/exception to a separated place. For
#filter_error_trace=false
# Enable the scheduler to filter compute hosts affined to routed network segment
# Since the introduction of placement pre-filters in 18.0.0 (Rocky), we have
# legacy ``AvailabilityZoneFilter`` scheduler filter. In 24.0.0 (Xena), the
# filter-based approach has been deprecated for removal in favor of the
# deprecated and will be removed when the ``AvailabilityZoneFilter`` filter is
#enable_isolated_aggregate_filtering=false
# Use placement to filter hosts based on image metadata. For more information,
#image_metadata_prefilter=false
/etc/nova/nova.conf애서 현재 사용 가능한 available_filters를 볼 수 있다.
또한 위와 같은 Filter가 만족스럽지 않다면 Custom Filter를 생성할 수도 있다.
$ openstack server image create --name snap1 instance01
+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| created_at | 2025-01-15T07:00:47Z |
| file | /v2/images/bc09e31c-2a05-45c1-b33b-6d102cbb6efe/file |
| id | bc09e31c-2a05-45c1-b33b-6d102cbb6efe |
| min_disk | 2 |
| min_ram | 0 |
| name | snap1 |
| owner | 8dc84595f82b4e6dac4a18f990b05c6d |
| properties | base_image_ref='be315e95-ca18-46b4-8ca2-afb6738c7129', boot_roles='reader,admin,member', hw_cdrom_bus='ide', hw_disk_bus='virtio', hw_input_bus='usb', hw_machine_type='pc', hw_pointer_model='usbtablet', hw_video_model='virtio', hw_vif_model='virtio', image_type='snapshot', instance_uuid='dfbe6675-32cf-468e-b21c-24e596a76d01', os_hidden='False', owner_project_name='admin', owner_specified.openstack.md5='', owner_specified.openstack.object='images/cirros6', owner_specified.openstack.sha256='', owner_user_name='admin', user_id='40f117859e3c40178c2cef243e535777' |
| protected | False |
| schema | /v2/schemas/image |
| status | queued |
| tags | |
| updated_at | 2025-01-15T07:00:47Z |
| visibility | private |
+------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
$ openstack image list
+--------------------------------------+---------+--------+
| ID | Name | Status |
+--------------------------------------+---------+--------+
| 9b7625df-f764-49a8-9373-6a8727530c7c | cirros3 | active |
| be315e95-ca18-46b4-8ca2-afb6738c7129 | cirros6 | active |
| bc09e31c-2a05-45c1-b33b-6d102cbb6efe | snap1 | active |
+--------------------------------------+---------+--------+
이후 위와 같이 추후 이미지에 문제가 생겼을 때 복구할 수 있는 Snapshot을 생성하고 Glance Image List에서 확인할 수 있다.
$ openstack aggregate create --property SSD=true agg1
+-------------------+----------------------------+
| Field | Value |
+-------------------+----------------------------+
| availability_zone | None |
| created_at | 2025-01-15T07:02:32.000000 |
| deleted_at | None |
| hosts | |
| id | 1 |
| is_deleted | False |
| name | agg1 |
| properties | SSD='true' |
| updated_at | 2025-01-15T07:02:33.319967 |
| uuid | None |
+-------------------+----------------------------+
이후 SSD를 지닌 인스턴스에 대한 Host Aggregate를 생성한다.
Aggregate는 Host가 가진 properties를 기준으로 이들을 묶는다.
$ openstack console url show --novnc instance01
+----------+------------------------------------------------------------------------------------------+
| Field | Value |
+----------+------------------------------------------------------------------------------------------+
| protocol | vnc |
| type | novnc |
| url | http://10.0.2.15:6080/vnc_auto.html?path=%3Ftoken%3Dfdab3881-28db-4687-b8c7-22b871a5f4fa |
+----------+------------------------------------------------------------------------------------------+
또한 위 명령어로 브라우저에서 접근 가능한 해당 인스턴스 console의 엔드포인트를 알 수 있다.
$ openstack console log show instance01
위 명령어로 인스턴스에 대한 로그 또한 확인할 수 있다.
| 유형 | Ephemeral Storage | Block Storage | Object Storage | Shared File System Storage |
|---|---|---|---|---|
| 사용 목적 | 운영 체제 실행 및 임시 저장 공간 | 가상 머신에 추가적인 영구 스토리지 제공 | 데이터/파일 저장 (VM 이미지 포함) | 가상 머신에서 공유 가능한 추가 영구 스토리지 제공 |
| 접근 방식 | 파일 시스템을 통해 접근 | 파티션, 포맷, 마운트 가능한 블록 장치 (예: dev/vdc) | REST API를 통해 접근 | 파티션, 포맷, 마운트 가능한 공유 파일 시스템 서비스 |
| 접근 가능한 위치 | 가상 머신 내에서만 접근 가능 | 가상 머신 내에서만 접근 가능 | 어디서나 접근 가능 | 가상 머신 내에서만 접근 가능 |
| 지속 시간 | VM이 종료될 때까지 유지 | 사용자가 삭제할 때까지 유지 | 사용자가 삭제할 때까지 유지 | 사용자가 삭제할 때까지 유지 |
| 관리 주체 | OpenStack Compute | OpenStack Block Storage | OpenStack Object Storage | OpenStack Shared File System Service |
| 일반적인 사용 예 | 10GB 첫 디스크, 30GB 두 번째 디스크 | 1TB 디스크 | 수십 TB의 데이터셋 저장 공간 | 1TB 공유 디스크 |

영구적인 블록 수준 스토리지 제공
블록 장치 생명 주기 관리
1:1 관계
USB 드라이브처럼 생각하면 쉽다스냅샷 관리
볼륨 유형 관리
Nova 및 Horizon과 통합
영구적인 읽기/쓰기 블록 스토리지 제공
인스턴스의 보조 스토리지로 연결 가능
부팅 볼륨으로 사용 가능
볼륨 생명 주기 관리
볼륨 관리
read-only copy관리자 작업으로 수행
Swift에 백업 저장
백업 생성 및 복원
$ cinder backup-create "volume id"운영 한계 설정 가능 : 프로젝트별로 자원 사용 한도를 제한하여 과도한 사용 방지
프로젝트 단위로 적용

Cinder Client
Cinder API
SQL Database
Cinder Scheduler
Cinder Volume
Cinder Backup

1 요청 생성
nova 명령어로 인스턴스 생성 요청 2 API 컴포넌트로 전달
3 스케줄링 및 자원 할당
4 명령 처리
1 데이터 전송 요청
2 iSCSI 또는 NFS를 통한 데이터 연결
3 데이터 경로
/dev/vda와 같은 경로로 마운트됨 /dev/hda)로 데이터가 저장 4 사용자 데이터 송수신
$ cinder service-list
+------------------+---------------------------+------+---------+-------+----------------------------+---------+-----------------+---------------+
| Binary | Host | Zone | Status | State | Updated_at | Cluster | Disabled Reason | Backend State |
+------------------+---------------------------+------+---------+-------+----------------------------+---------+-----------------+---------------+
| cinder-backup | localhost | nova | enabled | up | 2025-01-15T08:09:47.000000 | - | - | |
| cinder-backup | localhost.localdomain | nova | enabled | down | 2025-01-12T07:49:35.000000 | - | - | |
| cinder-scheduler | localhost | nova | enabled | up | 2025-01-15T08:09:42.000000 | - | - | |
| cinder-scheduler | localhost.localdomain | nova | enabled | down | 2025-01-12T07:49:35.000000 | - | - | |
| cinder-volume | localhost.localdomain@lvm | nova | enabled | down | 2025-01-12T07:49:29.000000 | - | - | - |
| cinder-volume | localhost@lvm | nova | enabled | up | 2025-01-15T08:09:46.000000 | - | - | up |
+------------------+---------------------------+------+---------+-------+----------------------------+---------+-----------------+---------------+
우선 위와 같이 cinder 서비스가 구동되고 있는 것을 확인한다.
$ openstack volume create --size 1 vol1
+---------------------+--------------------------------------+
| Field | Value |
+---------------------+--------------------------------------+
| attachments | [] |
| availability_zone | nova |
| bootable | false |
| consistencygroup_id | None |
| created_at | 2025-01-15T08:10:54.821577 |
| description | None |
| encrypted | False |
| id | 86627753-e648-4175-acca-9d27b3458c69 |
| migration_status | None |
| multiattach | False |
| name | vol1 |
| properties | |
| replication_status | None |
| size | 1 |
| snapshot_id | None |
| source_volid | None |
| status | creating |
| type | iscsi |
| updated_at | None |
| user_id | 40f117859e3c40178c2cef243e535777 |
+---------------------+--------------------------------------+
$ openstack volume list
+--------------------------------------+------+-----------+------+-------------+
| ID | Name | Status | Size | Attached to |
+--------------------------------------+------+-----------+------+-------------+
| 86627753-e648-4175-acca-9d27b3458c69 | vol1 | available | 1 | |
+--------------------------------------+------+-----------+------+-------------+
이후 위와 같이 새로운 Volume을 생성하고 확인한다.
$ ip netns exec qrouter-4358fd19-62ea-42d3-be7d-0ef3140dc249 ssh cirros@10.5.5.29
$ ls /dev/
bus loop1 random tty18 tty33 tty49 tty7 ttyS21 ttyS9
console loop2 rfkill tty19 tty34 tty5 tty8 ttyS22 ttyprintk
cpu_dma_latency loop3 root tty2 tty35 tty50 tty9 ttyS23 udmabuf
dma_heap loop4 rtc0 tty20 tty36 tty51 ttyS0 ttyS24 uinput
dri loop5 shm tty21 tty37 tty52 ttyS1 ttyS25 urandom
ecryptfs loop6 snapshot tty22 tty38 tty53 ttyS10 ttyS26 vcs
fb0 loop7 tty tty23 tty39 tty54 ttyS11 ttyS27 vcs1
full mapper tty0 tty24 tty4 tty55 ttyS12 ttyS28 vcsa
fuse mcelog tty1 tty25 tty40 tty56 ttyS13 ttyS29 vcsa1
hidraw0 mem tty10 tty26 tty41 tty57 ttyS14 ttyS3 vcsu
hpet net tty11 tty27 tty42 tty58 ttyS15 ttyS30 vcsu1
hwrng null tty12 tty28 tty43 tty59 ttyS16 ttyS31 vda
input port tty13 tty29 tty44 tty6 ttyS17 ttyS4 vda1
kmsg ppp tty14 tty3 tty45 tty60 ttyS18 ttyS5 vda15
log psaux tty15 tty30 tty46 tty61 ttyS19 ttyS6 vfio
loop-control ptmx tty16 tty31 tty47 tty62 ttyS2 ttyS7 vga_arbiter
loop0 pts tty17 tty32 tty48 tty63 ttyS20 ttyS8 zero
이후 SSH를 통해 인스턴스에 접근하여 vda이외에 디스크가 존재하지 않는 것을 볼 수 있다.
$ openstack server add volume instance01 vol1
+-----------------------+--------------------------------------+
| Field | Value |
+-----------------------+--------------------------------------+
| ID | 86627753-e648-4175-acca-9d27b3458c69 |
| Server ID | dfbe6675-32cf-468e-b21c-24e596a76d01 |
| Volume ID | 86627753-e648-4175-acca-9d27b3458c69 |
| Device | /dev/vdb |
| Tag | None |
| Delete On Termination | False |
+-----------------------+--------------------------------------+
$ ls /dev | grep vd
vda
vda1
vda15
vdb
이후 Volume을 attach하고 SSH를 통해 접근하여 /dev 디렉터리를 확인하면 vdb가 attach된 것을 확인할 수 있다.
sudo mkfs.ext3 /dev/vdb
sudo mkdir /mydisk
sudo mount /dev/vdb /mydisk
하지만 vdb 디스크는 현재 특정 format이 정해지지 않았기 때문에 ext 파일 시스템을 통해 이를 포맷한다.
이후 새로운 dir를 성하고 이를 Volume에 마운트하여준다.
$ openstack volume backup create --name backup1 --force vol1
+-------+--------------------------------------+
| Field | Value |
+-------+--------------------------------------+
| id | 0bd3f476-2169-4f9b-a5b7-c431fcb74516 |
| name | backup1 |
+-------+--------------------------------------+
$ openstack volume backup show backup1
+-----------------------+--------------------------------------+
| Field | Value |
+-----------------------+--------------------------------------+
| availability_zone | None |
| container | volumebackups |
| created_at | 2025-01-15T08:22:03.000000 |
| data_timestamp | 2025-01-15T08:22:03.000000 |
| description | None |
| fail_reason | None |
| has_dependent_backups | False |
| id | 0bd3f476-2169-4f9b-a5b7-c431fcb74516 |
| is_incremental | False |
| name | backup1 |
| object_count | 21 |
| size | 1 |
| snapshot_id | None |
| status | available |
| updated_at | 2025-01-15T08:22:54.000000 |
| volume_id | 86627753-e648-4175-acca-9d27b3458c69 |
+-----------------------+--------------------------------------+
이후 새로운 Backup을 생성하고 이를 확인한다.
Backup은 파일이기 때문에 Object Storage인 Swift를 통해 저장된다.
openstack volume snapshot create --volume vol1 --force snap1
+-------------+--------------------------------------+
| Field | Value |
+-------------+--------------------------------------+
| created_at | 2025-01-15T08:26:05.027417 |
| description | None |
| id | 6d6753ef-19df-41d3-a310-4c31fd98214c |
| name | snap1 |
| properties | |
| size | 1 |
| status | creating |
| updated_at | None |
| volume_id | 86627753-e648-4175-acca-9d27b3458c69 |
+-------------+--------------------------------------+
또한 위 명령어를 통해 snapshot을 생성할 수 있다
openstack command list | grep openstack.volume -A 100
Scalable, Distributed, and Replicated Object Storage
Simple and Powerful RESTful API
High Concurrency Support
Pooled Storage Capacity
Object = File + Metadata

| Consistency | Benefits | Limitations |
|---|---|---|
| Strict | Provide write guarantee | Poor performance at scale |
| Eventual | Excellent performance at scale | Can't be used for object locking or synchronizing |

Geographic Region
데이터를 여러 Geographic Region에 복제하여 지역 전체 장애에도 데이터를 보호함
Availability Zone
각 Geographic Region은 여러 Availability Zone으로 구성되며 한 영역의 장애가 다른 영역에 영향을 주지 않도록 설계됨
Server 분리
데이터를 각 Availability Zone 내의 여러 Server에 분산 저장하여 개별 서버 장애에 대비함
Disk 분산
각 Server 내에서는 데이터를 여러 Disk에 분산하여 동일 Disk에 복제본이 저장되지 않도록 보장함
복제 배치와 부하 분산
Consistent Hashing을 사용해 데이터를 효율적으로 분배하고 자원의 병목현상을 줄이며 부하를 고르게 분산함
내구성과 접근성 제공
여러 수준에서 데이터 복제를 수행하여 Disk, Server, Zone 장애가 발생하더라도 데이터 접근성을 유지함
계층적 구조
RESTful API 기반
https://storage.example.conm/<API Version>/<account>/<container>/<object>
API Version
Swift API의 버전을 나타냄
일반적으로 v1 또는 v2와 같은 형태로, 사용 가능한 API의 기능과 호환성을 정의함
Account
Swift 스토리지에서 데이터를 관리하는 계정
각 계정은 할당된 스토리지와 관련된 인증 정보를 포함하며, 계정 기반으로 데이터 액세스와 사용량이 관리됨
Container
계정 내에서 데이터를 조직화하는 논리적 그룹
파일 시스템의 디렉토리에 해당하며, 컨테이너는 객체의 그룹으로 관리되고 특정 접근 정책을 가질 수 있음
Object
저장되는 개별 데이터 단위로, 파일 또는 데이터 블록을 의미함
Swift의 핵심 구성 요소로, 이름과 메타데이터를 기반으로 저장되고 관리됨
PUT /v1/account/container/objectGET /v1/account/container/object

HTTP
Proxy
Ring
Account Service
Container Service
Object Service
Account Commands
object store account set : 계정 관련 속성을 설정 object store account show : 계정 정보를 조회 object store account unset : 계정 관련 속성을 해제 Container Commands
container create : 새로운 컨테이너를 생성 container delete : 기존 컨테이너를 삭제 container list : 모든 컨테이너 목록을 조회 container save : 컨테이너 데이터를 저장 container set : 컨테이너 속성을 설정 container show : 컨테이너 상세 정보를 조회 container unset : 설정된 컨테이너 속성을 해제 Object Commands
object create : 새로운 객체를 생성하여 저장 object delete : 기존 객체를 삭제 object list : 객체 목록을 조회 object save : 객체 데이터를 저장 object set : 객체 속성을 설정 object show : 객체 상세 정보를 조회 object unset : 설정된 객체 속성을 해제