C15-OpenStack 儲存服務 1:Cinder 區塊儲存與後端整合

0. 環境與準備

0.1 本課環境

主機角色管理網 IP
jmp001學員操作機(OpenStack CLI),接在外部網段 192.168.100.0/2410.127.0.3
ctl001 / ctl002 / ctl003控制節點:cinder_api、cinder_scheduler10.127.0.4 / .14 / .15
scp001儲存節點:cinder_volume(LVM driver,後端名稱 lvm-1)、tgtd(iSCSI target)10.127.0.7
scp002運算節點:nova_compute、nova_libvirt、iscsid。你的 VM 放在這台10.127.0.18

講師已建立全班共用的環境,請不要修改或刪除:

資源名稱說明
Network / Router / SGc15-net(192.168.15.0/24)、c15-router、c15-sg讓你的 VM 能綁 Floating IP,從 jmp001 SSH 進去。SG 放行 ICMP 與 TCP 22
QoS Specc15-gold-qosconsumer front-end:total_iops_sec=500、total_bytes_sec=20971520(20 MiB/s)
Volume Typec15-goldvolume_backend_name=lvm-1,並關聯 c15-gold-qos
Volume Typec15-nowherevolume_backend_name=no-such-backend:故意指向不存在的後端

本課 volume 在 scp001 上建立,VM 在 scp002 上跑,兩台之間用 iSCSI 連線。這正是 p.6、p.8 說的「LVM 例外」:target 在 cinder-volume 所在的主機上。

C15 本課的控制路徑與資料路徑 jmp001 以 CLI 呼叫控制節點上的 cinder-api(:8776)。cinder-api 以 RPC 交給 cinder-scheduler 選擇後端,再交給 scp001 上的 cinder-volume(lvm-1)。cinder-volume 在 VG cinder-volumes 的 thin pool 中建立 volume-ID 的 thin LV,snapshot 為 _snapshot-ID,由 snapshot 建立的 volume 是另一個 thin LV。attach 時 tgtd 在 scp001 的 10.127.0.7:3260 匯出 iSCSI target,以 CHAP 驗證;scp002 的 iscsid 登入後主機出現 /dev/sdX,nova_libvirt 把它以 virtio 掛給 VM 成為 vdb,並在 iotune 套用 front-end QoS。Guest 內 /sys/block/vdb/serial 是 volume ID 前 20 碼。資料路徑從 scp002 直接到 scp001,不經過控制節點。cinder-backup 未部署。 控制路徑 資料路徑 資料不經過控制節點, 也不經過 cinder_volume jmp001 openstack CLI ssh cirros@FIP ctl001 / ctl002 / ctl003(控制節點) cinder-backup 未部署 cinder-scheduler ×3 host@backend#pool c15-nowhere 在這裡失敗 cinder-api :8776 attachment API REST scp001(storage) 10.127.0.7 cinder_volume driver:LVM(lvm-1) tgtd iSCSI target :3260 RPC(RabbitMQ):建立 / 匯出 / 刪除 VG cinder-volumes / thin pool volume-<VOL>    c15-stuNN-vol _snapshot-<SNAP>  c15-stuNN-snap volume-<CLONE>   c15-stuNN-clone 都是同一個 pool 裡的 thin LV(Origin 欄位記錄來源) backing store scp002(compute) 10.127.0.18 iscsid 登入 target(os-brick) nova_compute connector ・ attachment attachment-create / update / complete /dev/sdX ← by-path/ip-10.127.0.7:3260-iscsi-…<VOL> nova_libvirt(QEMU) vdb ← /dev/sdX <iotune> 500 IOPS / 20 MiB/s c15-stuNN-vm(cirros) /dev/vdb serial = <VOL> 前 20 碼 Boot from Local:vda 在 scp002 本機 iSCSI CHAP
本課的控制路徑與資料路徑

⚠️ 規則

  • 你使用的是和講師相同的管理員權限,只操作名稱有你編號的資源
  • 本環境沒有部署 cinder-backup。不要執行 volume backup create:它會留下一筆 error 紀錄,而且因為沒有 backup 服務,這筆紀錄無法用 API 刪除(D5 會說明)
  • 預期輸出是示意,UUID、IP、時間會與你看到的不同

0.2 準備,並先把 VM 建起來

0.2 和 0.3 作用的位置:

Part 0 作用的位置 Part 0 作用的位置。0.2 作用在 nova-api → scp002:建立 c15-stuNN-vm(cirros,指定在 scp002,vda 是本機磁碟);0.3 作用在 cinder-api:service list:scheduler ×3 與 scp001 的 cinder-volume 都是 up;沒有 cinder-backup;0.3 作用在 cinder-scheduler:backend pool list:唯一的 pool scp001@lvm-1#lvm-1 及其容量與能力。 ctl001 / ctl002 / ctl003(控制節點) scp001(storage) 10.127.0.7 VG cinder-volumes / thin pool scp002(compute) 10.127.0.18 CLI RPC:建立・匯出・擴充・刪除 attach / detach backing store iSCSI jmp001所有指令都在這裡下ssh 進節點或 VM 觀察 cinder-api:8776type・attachment0.3 cinder-schedulerhost@backend#pool依 type 選後端0.3 cinder-backup未部署0.3 nova-api建 VM・attach0.2 cinder_volumeLVM driver(lvm-1)0.3 tgtdiSCSI target :3260 volume-<VOL> c15-stuNN-vol _snapshot-<SNAP> c15-stuNN-snap volume-<CLONE> c15-stuNN-clone iscsid登入 target nova_computeos-brick・connector0.2 /dev/sdX ← by-path/ip-10.127.0.7:3260-…<VOL> nova_libvirt(QEMU)vdb ← /dev/sdX・<iotune> c15-stuNN-vm(cirros)vda 在本機・vdb = volume0.2 標籤=這一步作用的位置(指令都在 jmp001 下);淡色=這個 Part 不會碰到。點線=控制路徑,粗線=資料路徑 0.2nova-api → scp002:建立 c15-stuNN-vm(cirros,指定在 scp002,vda 是本機磁碟) 0.3cinder-api:service list:scheduler ×3 與 scp001 的 cinder-volume 都是 up;沒有 cinder-backup 0.3cinder-scheduler:backend pool list:唯一的 pool scp001@lvm-1#lvm-1 及其容量與能力
Part 0 作用的位置:0.2 nova 在 scp002 建 VM、0.3 查 Cinder 服務與後端

VM 開機需要一點時間,所以先送出建立指令,再往下看其他東西。

指令
# [jmp001]
export NN=01                                     # ← 換成你的學員編號(01–20)
source ~/venv/bin/activate
source ~/creds/stu${NN}-openrc.sh
echo "c15-stu${NN}"
openstack server create c15-stu${NN}-vm --image cirros --flavor m1.tiny \
  --network c15-net --security-group c15-sg \
  --availability-zone nova:scp002-6164930-iaas -c id -c status

預期輸出:

預期輸出
c15-stu01
+--------+--------------------------------------+
| Field  | Value                                |
+--------+--------------------------------------+
| id     | 6c544407-de12-4533-8c24-7a3ff8b3caf4 |
| status | BUILD                                |
+--------+--------------------------------------+

0.3 Cinder 的服務與後端(p.6、9、18)

指令
# [jmp001]
openstack volume service list
openstack volume backend pool list --long -f yaml

預期輸出:

預期輸出
+------------------+---------------------------+------+---------+-------+----------------------------+
| Binary           | Host                      | Zone | Status  | State | Updated At                 |
+------------------+---------------------------+------+---------+-------+----------------------------+
| cinder-scheduler | ctl002-6161063-iaas       | nova | enabled | up    | 2026-11-07T19:54:58.000000 |
| cinder-scheduler | ctl001-6161060-iaas       | nova | enabled | up    | 2026-11-07T19:54:58.000000 |
| cinder-scheduler | ctl003-6161069-iaas       | nova | enabled | up    | 2026-11-07T19:54:53.000000 |
| cinder-volume    | scp001-6161072-iaas@lvm-1 | nova | enabled | up    | 2026-11-07T19:54:59.000000 |
+------------------+---------------------------+------+---------+-------+----------------------------+
- Capabilities:
    QoS_support: false
    allocated_capacity_gb: 0
    backend_state: up
    cacheable: true
    driver_version: 3.0.0
    filter_function: null
    free_capacity_gb: 475.0
    goodness_function: null
    location_info: LVMVolumeDriver:scp001-6161072-iaas:cinder-volumes:thin:0
    max_over_subscription_ratio: '20.0'
    multiattach: true
    pool_name: lvm-1
    provisioned_capacity_gb: 0.0
    reserved_percentage: 0
    storage_protocol: iSCSI
    thick_provisioning_support: false
    thin_provisioning_support: true
    timestamp: '2026-11-07T19:54:09.468097'
    total_capacity_gb: 475.0
    total_volumes: 1
    vendor_name: Open Source
    volume_backend_name: lvm-1
  Name: scp001-6161072-iaas@lvm-1#lvm-1

Part A:用 Volume Type 申請 Volume(p.4、7、19)

下圖標出這一節每一步作用在哪個元件上(淡色的是這一節不會碰到的):

Part A 作用的位置 Part A 作用的位置。A1 作用在 cinder-api:列出 type c15-gold / c15-nowhere 與 QoS c15-gold-qos:只是資料庫裡的定義;A2 作用在 cinder-scheduler:依 c15-gold 的 volume_backend_name=lvm-1 選中 scp001@lvm-1#lvm-1;A2 作用在 cinder_volume → LV:在 thin pool 建出 volume-<VOL>;os-vol-host-attr:host 就是這裡;A3 作用在 cinder-scheduler:c15-nowhere 找不到後端 → volume 進 error,原因寫進 message list。 ctl001 / ctl002 / ctl003(控制節點) scp001(storage) 10.127.0.7 VG cinder-volumes / thin pool scp002(compute) 10.127.0.18 CLI RPC:建立・匯出・擴充・刪除 attach / detach backing store iSCSI jmp001所有指令都在這裡下ssh 進節點或 VM 觀察 cinder-api:8776type・attachmentA3A2A1 cinder-schedulerhost@backend#pool依 type 選後端A3A2 cinder-backup未部署 nova-api建 VM・attach cinder_volumeLVM driver(lvm-1)A2 tgtdiSCSI target :3260 volume-<VOL> c15-stuNN-volA2 _snapshot-<SNAP> c15-stuNN-snap volume-<CLONE> c15-stuNN-clone iscsid登入 target nova_computeos-brick・connector /dev/sdX ← by-path/ip-10.127.0.7:3260-…<VOL> nova_libvirt(QEMU)vdb ← /dev/sdX・<iotune> c15-stuNN-vm(cirros)vda 在本機・vdb = volume 標籤=這一步作用的位置(指令都在 jmp001 下);淡色=這個 Part 不會碰到。點線=控制路徑,粗線=資料路徑 A1cinder-api:列出 type c15-gold / c15-nowhere 與 QoS c15-gold-qos:只是資料庫裡的定義 A2cinder-scheduler:依 c15-gold 的 volume_backend_name=lvm-1 選中 scp001@lvm-1#lvm-1 A2cinder_volume → LV:在 thin pool 建出 volume-<VOL>;os-vol-host-attr:host 就是這裡 A3cinder-scheduler:c15-nowhere 找不到後端 → volume 進 error,原因寫進 message list
Part A 作用的位置:A1 cinder-api、A2 scheduler → cinder_volume → LV、A3 scheduler 失敗

A1. 講師準備的兩個 Type

指令
# [jmp001]
openstack volume type list --long
openstack volume qos list

預期輸出:

預期輸出
+--------------------------------------+-------------+-----------+-------------------------------+---------------------------------------+
| ID                                   | Name        | Is Public | Description                   | Properties                            |
+--------------------------------------+-------------+-----------+-------------------------------+---------------------------------------+
| 95a89e5c-c712-4266-828f-2d4a14b6046d | c15-nowhere | True      | C15: 指向不存在的後端         | volume_backend_name='no-such-backend' |
| 6f460bd9-a9c6-4708-bfa8-eda995cb4beb | c15-gold    | True      | C15: LVM 後端 + front-end QoS | volume_backend_name='lvm-1'           |
| cf1a0609-3669-4736-8640-e15bd45e7867 | __DEFAULT__ | True      | Default Volume Type           |                                       |
+--------------------------------------+-------------+-----------+-------------------------------+---------------------------------------+
+--------------------------------------+--------------+-----------+--------------+--------------------------------------------------+
| ID                                   | Name         | Consumer  | Associations | Properties                                       |
+--------------------------------------+--------------+-----------+--------------+--------------------------------------------------+
| 617f03c2-bc47-44f6-8779-3eaa4c1862f4 | c15-gold-qos | front-end | c15-gold     | total_bytes_sec='20971520', total_iops_sec='500' |
+--------------------------------------+--------------+-----------+--------------+--------------------------------------------------+

A2. 建立 Volume,看它落在哪裡

指令
# [jmp001]
openstack volume create c15-stu${NN}-vol --type c15-gold --size 1 -c id -c status
sleep 3
openstack volume show c15-stu${NN}-vol -c status -c type -c size -c os-vol-host-attr:host
export VOL=$(openstack volume show c15-stu${NN}-vol -f value -c id); echo $VOL

預期輸出:

預期輸出
+--------+--------------------------------------+
| Field  | Value                                |
+--------+--------------------------------------+
| id     | 02229066-fa48-4f05-97f3-556246776fd9 |
| status | creating                             |
+--------+--------------------------------------+
+-----------------------+---------------------------------+
| Field                 | Value                           |
+-----------------------+---------------------------------+
| os-vol-host-attr:host | scp001-6161072-iaas@lvm-1#lvm-1 |
| size                  | 1                               |
| status                | available                       |
| type                  | c15-gold                        |
+-----------------------+---------------------------------+
02229066-fa48-4f05-97f3-556246776fd9

A3. 找不到後端的 Volume

指令
# [jmp001]
openstack volume create c15-stu${NN}-bad --type c15-nowhere --size 1 -c status
sleep 5
openstack volume show c15-stu${NN}-bad -c status -c os-vol-host-attr:host
export BAD=$(openstack volume show c15-stu${NN}-bad -f value -c id)
openstack --os-volume-api-version 3.3 volume message list -f value -c "Resource UUID" -c "User Message" | grep $BAD

預期輸出:

預期輸出
+--------+----------+
| Field  | Value    |
+--------+----------+
| status | creating |
+--------+----------+
+-----------------------+-------+
| Field                 | Value |
+-----------------------+-------+
| os-vol-host-attr:host | None  |
| status                | error |
+-----------------------+-------+
494e6297-3ab4-4bcb-8d47-b031566aa7b1 schedule allocate volume:Could not find any available weighted backend.

Part B:後端上的實體(p.8、9)

下圖標出這一節每一步作用在哪個元件上(淡色的是這一節不會碰到的):

Part B 作用的位置 Part B 作用的位置。B 作用在 scp001 LV:lvs 看到 volume-<VOL>:thin LV、1 GiB、使用率約 0%;B 作用在 scp001 tgtd:查不到這個 volume 的 target(0):還沒 attach 就不會匯出。 ctl001 / ctl002 / ctl003(控制節點) scp001(storage) 10.127.0.7 VG cinder-volumes / thin pool scp002(compute) 10.127.0.18 CLI RPC:建立・匯出・擴充・刪除 attach / detach backing store iSCSI jmp001所有指令都在這裡下ssh 進節點或 VM 觀察 cinder-api:8776type・attachment cinder-schedulerhost@backend#pool依 type 選後端 cinder-backup未部署 nova-api建 VM・attach cinder_volumeLVM driver(lvm-1) tgtdiSCSI target :3260B volume-<VOL> c15-stuNN-volB _snapshot-<SNAP> c15-stuNN-snap volume-<CLONE> c15-stuNN-clone iscsid登入 target nova_computeos-brick・connector /dev/sdX ← by-path/ip-10.127.0.7:3260-…<VOL> nova_libvirt(QEMU)vdb ← /dev/sdX・<iotune> c15-stuNN-vm(cirros)vda 在本機・vdb = volume 標籤=這一步作用的位置(指令都在 jmp001 下);淡色=這個 Part 不會碰到。點線=控制路徑,粗線=資料路徑 Bscp001 LV:lvs 看到 volume-<VOL>:thin LV、1 GiB、使用率約 0% Bscp001 tgtd:查不到這個 volume 的 target(0):還沒 attach 就不會匯出
Part B 作用的位置:scp001 的 LV 與 tgtd
指令
# [jmp001]
ssh 10.127.0.7 "sudo lvs -o lv_name,lv_attr,lv_size,origin,data_percent cinder-volumes" | grep -E "LV|pool|$VOL"
ssh 10.127.0.7 "sudo docker exec tgtd tgtadm --lld iscsi --mode target --op show" | grep -c $VOL

預期輸出:

預期輸出
  LV                                          Attr       LSize   Origin Data%
  cinder-volumes-pool                         twi-aotz-- 475.00g        0.00
  volume-02229066-fa48-4f05-97f3-556246776fd9 Vwi-a-tz--   1.00g        0.00
0

Part C:Attach 與資料路徑(p.11、12、15、4)

下圖標出這一節每一步作用在哪個元件上(淡色的是這一節不會碰到的):

Part C 作用的位置 Part C 作用的位置。C1 作用在 nova-api → nova_compute:server add volume:volume 狀態 reserved → attaching → in-use;C2 作用在 cinder-api:attachment 記錄 connection_info:target IQN、portal、LUN(CHAP 已濾掉);C3 作用在 scp001 tgtd:匯出 volume-<VOL> 為 iSCSI target,backing store 就是那個 LV;C4 作用在 scp002 iscsid:登入 target,主機出現 /dev/sdX(by-path 名稱含 VOL ID);C5 作用在 scp002 nova_libvirt:/dev/sdX 以 virtio 交給 VM 成為 vdb,<iotune> 套用 front-end QoS;C6 作用在 VM(ssh cirros@FIP):vdb 的 serial = VOL 前 20 碼;dd 寫入一行字,沿 iSCSI 落到 LV。 ctl001 / ctl002 / ctl003(控制節點) scp001(storage) 10.127.0.7 VG cinder-volumes / thin pool scp002(compute) 10.127.0.18 CLI RPC:建立・匯出・擴充・刪除 attach / detach backing store iSCSI jmp001所有指令都在這裡下ssh 進節點或 VM 觀察 cinder-api:8776type・attachmentC2 cinder-schedulerhost@backend#pool依 type 選後端 cinder-backup未部署 nova-api建 VM・attachC1 cinder_volumeLVM driver(lvm-1) tgtdiSCSI target :3260C3 volume-<VOL> c15-stuNN-volC6 _snapshot-<SNAP> c15-stuNN-snap volume-<CLONE> c15-stuNN-clone iscsid登入 targetC4 nova_computeos-brick・connectorC1 /dev/sdX ← by-path/ip-10.127.0.7:3260-…<VOL>C4 nova_libvirt(QEMU)vdb ← /dev/sdX・<iotune>C5 c15-stuNN-vm(cirros)vda 在本機・vdb = volumeC6 標籤=這一步作用的位置(指令都在 jmp001 下);淡色=這個 Part 不會碰到。點線=控制路徑,粗線=資料路徑 C1nova-api → nova_compute:server add volume:volume 狀態 reserved → attaching → in-use C2cinder-api:attachment 記錄 connection_info:target IQN、portal、LUN(CHAP 已濾掉) C3scp001 tgtd:匯出 volume-<VOL> 為 iSCSI target,backing store 就是那個 LV C4scp002 iscsid:登入 target,主機出現 /dev/sdX(by-path 名稱含 VOL ID) C5scp002 nova_libvirt:/dev/sdX 以 virtio 交給 VM 成為 vdb,<iotune> 套用 front-end QoS C6VM(ssh cirros@FIP):vdb 的 serial = VOL 前 20 碼;dd 寫入一行字,沿 iSCSI 落到 LV
Part C 作用的位置:C1 nova、C2 cinder-api、C3 tgtd、C4 iscsid、C5 nova_libvirt、C6 VM

C1. 綁 Floating IP,再 attach

指令
# [jmp001]
openstack server show c15-stu${NN}-vm -c status -c OS-EXT-SRV-ATTR:host
export FIP=$(openstack floating ip create public1 --description c15-stu${NN}-fip -f value -c floating_ip_address)
openstack server add floating ip c15-stu${NN}-vm $FIP; echo $FIP
openstack server add volume c15-stu${NN}-vm c15-stu${NN}-vol
for i in 1 2 3 4 5 6; do echo "$(date +%T) $(openstack volume show $VOL -f value -c status)"; sleep 2; done

預期輸出:

預期輸出
+----------------------+---------------------+
| Field                | Value               |
+----------------------+---------------------+
| OS-EXT-SRV-ATTR:host | scp002-6164930-iaas |
| status               | ACTIVE              |
+----------------------+---------------------+
192.168.100.100
+-----------------------+--------------------------------------+
| Field                 | Value                                |
+-----------------------+--------------------------------------+
| ID                    | 02229066-fa48-4f05-97f3-556246776fd9 |
| Server ID             | 6c544407-de12-4533-8c24-7a3ff8b3caf4 |
| Volume ID             | 02229066-fa48-4f05-97f3-556246776fd9 |
| Device                | /dev/vdb                             |
| Tag                   | None                                 |
| Delete On Termination | False                                |
+-----------------------+--------------------------------------+
03:57:07 reserved
03:57:10 attaching
03:57:14 in-use
03:57:16 in-use
03:57:18 in-use
03:57:20 in-use

C2. Attachment 與 connection_info

指令
# [jmp001]
openstack --os-volume-api-version 3.27 volume attachment list --volume-id $VOL
export ATT=$(openstack --os-volume-api-version 3.27 volume attachment list --volume-id $VOL -f value -c ID)
openstack --os-volume-api-version 3.27 volume attachment show $ATT -f yaml | grep -vE "auth_(username|password)"

