本系列文章會深刻研究 Ceph 以及 Ceph 和 OpenStack 的集成:html
(1)安裝和部署node
(2)Ceph RBD 接口和工具python
(3)Ceph 物理和邏輯結構linux
(4)Ceph 的基礎數據結構git
(5)Ceph 與 OpenStack 集成的實現github
(6)QEMU-KVM 和 Ceph RBD 的 緩存機制總結web
(7)Ceph 的基本操做和常見故障排除方法apache
(8)關於Ceph PGsapi
爲了深刻學習 Ceph 以及 Ceph 和 OpenStack 的集成,搭建了以下的測試環境:緩存
硬件環境:
軟件環境:
從上圖可見,該環境使用三個虛機做爲Ceph節點,每一個節點上增長兩個虛擬磁盤 vda 和 vdb 做爲 OSD 存儲磁盤,每一個節點上安裝 MON,前兩個節點上安裝 MDS。三個節點使用物理網絡進行通訊。
(0)準備好三個節點 ceph{1,2,3}:安裝操做系統、設置 NTP、配置 ceph1 能夠經過 ssh 無密碼訪問其他節點(依次運行 ssh-keygen,ssh-copy-id ceph2,ssh-copy-id ceph3,修改 /etc/ssh/sshd_config 文件中的 PermitRootLogin yes 來使得 ssh 支持 root 用戶)
節點名稱 | IP 地址 | 部署進程 | 數據盤 |
ceph1 | 192.168.1.194 | 1MON+1MDS+2OSD | /dev/vda, /dev/vdb |
ceph2 | 192.168.1.195 | 1MON+1MDS+2OSD | /dev/vda, /dev/vdb |
ceph3 | 192.168.1.218 | 1MON+1OSD | /dev/vda, /dev/vdb |
(1)在 ceph1 上安裝 ceph-deploy,接下來會使用這個工具來部署 ceph 集羣
(2)在ceph 上,運行 ceph-deploy install ceph{1,2,3} 命令在各節點上安裝 ceph 軟件。安裝好後能夠查看 ceph 版本:
root@ceph1:~# ceph -v ceph version 0.80.10 (ea6c958c38df1216bf95c927f143d8b13c4a9e70)
(3)在 ceph1 上執行如下命令建立 MON 集羣
ceph-deploy new ceph{1,2,3} ceph-deploy mon create ceph{1,2,3} ceph-deploy mon create-initial
完成後查看 MON 集羣狀態:
root@ceph1:~# ceph mon_status {"name":"ceph1","rank":0,"state":"leader","election_epoch":16,"quorum":[0,1,2],"outside_quorum":[],"extra_probe_peers":[],"sync_provider":[],"monmap":{"epoch":1,"fsid":"4387471a-ae2b-47c4-b67e-9004860d0fd0","modified":"0.000000","created":"0.000000","mons":[{"rank":0,"name":"ceph1","addr":"192.168.1.194:6789\/0"},{"rank":1,"name":"ceph2","addr":"192.168.1.195:6789\/0"},{"rank":2,"name":"ceph3","addr":"192.168.1.218:6789\/0"}]}}
(4)在各節點上準備數據盤,只須要在 fdisk -l 命令輸出中能看到數據盤便可,不須要作任何別的操做,而後在 ceph1 上執行以下命令添加 OSD
ceph-deploy --overwrite-conf osd prepare ceph1:/data/osd:/dev/vda ceph2:/data/osd:/dev/vda ceph3:/data/osd:/dev/vda ceph-deploy --overwrite-conf osd activate ceph1:/data/osd:/dev/vda ceph2:/data/osd:/dev/vda ceph3:/data/osd:/dev/vda ceph-deploy --overwrite-conf osd prepare ceph1:/data/osd2:/dev/vdb ceph2:/data/osd2:/dev/vdb ceph3:/data/osd2:/dev/vdb ceph-deploy --overwrite-conf osd activate ceph1:/data/osd2:/dev/vdb ceph2:/data/osd2:/dev/vdb ceph3:/data/osd2:/dev/vdb
該命令詳細信息:
要使得多個OSD數據盤共享一個單獨的 SSD 磁盤,首先要使用 fdisk 對該磁盤進行分區,好比下面的命令將 /dev/sdd 分爲兩個區:
Command (m for help): n Partition type: p primary (1 primary, 0 extended, 3 free) e extended Select (default p): Using default response p Partition number (1-4, default 2): Using default value 2 First sector (1026048-2097151, default 1026048): Using default value 1026048 Last sector, +sectors or +size{K,M,G} (1026048-2097151, default 2097151): Using default value 2097151 Command (m for help): w The partition table has been altered!
結果是:
Disk /dev/sdd: 1073 MB, 1073741824 bytes 255 heads, 63 sectors/track, 130 cylinders, total 2097152 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x6767c86e Device Boot Start End Blocks Id System /dev/sdd1 2048 1026047 512000 83 Linux /dev/sdd2 1026048 2097151 535552 83 Linux
此時,執行下面的命令來建立並激活 OSD:
ceph-deploy --overwrite-conf osd prepare ceph1:sdb:/dev/sdd1 ceph2:sdb:/dev/sdd1
ceph-deploy --overwrite-conf osd activate ceph1:sdb1:/dev/sdd1 ceph2:sdb1:/dev/sdd1
注意prepare 和 activate 兩個命令參數的區別,前者是使用磁盤,後者是使用分區。
備註:看起來最上面的命令有誤,須要修改,TBD。它實際上是使用了 /data/osd 目錄存放數據,而磁盤 /dev/vda 做爲日誌盤。
另外,若是是第二次安裝的話,須要刪除已經存在的 /dev/sdd1 這樣的分區,而後再使用命令 ceph-deploy disk zap /dev/sdd 來將其數據所有刪除。
完成以後,會將 osd 盤掛載到 /var/lib/ceph/osd 下面的兩個目錄,目錄名爲 ceph-<osd id>
/dev/sdc1 on /var/lib/ceph/osd/ceph-2 type xfs (rw,noatime,inode64) /dev/sdb1 on /var/lib/ceph/osd/ceph-0 type xfs (rw,noatime,inode64)
而日誌盤則會在各自的 osd 目錄下建立一個 link,好比 /var/lib/ceph/osd/ceph-2/journal:
lrwxrwxrwx 1 root root 9 Jun 1 18:07 journal -> /dev/sdd2
完成後查看 OSD 狀態:
root@ceph1:~# ceph osd tree # id weight type name up/down reweight -1 0.1399 root default -2 0.03998 host ceph1 3 0.01999 osd.3 up 1 6 0.01999 osd.6 up 1 -3 0.05997 host ceph2 4 0.01999 osd.4 up 1 7 0.01999 osd.7 up 1 -4 0.03998 host ceph3 5 0.01999 osd.5 up 1 8 0.01999 osd.8 up 1
(5)將 Admin key 複製到其他各個節點,而後安裝 MDS 集羣
ceph-deploy admin ceph1 ceph2 ceph3
ceph-deploy mds create ceph1 ceph2
完成後可使用 「ceph mds」 命令來操做 MDS 集羣,好比查看狀態:
root@ceph1:~# ceph mds stat e13: 1/1/1 up {0=ceph1=up:active}, 1 up:standby
看起來 MDS 集羣是個 active/standby 模式的集羣。
至此,Ceph 集羣部署完成,可使用 ceph 命令查看集羣狀態:
root@ceph1:~# ceph mds stat e13: 1/1/1 up {0=ceph1=up:active}, 1 up:standby root@ceph1:~# ceph -s cluster 4387471a-ae2b-47c4-b67e-9004860d0fd0 health HEALTH_OK monmap e1: 3 mons at {ceph1=192.168.1.194:6789/0,ceph2=192.168.1.195:6789/0,ceph3=192.168.1.218:6789/0}, election epoch 16, quorum 0,1,2 ceph1,ceph2,ceph3 mdsmap e13: 1/1/1 up {0=ceph1=up:active}, 1 up:standby osdmap e76: 10 osds: 7 up, 7 in
在這過程當中,失敗和反覆是不免的,在任什麼時候候,可使用以下的命令將已有的配置擦除而後從頭安裝:
ceph-deploy purge ceph{1,2,3} ceph-deploy purgedata ceph{1,2,3} ceph-deploy forgetkeys
爲方便起見,管理網絡直接鏈接物理網卡;租戶網絡就比較麻煩一點,由於機器上只有一個物理網卡,幸好全部的計算節點都在同一個物理服務器上,所以能夠:
1. 在物理服務器上,建立一個虛擬網卡 tap0,再建立一個 linux bridge ‘mgtbr0’
tunctl -t tap0 -u root chmod 666 /dev/net/tun ifconfig tap0 0.0.0.0 promisc brctl addbr mgtbr0 brctl addif mgtbr0 tap0
2. 這是 mgtbr0 的配置腳本:
[root@rh65 ~]# cat /etc/sysconfig/network-scripts/ifcfg-mgtbr0 DEVICE=mgtbr0 TYPE=Ethernet ONBOOT=yes NM_CONTROLLED=no BOOTPROTO=static IPADDR=10.0.0.100 PREFIX=24 GATEWAY=10.0.0.1 DEFROUTE=yes IPV4_FAILURE_FATAL=yes IPV6INIT=no TYPE=Bridge
3. 在網絡和各計算節點上,增長一塊網卡,鏈接到物理服務器上的 bridge。
把全部的節點鏈接到管理和租戶網絡後,在物理服務器上看到的 linux bridge 是這樣子:
bridge name bridge id STP enabled interfaces br0 8000.3440b5d905ee no eth1 #物理網卡 vnet0 #controller 節點 vnet1 #network 節點 vnet2 #compute1 節點 vnet3 #compute2 節點 vnet4 #ceph1 節點 vnet5 #ceph2 節點 vnet8 #ceph3 節點 br1 8000.000000000000 no mgtbr0 8000.f29e2c075ca6 no tap0 #虛擬網卡 vnet6 #network 節點 vnet7 #compute1 節點 vnet9 #compute2 節點
參考 Installation Guide for Ubuntu 14.04 (LTS) 完成配置,沒感受到 Kilo 版本和 Juno 版本太大的不一樣,除了 keystone 使用 Apache web server 替代了 Keystone WSGI Server 之外(注意不能同時啓動 apache2 和 keystone 服務,二者有衝突,感受 Kilo 版本中 Identity 部分改動很大,仍是存在很多問題)。
本例中,OpenStack Cinder、Glance 和 Nova 分別會將卷、鏡像和虛機鏡像保存到 Ceph 分佈式塊設備(RBD)中。
(1)在 ceph 中建立三個 pool 分別給 Cinder,Glance 和 nova 使用
ceph osd pool create volumes 64 ceph osd pool create images 64 ceph osd pool create vms 64
(2)將 ceph 的配置文件傳到 ceph client 節點 (glance-api, cinder-volume, nova-compute andcinder-backup)上:
ssh controller sudo tee /etc/ceph/ceph.conf </etc/ceph/ceph.conf ssh compute1 sudo tee /etc/ceph/ceph.conf </etc/ceph/ceph.conf ssh compute2 sudo tee /etc/ceph/ceph.conf </etc/ceph/ceph.conf
(3)在各節點上安裝ceph 客戶端
在 glance-api 節點,安裝 librbd sudo apt-get install python-rbd 在 nova-compute 和 cinder-volume 節點安裝 ceph-common: sudo apt-get install ceph-common
(4)配置 cinder 和 glance 用戶訪問 ceph 的權限
# cinder 用戶會被 cinder 和 nova 使用,須要訪問三個pool
ceph auth get-or-create client.cinder mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=volumes, allow rwx pool=vms, allow rx pool=images'
# glance 用戶只會被 Glance 使用,只須要訪問 images 這個 pool ceph auth get-or-create client.glance mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=images'
(5)將 client.cinder 和 client.glance 的 keystring 文件拷貝到各節點並設置訪問權限
ceph auth get-or-create client.glance | ssh controller sudo tee /etc/ceph/ceph.client.glance.keyring
ssh controller sudo chown glance:glance /etc/ceph/ceph.client.glance.keyring
ceph auth get-or-create client.cinder | ssh controller sudo tee /etc/ceph/ceph.client.cinder.keyring
ssh controller sudo chown cinder:cinder /etc/ceph/ceph.client.cinder.keyring
ceph auth get-or-create client.cinder | ssh compute1 sudo tee /etc/ceph/ceph.client.cinder.keyring
ceph auth get-or-create client.cinder | ssh compute2 sudo tee /etc/ceph/ceph.client.cinder.keyring
(6)在 compute1 和 compute2 節點上作 libvirt 配置
ceph auth get-key client.cinder | ssh compute1 tee client.cinder.key
cat > secret.xml <<EOF
<secret ephemeral='no' private='no'>
<uuid>e21a123a-31f8-425a-86db-7204c33a6161</uuid>
<usage type='ceph'>
<name>client.cinder secret</name>
</usage>
</secret>
EOF
sudo virsh secret-define --file secret.xml
sudo virsh secret-set-value --secret e21a123a-31f8-425a-86db-7204c33a6161 --base64 $(cat client.cinder.key) && rm client.cinder.key secret.xml
在 /etc/glance/glance-api.conf 文件中作以下修改: [DEFAULT] ... show_image_direct_url = True ... [glance_store] stores=glance.store.rbd.Store (設置爲 rbd 也能夠?) default_store = rbd rbd_store_pool = images rbd_store_user = glance rbd_store_ceph_conf = /etc/ceph/ceph.conf rbd_store_chunk_size = 8
注意:若是在建立 image 時候出現 AttributeError: 'NoneType' object has no attribute 'Rados' 錯誤,則須要安裝 python-rados
修改 /etc/cinder/cinder.conf: [DEFAULT] ... #volume_group = cinder-volumes volume_driver = cinder.volume.drivers.rbd.RBDDriver rbd_pool = volumes rbd_ceph_conf = /etc/ceph/ceph.conf rbd_flatten_volume_from_snapshot = false rbd_max_clone_depth = 5 rbd_store_chunk_size = 4 rados_connect_timeout = -1 glance_api_version = 2 rbd_user = cinder rbd_secret_uuid = e21a123a-31f8-425a-86db-7204c33a6161 ...
注意:
(1)cinder-volume 節點上的 ceph 配置文件是必須存在的,由於 cinder-volume 須要使用它來創建和 Ceph 集羣的鏈接,不存在的話則會報錯誤。
cinder/volume/drivers/rbd.py 文件:
client = self.rados.Rados(rados_id=self.configuration.rbd_user, conffile=self.configuration.rbd_ceph_conf)
缺失 ceph 配置文件時 cinder-volume 報錯:
2016-01-02 18:23:54.127 25433 INFO cinder.volume.manager [req-d921feed-db0b-4643-b01b-13dde3da6285 - - - - -] Starting volume driver RBDDriver (1.1.0) 2016-01-02 18:23:54.162 25433 ERROR cinder.volume.manager [req-d921feed-db0b-4643-b01b-13dde3da6285 - - - - -] Error encountered during initialization of driver: RBDDriver 2016-01-02 18:23:54.163 25433 ERROR cinder.volume.manager [req-d921feed-db0b-4643-b01b-13dde3da6285 - - - - -] error calling conf_read_file: errno EINVAL
對 cinder-volume 來講,它所須要的 ceph.conf 中的信息主要是 MON 服務器的地址,以及cinder 所使用的用戶的驗證方式,所以須要將 keystring 文件 ceph.client.cinder.keyring 放在同一個目錄下面。
mon_initial_members = ceph1, ceph2, ceph3 mon_host = 9.115.251.194,9.115.251.195,9.115.251.218 auth_cluster_required = cephx auth_service_required = cephx auth_client_required = cephx filestore_xattr_use_omap = true
(2)能夠支持 multi-backend 配置,在每一個 backend 中使用不一樣的 Ceph pool,甚至使用不一樣的 rbd_ceph_conf 來支持多個 Ceph 集羣。
作完以上配置以後,你就能夠經過cinder 在 Ceph 中建立 volume 了。
其實 nova compute 使用 RBD 有兩種功能:
修改 nova compute 節點上的 nova.conf 文件:
[libvirt] rbd_user = cinder rbd_secret_uuid = e21a123a-31f8-425a-86db-7204c33a6161
若是隻是將 ceph volume 掛接到 Nova 虛機的話,nova-compute 是不須要從 ceph 配置文件中讀取 MON 服務器的信息的,而是調用 cinder api 去獲取。所以,在計算節點上缺失 ceph 配置文件實際上是不影響將 ceph 卷掛接到 nova 虛機的。 注意這是 Havana 之後的行爲,對於以前的版本,nova-compute 從 ceph 配置文件中讀取 MON 信息,所以須要 ceph 配置文件。詳見 ticket:Nova failed to mount a RBD volume without extra ceph.conf。作了這個改動之後,另外一個好處是,向 nova 支持多個 ceph 集羣提供了可能,由於使用 ceph 配置文件的話只能使用一個文件,而 cinder 中能夠 使用 multi-backend 技術來支持多個 ceph 集羣。
因此 nova.conf 中主要是配置訪問 ceph 的 user 和 secret id,以便從本機上保存的 secrets 中獲取密鑰。配置文件中只保存有 rbd secret id,由於本機上須要有該 id 對應的 secret的完整內容。
關於爲何只須要這兩個參數,還能夠閱讀 LibvirtNetVolumeDriver 類的代碼,該類實現了 libirt 訪問 Ceph 等網絡存儲的功能。
在執行 nova attach-volume 以後(以下圖步驟5),nova-compute 會修改 nova instance 的 libvirt xml 文件。示例以下:
<disk type='network' device='disk'> <driver name='qemu' type='raw' cache='writeback'/> <auth username='cinder'> <secret type='ceph' uuid='e21a123a-31f8-425a-86db-7204c33a6161'/> </auth> <source protocol='rbd' name='volumes/volume-b4e9a905-d59e-46e4-aa6d-e57c90000013'> <host name='9.115.251.194' port='6789'/> <host name='9.115.251.195' port='6789'/> <host name='9.115.251.218' port='6789'/> </source> <backingStore/> <target dev='vdb' bus='virtio'/> <serial>b4e9a905-d59e-46e4-aa6d-e57c90000013</serial> <alias name='virtio-disk1'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> </disk>
所以,若是隻是須要支持將 Ceph 卷掛接到 nova 虛機的話,能夠在計算節點上的 ceph 配置文件中,能夠只保留 client 部分的配置信息,包括 RBD Cache 的配置以及日誌配置等,這樣就能夠避免和具體哪個 Ceph 集羣的硬綁定。而這個配置實際上是給 librbd 準備的,便於對它進行調試。下面是一個配置示例:
[client] rbd cache = true #rbd cache = false #rbd cache writethrough until flush = true #admin socket = /var/run/ceph/$cluster-$type.$id.$pid.$cctid.asok log file = /var/log/ceph/qemu-guest.$pid.log #log file = /var/lib/libvirt/qemu/qemu-guest.$pid.log admin socket=/var/log/ceph/rbd-$pid.asok debug rbd = 20 debug rbd = 20, debug objectcacher=20 debug objecter=20 debug ms = 1
做爲參考,下圖爲掛接 iSCSI volume 給虛機的大體流程,能夠看出來掛接 Ceph volume 的流程簡化了不少,由於不須要作 iSCSI 配置:
說明:
{‘driver_volume_type’: ‘iscsi’, ‘data’: {‘auth_password’: ‘YZ2Hceyh7VySh5HY’, ‘target_discovered’: False, ‘encrypted’: False, ‘qos_specs’: None, ‘target_iqn’: ‘iqn.2010-10.org.openstack:volume-8b1ec3fe-8c5 ‘target_portal’: ‘11.0.0.8:3260′, ‘volume_id’: ‘8b1ec3fe-8c57-45ca-a1cf-a481bfc8fce2′, ‘target_lun’: 1, ‘access_mode’: ‘rw’, ‘auth_username’: ‘nE9PY8juynmmZ95F7Xb7′, ‘auth_method’: ‘CHAP’}}
<disk type='block' device='disk'> <driver name='qemu' type='raw' cache='none' io='native'/> <source dev='/dev/disk/by-path/ip-10.0.0.2:3260-iscsi-iqn.2010-10.org.openstack:volume-2ed1b04c-b34f-437d-9aa3-3feeb683d063-lun-0'/> <target dev='vdb' bus='virtio'/> <serial>2ed1b04c-b34f-437d-9aa3-3feeb683d063</serial> <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> </disk>
在每一個計算節點上的 /etc/nova/nova.conf 文件中作以下修改。與 4.3.3.1 中的配置相比,增長了 images 相關配置,這是由於 nova-compute 須要本身管理 rbd image 了(實現是經過 RBD imagebackend,它會調用 rbd 命令來建立 volume 並導入 image,並在須要的時候作 resize)。
[libvirt] images_type = rbd #只有在 boot disk 放在 ceph 中才須要配置這個,不然,設置爲 qcow2 images_rbd_pool = vms images_rbd_ceph_conf = /etc/ceph/ceph.conf rbd_user = cinder rbd_secret_uuid = e21a123a-31f8-425a-86db-7204c33a6161 disk_cachemodes="network=writeback" hw_disk_discard = unmap 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"
當用戶選擇將 boot disk 放在 Ceph 中的話,須要在 nova.conf 中配置 images_rbd_ceph_conf ,這是由於就像 cinder-volume 同樣,nova-compute 須要使用 ceph.conf 和其它參數建立和 Ceph 的鏈接,而後使用 」rbd import --pool 「命令來建立 image。這種狀況下,若是沒有 ceph.conf 文件的話,啓動 nova-compute 服務時就會報錯:
2016-01-02 22:27:30.920 25407 ERROR nova.openstack.common.threadgroup [req-9a61379c-52e9-48b7-9f7c-91c928fdaf2b - - - - -] error calling conf_read_file: errno EINVAL
所以,此時的 nova-compute 和 glance 以及 cinder-volume 的角色沒什麼不一樣,它們也須要使用相同的 ceph 配置文件。
至此,環境安裝和配置完成,經過 cinder,glance 和 nova 命令建立的卷、鏡像和虛機的鏡像都會被保存在 Ceph 的 RBD 中。接下來的文章會深刻分析其中的原理和實現。
參考文檔: