繼研究了Neutron之后,繼續Nova的外圍研究之旅。本站是研究塊存儲服務Cinder。
0。驗證環境
環境包括:
1、一個controller節點,運行nova-api, nova-scheduler, cinder-api, cinder-scheduler, mysql, rabbitmq
2、一個Nova compute節點,運行一個虛機
3、三個cinder volume節點,每個節點使用LVMISCSIDriver來使用本地存儲
4. 創建一個volume type,設置 volume_backend_name = lvmbackend
cinder.conf 在 block1上 enabled_backends = lvmdriver-b1 [lvmdriver-b1] volume_group = cinder-volumes volume_driver = cinder.volume.drivers.lvm.LVMISCSIDriver volume_backend_name = lvmbackend cinder.conf 在 block2上 enabled_backends = lvmdriver-b21,lvmdriver-b22 storage_availability_zone=az1 [lvmdriver-b21] iscsi_ip_address = 10.0.1.29 volume_group = cinder-volumes1 volume_driver = cinder.volume.drivers.lvm.LVMISCSIDriver volume_backend_name = lvmbackend [lvmdriver-b22] volume_group = cinder-volumes2 volume_driver = cinder.volume.drivers.lvm.LVMISCSIDriver volume_backend_name = lvmbackend cinder.conf 在 block3上
enabled_backends = lvmdrier-network [lvmdriver-network] volume_group = system volume_driver = cinder.volume.drivers.lvm.LVMISCSIDriver volume_backend_name = lvmbackend
關於幾個小問題的說明:
- [***] 會定一個一個 backend,下面幾行是該backend 的配置。需要啟用的backend 需要添加到 enabled_backends 的值中
- volume_backend_name 會被 volume type 用到,通過 --property volume_backend_name 屬性來設置。
- 多個backends 中的 volume_backend_name 可以相同。此時 scheduler 會按照指定的調度放在在多個 backend 之內選擇一個最合適的。
- 每個 backend 都會有一個 cinder volume service instance,出現在 cinder service-list 命令的輸出中,其 Host 的格式為 <節點名稱>@<backend 值>
cinder的service如下:
root@controller:/home/s1# cinder service-list +------------------+---------------------------+------+---------+-------+----------------------------+-----------------+ | Binary | Host | Zone | Status | State | Updated_at | Disabled Reason | +------------------+---------------------------+------+---------+-------+----------------------------+-----------------+ | cinder-backup | controller | nova | enabled | up | 2015-01-11T16:36:00.000000 | None | | cinder-scheduler | controller | nova | enabled | up | 2015-01-11T16:36:01.000000 | None | | cinder-volume | block1@lvmdriver-b1 | nova | enabled | up | 2015-01-11T16:36:08.000000 | None | | cinder-volume | block2@lvmdriver-b21 | az1 | enabled | up | 2015-01-11T16:36:06.000000 | None | | cinder-volume | block2@lvmdriver-b22 | az1 | enabled | up | 2015-01-11T16:36:05.000000 | None | | cinder-volume | network@lvmdriver-network | nova | enabled | up | 2015-01-11T16:36:02.000000 | None | +------------------+---------------------------+------+---------+-------+----------------------------+-----------------+
說明:
- Cinder為每一個backend運行一個cinder-volume服務
- 通過在cinder.conf中設置 storage_availability_zone=az1 可以指定cinder-volume host的Zone。用戶創建volume的時候可以選擇AZ,配合cinder-scheduler的AvailabilityZoneFilter可以將volume創建到指定的AZ中。 默認的情況下Zone為nova。
- 通過在cinder.conf中的backend配置部分設置 iscsi_ip_address = 10.0.1.29 可以指定iSCSI session使用的網卡,從而做到數據網絡和管理網絡的分離。
- 搭以上多節點環境,一定要注意各節點之間使用NTP進行時間同步,否則可能出現cinder-volume沒有任何錯誤,但是其狀態為down的情況。
1、關於OpenStack塊存儲
1.1 OpenStack中的存儲
1.2 虛機對塊存儲的要求
1.3 Cinder概述
1.4 Cinder的內部架構
- 三個主要組成部分
- –cinder-api 組件負責向外提供Cinder REST API
- –cinder-scheduler 組件負責分配存儲資源
- –cinder-volume 組件負責封裝driver,不同的driver負責控制不同的后端存儲
- 組件之間的RPC靠消息隊列(Queue)實現
- Cinder的開發工作主要集中在scheduler和driver,以便提供更多的調度算法、更多的功能、以及指出更多的后端存儲
- Volume元數據和狀態保存在Database中
1.5 Cinder的基本功能
1 |
卷操作 |
創建卷 |
2 |
從已有卷創建卷 (克隆) |
|
3 |
擴展卷 |
|
4 |
刪除卷 |
|
5 |
卷-虛機操作 |
掛載卷到虛機 |
6 |
分離虛機卷 |
|
7 |
卷-快照操作 |
創建卷的快照 |
8 |
從已有卷快照創建卷 |
|
9 |
刪除快照 |
|
10 |
卷-鏡像操作 |
從鏡像創建卷 |
11 |
從卷創建鏡像 |
1.6 Cinder 插件
1.6.1 LVMISCSIDriver
上圖說明:
- cinder-volume 服務部署在控制節點上。該節點上創建了一個 volume group。所謂LVM中的 Local,指的就是 volume group 和 cinder-volume 在同一個節點上,因為 cinder LVM driver 需要調用本地的相關命令來管理 volume group。
- 每個 nova-compute 計算節點作為 iSCSI Intiator 和存儲節點通信。每當 VG 中為一個計算節點的一台虛機分配一個volume 后,在計算節點上就會出現一個 /dev/sdx 設備。此設備會被 qemu-kvm 提供給虛機,作為虛機的一個disk。
- 一個 cinder-volume 節點上可以有多個 volume group。此時每個 volume group 都有一個 cinder-volume 服務實例。
- 一個 openstack 環境中可以有多個 cinder-volume 節點。
root@compute1:/home/s1# cat /etc/iscsi/initiatorname.iscsi InitiatorName=iqn.1993-08.org.debian:01:8d794081cd6a
root@compute1:/home/s1# iscsiadm -m session tcp: [10] 192.168.1.24:3260,1 iqn.2010-10.org.openstack:volume-5cfc715d-a7b3-47b4-bded-44c0a228360c tcp: [11] 192.168.1.19:3260,1 iqn.2010-10.org.openstack:volume-4039eb07-90eb-4a92-8fd3-e3514cb4969b tcp: [14] 192.168.1.29:3260,1 iqn.2010-10.org.openstack:volume-3f204086-609e-449f-90a1-3a0d2c92c525 tcp: [16] 10.0.1.29:3260,1 iqn.2010-10.org.openstack:volume-1b7f6669-06db-474e-bf78-4feea529be5b tcp: [6] 192.168.1.24:3260,1 iqn.2010-10.org.openstack:volume-39363c5f-cf3c-4461-af83-00314839f05a tcp: [9] 192.168.1.24:3260,1 iqn.2010-10.org.openstack:volume-a0a7ccb3-8864-4fd0-aee2-0e20d43ba8dd
每個target的詳細信息:
tgtadm --lld iscsi --op show --mode target Target 1: iqn.2010-10.org.openstack:volume-136354c3-5920-46b9-a930-52c055c53295 System information: Driver: iscsi State: ready I_T nexus information: I_T nexus: 2 Initiator: iqn.1993-08.org.debian:01:8d794081cd6a alias: compute1 Connection: 0 IP Address: 192.168.1.15 LUN information: LUN: 0 Type: controller SCSI ID: IET 00010000 SCSI SN: beaf10 Size: 0 MB, Block size: 1 Online: Yes Removable media: No Prevent removal: No Readonly: No SWP: No Thin-provisioning: No Backing store type: null Backing store path: None Backing store flags: LUN: 1 Type: disk SCSI ID: IET 00010001 SCSI SN: beaf11 Size: 1074 MB, Block size: 512 Online: Yes Removable media: No Prevent removal: No Readonly: No SWP: No Thin-provisioning: No Backing store type: rdwr Backing store path: /dev/cinder-volumes/volume-136354c3-5920-46b9-a930-52c055c53295 Backing store flags: Account information: s6KdhjSUrU2meEyxPTDZ ACL information: ALL
1.6.2 IBM SVC/DS8K/XIV 插件
上圖說明:
- cinder-volume 通過管理網絡和存儲的控制器進行通信來管理volume,因此,理論上最少只需要一個 cinder-volume 實例。但是,為了高可用需要,往往會再部署一個備 cinder-volume 服務,並用 Pacemaker 進行控制。當主服務down后,備服務會接管。
- 以 XIV iSCSI driver (代碼在這里)為例說明創建卷的過程
- 該 cinder 通過遠程運行SSH 來執行XIV命令來操縱 XIV,比如運行 svctask mkvdisk 命令來創建一個XIV 卷。
- 當為虛機分配一個XIV volume 時 cinder driver 所做的工作:(1)計算計算節點的 host name (2)在 XIV 上為該host 創建一個 virtual host,需要指定HBA卡的WWPN(當采用FC連接時),或者host 的 IQN(當采用 iSCSI 連接時) (4)在XIV 上創建一個 LUN (5)將該LUN mount 給virtual host
- 此時,host 上每個 volume 都會有一個 /dev/sdx 設備
- qemu 將 sdx 設備虛擬化為虛機的一個 disk
1.6.3 LVM插件和Vendor插件的比較
2、 Cinder操作
下面講講幾個比較有意思的操作。
2.1 tranfer volume:將volume 的擁有權從一個tenant中的用戶轉移到另一個tenant中的用戶。
兩步走:
+------------+--------------------------------------+
| Property | Value |
+------------+--------------------------------------+
| auth_key | a94e45d06dd54500 |
| created_at | 2015-01-07T07:36:33.916921 |
| id | b14d1d26-8249-4dd2-8213-258ccfe31542 |
| name | None |
| volume_id | d146a947-9c1e-489f-b7a3-6b9604d9fb49 |
+------------+--------------------------------------+
+-----------+--------------------------------------+
| Property | Value |
+-----------+--------------------------------------+
| id | b14d1d26-8249-4dd2-8213-258ccfe31542 |
| name | None |
| volume_id | d146a947-9c1e-489f-b7a3-6b9604d9fb49 |
+-----------+--------------------------------------+
2.2 volume migrate: 將volume從一個backend遷移到另一個backend
多種可能的情況:
2.3 volume backup
2.4 qos 支持
3 cinder的組件
關於RPC: cinder內部各組件之間使用基於RabbitMQ的RPC通信。cinder-scheduler和cinder-volume分別 會 創建RPC連接,啟動消費者線程,然后等待隊列消息。當輪詢查詢到消息到達后,創建線程處理相關消息。
3.1 cinder-api
主要服務接口, 負責接受和處理外界的API請求,並將請求放入RabbitMQ隊列,交由后端執行。
cinder-api提供兩個版本的REST API:V1提供Volume,Vloume type,Snapshot操作的API;V2增加了QoS,Limits,Backup操作的API。
除了V1和V2文檔列出來的API外,一些volume的操作需要通過POST + action的方式實現,比如extend volume:
POST http://controller:8776/v1/fa2046aaead44a698de8268f94759fc1/volumes/8e87490c-fa18-4cff-b10e-27645c2a7b99/action
Action body: {"os-extend": {"new_size": 2}}
此類操作有:
- os-reset_status
- os-force_delete
- os-force_detach
- os-migrate_volume
- os-migrate_volume_completion
- os-reset_status
- os-update_snapshot_status
- os-attach
- os-detach
- os-reserve
- os-unreserve
- os-begin_detaching
- os-roll_detaching
- os-initialize_connection
- os-terminate_connection
- os-volume_upload_image
- os-extend
- os-update_readonly_flag
- os-retype
- os-set_bootable
- os-promote-replica
- os-reenable-replica
- os-unmanage
cinder-api service 的啟動過程分析見 探索 OpenStack 之(11):cinder-api Service 啟動過程分析 以及 WSGI / Paste deploy / Router 等介紹 (2015-02-04 16:01)
3.2 cinder-scheduler
cinder-scheduler的用途是在多backend環境中決定新建volume的放置host:
0。 首先判斷host的狀態,只有service狀態為up的host才會被考慮。
1。創建volume的時候,根據filter和weight算法選出最優的host來創建volume。
2。遷移volume的時候,根據filter和weight算法來判斷目的host是不是符合要求。
如果選出一個host,則使用RPC調用cinder-volume來執行volume操作。
為了維護host的狀態,cinder-scheduler接受定時的host上cinder-volume狀態上報:
2015-01-12 02:02:56.688 828 DEBUG cinder.scheduler.host_manager [req-403ef666-5551-4f31-a130-7bcad8e9d1ec - - - - -] Received volume service update from block2@lvmdriver-b21: {u'pools': [{u'pool_name': u'lvmbackend', u'QoS_support': False, u'allocated_capacity_gb': 1, u'free_capacity_gb': 3.34, u'location_info': u'LVMVolumeDriver:block2:cinder-volumes1:default:0', u'total_capacity_gb': 5.34, u'reserved_percentage': 0}], u'driver_version': u'2.0.0', u'vendor_name': u'Open Source', u'volume_backend_name': u'lvmbackend', u'storage_protocol': u'iSCSI'} update_service_capabilities /usr/lib/python2.7/dist-packages/cinder/scheduler/host_manager.py:434
3.2.1 Host Filtering 算法
默認的filter包括 AvailabilityZoneFilter,CapacityFilter,CapabilitiesFilter。其中:
- AvailabilityZoneFilter會判斷cinder host的availability zone是不是與目的az相同。不同則被過濾掉。
- CapacityFilter會判斷host上的剩余空間 free_capacity_gb 大小,確保free_capacity_gb 大於volume 的大小。不夠則被過濾掉。
- CapabilitiesFilter會檢查host的屬性是否和volume type中的extra specs是否完全一致。不一致則被國旅掉。
經過以上Filter的過濾,cinder-scheduler會得到符合條件的host列表,然后進入weighting環節,根據weighting算法選出最優的host。得到空列表則報No valid host was found錯誤。
cinder.conf中,scheduler_default_filters不設置的話,cinder-scheduler默認會使用這三個filter。
3.2.2 Host Weighting 算法
- AllocatedCapacityWeigher:有最小已使用空間的host勝出。 可設置allocated_capacity_weight_multiplier為正值來反轉,其默認值為-1。
-
CapacityWeigher:有最大可使用空間的host勝出。可設置capacity_weight_multiplier為負值來反轉算法,其默認值為1
-
ChanceWeigher:隨機從過濾出的host中選擇一個host
經過此步驟,cinder-scheduler將得到一個weighted_hosts列表,它將會選擇第一個host做為volume的目的host,把它加到retry_hosts列表中,然后通過RPC調用上面的cinder-volume來創建volume。
cinder.conf中,scheduler_default_weighers不設置的話,cinder-scheduler默認使用 CapacityWeigher。
3.3 cinder-volume
3.3.1 volume創建失敗重試機制
用戶可以在cinder.conf中使用scheduler_max_attempts來配置volume創建失敗時候的重試次數,默認次數為3,值為1則表示不使用重試機制。
# Maximum number of attempts to schedule an volume (integer value)
#scheduler_max_attempts=3
cinder-sheduler和cinder-volume之間會傳遞當前是重試次數。如果volume創建失敗,cinder-volume會通過RPC重新調用cinder-scheduler去創建volume,cinder-scheduler會檢查當前的重試次數是不是超過最大可重試次數。如果沒超過,它會選擇下一個可以使用的host去重新創建volume。如果在規定的重試次數內仍然無法創建volume,那么會報No valid host was found錯誤。
比如下面的重試過程:
cinder-volume:
- Insufficient free space for volume creation on host network@lvmdriver-network#lvmbackend (requested / avail): 5/0.0
- Insufficient free space for volume creation on host block2@lvmdriver-b2#lvmbackend (requested / avail): 5/4.0
- Insufficient free space for volume creation on host block1@lvmdriver-b1#lvmbackend (requested / avail): 5/1.0
3.3.2 從image創建volume
Attempt to create a volume by efficiently copying image to volume. If both source and target are backed by gpfs storage and the source image is in raw format move the image to create a volume using either gpfs clone operation or with a file copy. If the image format is not raw, convert it to raw at the volume path.
b。若driver的clone-image方法不成功,則執行Cinder的默認方法:(1)創建一個raw的volume,設置其狀態為downloading (2)將image下載並拷貝到該volume。具體方法每個driver可以自行實現,Cinder也提供默認實現。
c。拷貝image的metadata到volume的metadata。
3.3.3 從snapshot創建volume
a。獲取snapshot
b。Cinder不提供默認實現方式,它調用各driver的create_volume_from_snapshot方法創建volume。以IBM SVC為例,它會在SVC存儲上創建snapshot的一個拷貝。
c。如果snapshot是bootable的話,需要拷貝它的metadata到新的volume上。
3.3.4 從volume創建volume
a。獲取源volume
b。Cinder不提供默認實現方式,它需要調用各driver的create_cloned_volume方法來創建volume。以IBM SVC為例,它會在存儲上創建源volume的一個拷貝。
c。如果源volume是bootable的話,需要拷貝它的metadata到新的volume上。
3.3.5 創建原始volume
默認的話,cinder-volume會調用各driver創建一個原始的volume。