預期輸出:

預期輸出
+--------------------------------------+--------------------------------------+--------------------------------------+----------+
| ID                                   | Volume ID                            | Server ID                            | Status   |
+--------------------------------------+--------------------------------------+--------------------------------------+----------+
| befa172a-7500-47b0-85d7-938e3b8921d8 | 02229066-fa48-4f05-97f3-556246776fd9 | 6c544407-de12-4533-8c24-7a3ff8b3caf4 | attached |
+--------------------------------------+--------------------------------------+--------------------------------------+----------+
ID: befa172a-7500-47b0-85d7-938e3b8921d8
Volume ID: 02229066-fa48-4f05-97f3-556246776fd9
Instance ID: 6c544407-de12-4533-8c24-7a3ff8b3caf4
Status: attached
Attach Mode: rw
Attached At: '2026-11-07T19:57:07.000000'
Detached At: ''
Properties:
  access_mode: rw
  attachment_id: befa172a-7500-47b0-85d7-938e3b8921d8
  auth_method: CHAP
  cacheable: false
  driver_volume_type: iscsi
  encrypted: false
  enforce_multipath: true
  qos_specs:
    total_bytes_sec: '20971520'
    total_iops_sec: '500'
  target_discovered: false
  target_iqn: iqn.2010-10.org.openstack:volume-02229066-fa48-4f05-97f3-556246776fd9
  target_lun: 1
  target_portal: 10.127.0.7:3260
  volume_id: 02229066-fa48-4f05-97f3-556246776fd9

C3. scp001:tgtd 匯出了 target

只印出你自己的 target,CHAP 帳號以「略」取代:

指令
# [jmp001]
ssh 10.127.0.7 "sudo docker exec tgtd tgtadm --lld iscsi --mode target --op show" \
  | awk -v v="$VOL" '/^Target/{p=index($0,v)>0} /Account information/{if(p)print "    Account information: (CHAP 帳號,略)"; s=1; next} /ACL information/{s=0} p&&!s' \
  | grep -vE "SCSI|Removable|Prevent|Readonly|SWP|Online|flags|Thin"

預期輸出:

預期輸出
Target 1: iqn.2010-10.org.openstack:volume-02229066-fa48-4f05-97f3-556246776fd9
    System information:
        Driver: iscsi
        State: ready
    I_T nexus information:
        I_T nexus: 29
            Initiator: iqn.2016-04.com.open-iscsi:a94163e4c3ce alias: scp002-6164930-iaas
            Connection: 0
                IP Address: 10.127.0.18
    LUN information:
        LUN: 0
            Type: controller
            Size: 0 MB, Block size: 1
            Backing store type: null
            Backing store path: None
        LUN: 1
            Type: disk
            Size: 1074 MB, Block size: 512
            Backing store type: rdwr
            Backing store path: /dev/cinder-volumes/volume-02229066-fa48-4f05-97f3-556246776fd9
    Account information: (CHAP 帳號,略)
    ACL information:
        ALL

C4. scp002:iSCSI session 與主機上的裝置

指令
# [jmp001]
ssh 10.127.0.18 "sudo docker exec iscsid iscsiadm -m session" | grep $VOL
ssh 10.127.0.18 "ls -l /dev/disk/by-path/" | grep $VOL

預期輸出:

預期輸出
tcp: [23] 10.127.0.7:3260,1 iqn.2010-10.org.openstack:volume-02229066-fa48-4f05-97f3-556246776fd9 (non-flash)
lrwxrwxrwx 1 root root  9 Nov  8 03:57 ip-10.127.0.7:3260-iscsi-iqn.2010-10.org.openstack:volume-02229066-fa48-4f05-97f3-556246776fd9-lun-1 -> ../../sda

C5. scp002:libvirt 把它交給 VM

指令
# [jmp001]
export INST=$(openstack server show c15-stu${NN}-vm -f value -c OS-EXT-SRV-ATTR:instance_name); echo $INST
ssh 10.127.0.18 "sudo docker exec nova_libvirt virsh domblklist $INST"
ssh 10.127.0.18 "sudo docker exec nova_libvirt virsh dumpxml $INST" | grep -B3 -A8 "<target dev='vdb'"

預期輸出:

預期輸出
instance-00000099
 Target   Source
-----------------------------------------------------------------------------
 vda      /var/lib/nova/instances/6c544407-de12-4533-8c24-7a3ff8b3caf4/disk
 vdb      /dev/sda

      <driver name='qemu' type='raw' cache='none' io='native'/>
      <source dev='/dev/sda' index='3'/>
      <backingStore/>
      <target dev='vdb' bus='virtio'/>
      <iotune>
        <total_bytes_sec>20971520</total_bytes_sec>
        <total_iops_sec>500</total_iops_sec>
      </iotune>
      <serial>02229066-fa48-4f05-97f3-556246776fd9</serial>
      <alias name='ua-02229066-fa48-4f05-97f3-556246776fd9'/>

C6. 進 VM 看,並寫入一筆資料

指令
# [jmp001]
echo $VOL | cut -c1-20
ssh cirros@$FIP

第一次連線會問 Are you sure you want to continue connecting (yes/no/[fingerprint])?,輸入 yes。密碼是 cirros 映像的預設密碼 gocubsgo。進入後執行(把 01 換成你的編號):

指令
# [c15-stuNN-vm]
lsblk
cat /sys/block/vdb/serial; echo
ls /dev/disk/by-id/
echo c15-stu01-hello | sudo dd of=/dev/vdb bs=512 count=1 conv=sync,fsync
sudo dd if=/dev/vdb bs=32 count=1 2>/dev/null; echo
exit

預期輸出([jmp001] 那行在前,之後是 VM 裡的輸出):

預期輸出
02229066-fa48-4f05-9
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
vda     252:0    0    1G  0 disk
|-vda1  252:1    0 1015M  0 part /
`-vda15 252:15   0    8M  0 part
vdb     252:16   0    1G  0 disk
02229066-fa48-4f05-9
ls: /dev/disk/by-id/: No such file or directory
0+1 records in
1+0 records out
c15-stu01-hello

Part D:Snapshot 與狀態機(p.16、17)

下圖標出這一節每一步作用在哪個元件上(淡色的是這一節不會碰到的):

Part D 作用的位置 Part D 作用的位置。D1 作用在 cinder-api:對 in-use 的 volume 做 snapshot 要加 --force,否則 HTTP 400;D1 作用在 scp001 LV:多出 _snapshot-<SNAP>,Origin 是 volume-<VOL>;D2 作用在 scp001 LV:從 snapshot 建出 volume-<CLONE>;在 scp001 直接 dd 讀出 C6 寫的那行字;D3 作用在 cinder-api:刪除 in-use 的 volume:被狀態機擋下;D4 作用在 scp001 LV:先刪 snapshot 也可以:LVM thin 上 clone 不受影響(Origin 變空);D5 作用在 cinder-backup:沒有部署,所以沒有 backup 可用(只看,不要做)。 ctl001 / ctl002 / ctl003(控制節點) scp001(storage) 10.127.0.7 VG cinder-volumes / thin pool scp002(compute) 10.127.0.18 CLI RPC:建立・匯出・擴充・刪除 attach / detach backing store iSCSI jmp001所有指令都在這裡下ssh 進節點或 VM 觀察 cinder-api:8776type・attachmentD3D1 cinder-schedulerhost@backend#pool依 type 選後端D2 cinder-backup未部署D5 nova-api建 VM・attach cinder_volumeLVM driver(lvm-1)D2 tgtdiSCSI target :3260 volume-<VOL> c15-stuNN-vol _snapshot-<SNAP> c15-stuNN-snapD4D1 volume-<CLONE> c15-stuNN-cloneD2 iscsid登入 target nova_computeos-brick・connector /dev/sdX ← by-path/ip-10.127.0.7:3260-…<VOL> nova_libvirt(QEMU)vdb ← /dev/sdX・<iotune> c15-stuNN-vm(cirros)vda 在本機・vdb = volume 標籤=這一步作用的位置(指令都在 jmp001 下);淡色=這個 Part 不會碰到。點線=控制路徑,粗線=資料路徑 D1cinder-api:對 in-use 的 volume 做 snapshot 要加 --force,否則 HTTP 400 D1scp001 LV:多出 _snapshot-<SNAP>,Origin 是 volume-<VOL> D2scp001 LV:從 snapshot 建出 volume-<CLONE>;在 scp001 直接 dd 讀出 C6 寫的那行字 D3cinder-api:刪除 in-use 的 volume:被狀態機擋下 D4scp001 LV:先刪 snapshot 也可以:LVM thin 上 clone 不受影響(Origin 變空) D5cinder-backup:沒有部署,所以沒有 backup 可用(只看,不要做)
Part D 作用的位置:D1 cinder-api 與 snapshot LV、D2 clone LV、D3 cinder-api、D4 snapshot LV、D5 cinder-backup

D1. 對 in-use 的 volume 做 snapshot

指令
# [jmp001]
openstack volume snapshot create c15-stu${NN}-snap --volume c15-stu${NN}-vol
openstack volume snapshot create c15-stu${NN}-snap --volume c15-stu${NN}-vol --force -c id -c status
sleep 3
export SNAP=$(openstack volume snapshot show c15-stu${NN}-snap -f value -c id)
openstack volume snapshot show c15-stu${NN}-snap -c status
ssh 10.127.0.7 "sudo lvs -o lv_name,lv_attr,lv_size,origin,data_percent cinder-volumes" | grep -E "LV|$VOL|$SNAP"

預期輸出:

預期輸出
Invalid volume: Volume 02229066-fa48-4f05-97f3-556246776fd9 status must be available, but current status is: in-use. (HTTP 400) (Request-ID: req-8d45fda3-8955-4cb1-9b6c-d1bd90f58ef7)
+--------+--------------------------------------+
| Field  | Value                                |
+--------+--------------------------------------+
| id     | af2cad90-fd20-4c18-b23d-b3699372c500 |
| status | creating                             |
+--------+--------------------------------------+
+--------+-----------+
| Field  | Value     |
+--------+-----------+
| status | available |
+--------+-----------+
  LV                                             Attr       LSize   Origin                                      Data%
  _snapshot-af2cad90-fd20-4c18-b23d-b3699372c500 Vwi---tz-k   1.00g volume-02229066-fa48-4f05-97f3-556246776fd9
  volume-02229066-fa48-4f05-97f3-556246776fd9    Vwi-aotz--   1.00g                                             0.02

D2. 從 snapshot 建立新 volume

指令
# [jmp001]
openstack volume create c15-stu${NN}-clone --snapshot c15-stu${NN}-snap -c status
sleep 6
openstack volume show c15-stu${NN}-clone -c status -c type -c snapshot_id -c os-vol-host-attr:host
export CLONE=$(openstack volume show c15-stu${NN}-clone -f value -c id)
ssh 10.127.0.7 "sudo lvs -o lv_name,lv_attr,lv_size,origin,data_percent cinder-volumes" | grep -E "LV|$VOL|$SNAP|$CLONE"
ssh 10.127.0.7 "sudo dd if=/dev/cinder-volumes/volume-$CLONE bs=32 count=1 2>/dev/null"; echo

預期輸出:

預期輸出
+--------+----------+
| Field  | Value    |
+--------+----------+
| status | creating |
+--------+----------+
+-----------------------+--------------------------------------+
| Field                 | Value                                |
+-----------------------+--------------------------------------+
| os-vol-host-attr:host | scp001-6161072-iaas@lvm-1#lvm-1      |
| snapshot_id           | af2cad90-fd20-4c18-b23d-b3699372c500 |
| status                | available                            |
| type                  | c15-gold                             |
+-----------------------+--------------------------------------+
  LV                                             Attr       LSize   Origin                                         Data%
  _snapshot-af2cad90-fd20-4c18-b23d-b3699372c500 Vwi-a-tz-k   1.00g volume-02229066-fa48-4f05-97f3-556246776fd9    0.02
  volume-02229066-fa48-4f05-97f3-556246776fd9    Vwi-aotz--   1.00g                                                0.02
  volume-94ef8ed3-2c5e-4589-bf1c-743e39771089    Vwi-a-tz--   1.00g _snapshot-af2cad90-fd20-4c18-b23d-b3699372c500 0.02
c15-stu01-hello

D3. 狀態機擋下的操作

指令
# [jmp001]
openstack volume delete c15-stu${NN}-vol
openstack volume list --long -c Name -c Status -c Type -c "Attached to" | grep -E "Name|c15-stu${NN}-"

預期輸出:

預期輸出
Failed to delete volume with name or ID 'c15-stu01-vol': Invalid volume: Volume status must be available or error or error_restoring or error_extending or error_managing and must not be migrating, attached, belong to a group, have snapshots, awaiting a transfer, or be disassociated from snapshots after volume transfer. (HTTP 400) (Request-ID: req-2bfd2f95-4440-4a61-97d4-47982a0200ae)
1 of 1 volumes failed to delete.
| Name            | Status    | Type        | Attached to                           |
| c15-stu01-clone | available | c15-gold    |                                       |
| c15-stu01-bad   | error     | c15-nowhere |                                       |
| c15-stu01-vol   | in-use    | c15-gold    | Attached to c15-stu01-vm on /dev/vdb  |

D4. 先刪 snapshot 會怎樣?

p.17 的建議順序是「先刪由 snapshot 建立的 volume,再刪 snapshot」,因為部分後端的 clone 依賴 snapshot。在這個 LVM thin 後端上試試看:

指令
# [jmp001]
openstack volume snapshot delete c15-stu${NN}-snap
sleep 4
openstack volume snapshot list | grep -c c15-stu${NN}-snap
ssh 10.127.0.7 "sudo lvs -o lv_name,lv_attr,lv_size,origin,data_percent cinder-volumes" | grep -E "LV|$VOL|$SNAP|$CLONE"

預期輸出:

預期輸出
0
  LV                                          Attr       LSize   Origin Data%
  volume-02229066-fa48-4f05-97f3-556246776fd9 Vwi-aotz--   1.00g        0.02
  volume-94ef8ed3-2c5e-4589-bf1c-743e39771089 Vwi-a-tz--   1.00g        0.02

D5. Snapshot ≠ Backup(只看,不要做)

指令
# [jmp001]
openstack volume service list -c Binary -c Host -c State

預期輸出:

預期輸出
+------------------+---------------------------+-------+
| Binary           | Host                      | State |
+------------------+---------------------------+-------+
| cinder-scheduler | ctl002-6161063-iaas       | up    |
| cinder-scheduler | ctl001-6161060-iaas       | up    |
| cinder-scheduler | ctl003-6161069-iaas       | up    |
| cinder-volume    | scp001-6161072-iaas@lvm-1 | up    |
+------------------+---------------------------+-------+

Part E:Detach 與擴充(p.11、16)

下圖標出這一節每一步作用在哪個元件上(淡色的是這一節不會碰到的):

Part E 作用的位置 Part E 作用的位置。E1 作用在 nova_compute・nova_libvirt:server remove volume:vdb 從 VM 拔掉;E1 作用在 scp002 iscsid:登出 session,/dev/sdX 消失(No active sessions);E1 作用在 tgtd・cinder-api:target 移除、attachment 刪除,volume 回到 available;E2 作用在 cinder_volume → LV:volume set --size 2:LV 擴成 2 GiB;E2 作用在 cinder-api:縮回 1 GB 被拒:New size must be greater than 2 GB。 ctl001 / ctl002 / ctl003(控制節點) scp001(storage) 10.127.0.7 VG cinder-volumes / thin pool scp002(compute) 10.127.0.18 CLI RPC:建立・匯出・擴充・刪除 attach / detach backing store iSCSI jmp001所有指令都在這裡下ssh 進節點或 VM 觀察 cinder-api:8776type・attachmentE2E1 cinder-schedulerhost@backend#pool依 type 選後端 cinder-backup未部署 nova-api建 VM・attachE1 cinder_volumeLVM driver(lvm-1)E2 tgtdiSCSI target :3260E1 volume-<VOL> c15-stuNN-volE2 _snapshot-<SNAP> c15-stuNN-snap volume-<CLONE> c15-stuNN-clone iscsid登入 targetE1 nova_computeos-brick・connectorE1 /dev/sdX ← by-path/ip-10.127.0.7:3260-…<VOL>E1 nova_libvirt(QEMU)vdb ← /dev/sdX・<iotune>E1 c15-stuNN-vm(cirros)vda 在本機・vdb = volume 標籤=這一步作用的位置(指令都在 jmp001 下);淡色=這個 Part 不會碰到。點線=控制路徑,粗線=資料路徑 E1nova_compute・nova_libvirt:server remove volume:vdb 從 VM 拔掉 E1scp002 iscsid:登出 session,/dev/sdX 消失(No active sessions) E1tgtd・cinder-api:target 移除、attachment 刪除,volume 回到 available E2cinder_volume → LV:volume set --size 2:LV 擴成 2 GiB E2cinder-api:縮回 1 GB 被拒:New size must be greater than 2 GB
Part E 作用的位置:E1 拆掉 attach 的各段、E2 cinder_volume 擴充 LV

E1. Detach:連線依序拆掉

指令
# [jmp001]
openstack server remove volume c15-stu${NN}-vm c15-stu${NN}-vol
for i in 1 2 3; do echo "$(date +%T) $(openstack volume show $VOL -f value -c status)"; sleep 2; done
openstack --os-volume-api-version 3.27 volume attachment list --volume-id $VOL
ssh 10.127.0.7 "sudo docker exec tgtd tgtadm --lld iscsi --mode target --op show" | grep -c $VOL
ssh 10.127.0.18 "sudo docker exec iscsid iscsiadm -m session" | grep -c $VOL

預期輸出:

預期輸出
04:00:39 detaching
04:00:42 available
04:00:44 available

0
iscsiadm: No active sessions.
0

E2. 擴充,以及不能縮小

指令
# [jmp001]
openstack volume set --size 2 c15-stu${NN}-vol
sleep 3
openstack volume show c15-stu${NN}-vol -c size -c status
ssh 10.127.0.7 "sudo lvs -o lv_name,lv_size cinder-volumes" | grep $VOL
openstack volume set --size 1 c15-stu${NN}-vol

預期輸出:

預期輸出
+--------+-----------+
| Field  | Value     |
+--------+-----------+
| size   | 2         |
| status | available |
+--------+-----------+
  volume-02229066-fa48-4f05-97f3-556246776fd9   2.00g
Failed to set volume size: New size must be greater than 2 GB
One or more of the set operations failed

Part F:清除

下圖標出這一節每一步作用在哪個元件上(淡色的是這一節不會碰到的):

Part F 作用的位置 Part F 作用的位置。F 作用在 cinder_volume → LV:刪除 clone、vol、bad 三個 volume,對應的 LV 消失;F 作用在 nova-api → scp002:刪除 Floating IP 與 VM。 ctl001 / ctl002 / ctl003(控制節點) scp001(storage) 10.127.0.7 VG cinder-volumes / thin pool scp002(compute) 10.127.0.18 CLI RPC:建立・匯出・擴充・刪除 attach / detach backing store iSCSI jmp001所有指令都在這裡下ssh 進節點或 VM 觀察 cinder-api:8776type・attachmentF cinder-schedulerhost@backend#pool依 type 選後端 cinder-backup未部署 nova-api建 VM・attachF cinder_volumeLVM driver(lvm-1)F tgtdiSCSI target :3260 volume-<VOL> c15-stuNN-volF _snapshot-<SNAP> c15-stuNN-snap volume-<CLONE> c15-stuNN-cloneF iscsid登入 target nova_computeos-brick・connectorF /dev/sdX ← by-path/ip-10.127.0.7:3260-…<VOL> nova_libvirt(QEMU)vdb ← /dev/sdX・<iotune> c15-stuNN-vm(cirros)vda 在本機・vdb = volumeF 標籤=這一步作用的位置(指令都在 jmp001 下);淡色=這個 Part 不會碰到。點線=控制路徑,粗線=資料路徑 Fcinder_volume → LV:刪除 clone、vol、bad 三個 volume,對應的 LV 消失 Fnova-api → scp002:刪除 Floating IP 與 VM
Part F 作用的位置:刪除 volume、FIP 與 VM
指令
# [jmp001]
openstack volume delete c15-stu${NN}-clone c15-stu${NN}-vol c15-stu${NN}-bad
openstack floating ip delete $(openstack floating ip list --long -f value -c ID -c Description | awk -v d=c15-stu${NN}-fip '$2==d{print $1}')
openstack server delete --wait c15-stu${NN}-vm
sleep 3
openstack volume list --name c15-stu${NN} -f value -c Name
openstack volume snapshot list -f value -c Name | grep c15-stu${NN}
openstack server list --name c15-stu${NN} -f value -c Name
ssh 10.127.0.7 "sudo lvs cinder-volumes" | grep -cE "$VOL|$CLONE"

預期輸出:(前三個查詢沒有輸出)

預期輸出
0

小結

試跑量測(單人)時間
volume create → available< 5 秒
c15-nowhere → error< 5 秒
attach:送出 → in-use約 12 秒(reserved → attaching → in-use)
snapshot(--force)→ available1–3 秒
由 snapshot 建立 volume約 6 秒
detach → available約 6 秒
extend 1 → 2 GB< 3 秒
你看到的在哪裡對應簡報
host@backend#poolvolume show 的 os-vol-host-attr:hostp.7、9
scheduler 找不到後端volume message listp.7、19
volume 的實體scp001 的 LV volume-<ID>(thin)p.8、9
connection_infovolume attachment show 的 Propertiesp.11、15
iSCSI target / sessionscp001 tgtd、scp002 iscsidp.12、15
front-end QoSVM XML 的 <iotune>p.4
Guest 裡對應 volume/sys/block/vdX/serial(或 /dev/disk/by-id/)p.15
snapshot 在同一個後端同一個 thin pool 的 _snapshot-<ID>p.17