Ceph部署、基本使用和與OpenStack的整合

2020-08-14 11:06:36

本文並非關於Ceph的系統介紹,沒有對Ceph原理等知識的介紹,基本都是操作命令。內容參考自Ceph官方文件,以及《Ceph Cookbook》。

本文內容在CentOS7上進行過幾次成功的部署,沒坑,所部署的Ceph版本爲nautilus,部署工具爲ceph-deploy

0 準備工作

0.1 安裝ceph-deploy

以下方法二選一。

0.1.1 直接安裝ceph-deploy

可以到國內的源中查詢rpm包直接安裝,比如阿裡雲

rpm -Uvh https://mirrors.aliyun.com/ceph/rpm-nautilus/el7/noarch/ceph-deploy-2.0.1-0.noarch.rpm  
yum install -y epel-release python-setuptools

0.1.2 基於repo來安裝

# 命令來自官方文件
sudo yum install -y yum-utils && sudo yum-config-manager --add-repo https://dl.fedoraproject.org/pub/epel/7/x86_64/ && sudo yum install --nogpgcheck -y epel-release && sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 && sudo rm /etc/yum.repos.d/dl.fedoraproject.org*

建立一個軟體庫組態檔。

sudo vim /etc/yum.repos.d/ceph.repo

內容如下:

[ceph-noarch]
name=Ceph noarch packages
baseurl=https://mirrors.aliyun.com/ceph/rpm-nautilus/el7/noarch
enabled=1
gpgcheck=1
priority=1
type=rpm-md
gpgkey=https://mirrors.aliyun.com/ceph/keys/release.asc

ceph-deploy是在noarch下的,所以先新增這個即可。然後就可以安裝ceph-deploy了。

sudo yum install ceph-deploy python-setuptools

0.2 Ceph節點設定

0.2.1 安裝chrony

sudo yum install -y chrony

mv /etc/chrony.conf /etc/chrony.conf.bak

cat > /etc/chrony.conf <<EOF
server ntp.aliyun.com iburst
stratumweight 0
driftfile /var/lib/chrony/drift
rtcsync
makestep 10 3
bindcmdaddress 127.0.0.1
bindcmdaddress ::1
keyfile /etc/chrony.keys
commandkey 1
generatecommandkey
logchange 0.5
logdir /var/log/chrony
EOF

systemctl enable chronyd
systemctl restart chronyd

0.2.2 建立Ceph使用者(可選)

在各 Ceph 節點建立新使用者。

ssh user@ceph-server
sudo useradd -d /home/{username} -m {username}
sudo passwd {username}

確保各 Ceph 節點上新建立的使用者都有 sudo 許可權。

echo "{username} ALL = (root) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/{username}
sudo chmod 0440 /etc/sudoers.d/{username}

0.2.3 SSH設定

安裝SSH伺服器:

sudo yum install openssh-server

設定ceph-deploy到ceph各節點的SSH免密登錄:

# 生成金鑰對
ssh-kengen

# 設定免密登錄
ssh-copy-id {username}@node1
ssh-copy-id {username}@node2
ssh-copy-id {username}@node3

如果使用非root使用者進行部署,那麼推薦修改~/.ssh/config檔案,

Host node1
   Hostname node1
   User {username}
Host node2
   Hostname node2
   User {username}
Host node3
   Hostname node3
   User {username}

0.2.4 開放埠

MON預設使用33006789埠,OSD預設使用6800-7300埠,RGW使用7480埠。

sudo firewall-cmd --zone=public --add-port=3300/tcp --permanent
sudo firewall-cmd --zone=public --add-port=6789/tcp --permanent
sudo firewall-cmd --zone=public --add-port=7480/tcp --permanent
sudo firewall-cmd --zone=public --add-port=6800-7300/tcp --permanent

0.2.5 關閉SELINUX

sudo setenforce 0

要使 SELinux 設定永久生效(如果它的確是問題根源),需修改其組態檔/etc/selinux/config

1 部署Ceph儲存叢集

先在管理節點上建立一個目錄(非root使用者可以選擇其他目錄),用於儲存 ceph-deploy 生成的組態檔和金鑰對。

mkdir /etc/ceph
cd /etc/ceph

ceph-deploy 會把有些檔案輸出到當前目錄,最好在此目錄下執行 ceph-deploy 。

1.0 重新部署

# 解除安裝Ceph
ceph-deploy purge {ceph-node} [{ceph-node}]
cd
# 清掉數據
ceph-deploy purgedata {ceph-node} [{ceph-node}]
# 刪除key
ceph-deploy forgetkeys
# 刪除所有ceph-deploy產生的檔案
rm ceph.*

# 在有OSD的節點刪除ceph建立的LVM
lvremove -f $(lvdisplay | grep "/dev/ceph" | awk '{print $3}')
vgremove -f $(vgscan | grep ceph | awk '{print $4}' | tr -d \")

1.1 建立叢集

1.1.1 初始化一個叢集

在管理節點上,進入剛建立的放置組態檔的目錄,用 ceph-deploy 執行如下步驟。

ceph-deploy new {initial-monitor-node(s)}
# 例如(多個節點用空格隔開):
# ceph-deploy new node1

在當前目錄下用 lscat 檢查 ceph-deploy 的輸出,應該有一個 Ceph 組態檔、一個 monitor 金鑰環和一個日誌檔案。

1.1.2 網路設定

如果有多個網絡卡,需要在[global]中設定public network

public network = {ip-address}/{prefix}
cluster network = {ip-address}/{prefix}
# 例如
# public network = 10.1.2.0/24
# cluster network = 10.2.2.0/24

1.1.3 安裝Ceph包:

# 使用阿裡雲的源
export CEPH_DEPLOY_REPO_URL=https://mirrors.aliyun.com/ceph/rpm-nautilus/el7
export CEPH_DEPLOY_GPG_URL=https://mirrors.aliyun.com/ceph/keys/release.asc
# 安裝
ceph-deploy install {ceph-node} [{ceph-node} ...]
# 例如:
# ceph-deploy install admin-node node1 node2 node3

ceph-deploy 將在各節點安裝 Ceph 。

1.1.4 部署初始MON節點

設定初始 monitor(s)、並收集所有金鑰:

ceph-deploy mon create-initial

完成上述操作後,當前目錄裡應該會出現這些金鑰環:

ceph.client.admin.keyring
ceph.bootstrap-mgr.keyring
ceph.bootstrap-osd.keyring
ceph.bootstrap-mds.keyring
ceph.bootstrap-rgw.keyring

1.1.5 複製組態檔到其他節點

複製組態檔(ceph.conf)和admin的key(ceph.client.admin.keyring)到其他節點,這樣在相應的節點上就可以無需指定MON地址和keyring來執行ceph命令了。

ceph-deploy admin {ceph-node(s)}
# 例如
# ceph-deploy admin node1 node2 node3

1.1.6 部署一個manager daemon

luminous+的版本需執行:

ceph-deploy mgr create node1 

1.1.7 新增OSD

新增前確保要使用的磁碟裝置上沒有重要數據,並且沒有LVM虛擬卷和卷組。

ceph-deploy osd create --data {data-disk}
# 例如
# ceph-deploy osd create --data /dev/sdb node1

nautilus版本預設使用bluestore,早期版本一般使用filestore。

兩種不同的檔案系統在使用SSD做journal的時候是不同的方式,具體可以參考:如何ssd作爲ceph-osd的日誌盤使用

1.1.8 檢視健康狀況

ceph -s 
ceph -w # 可以持續檢視健康變化情況

1.2 擴充套件叢集

1.2.1 新增MON節點

一個叢集中至少要有一個MON節點和一個MGR節點。

多個MON節點基於Paxos投票機制 機製工作,因此最好有2N+1個MON節點,以避免單點故障。

ceph-deploy mon add {ceph-node}
# 例如:
# ceph-deploy mon add node2

1.2.2 新增MGR節點

多個Manager節點以active/standby方式工作,若主節點宕機,備節點會接管。

ceph-deploy mgr create node2 node3

如果要新增控制面板功能:

# 安裝 ceph-mgr-dashboard。注意,每個mgr節點都需要安裝
yum install ceph-mgr-dashboard -y
# 啓用 dashboard
ceph mgr module enable dashboard
# 建立自簽名證書
ceph dashboard create-self-signed-cert
# 建立使用者
ceph dashboard ac-user-create <user> <password> administrator
# 防火牆開放8443埠
firewall-cmd --zone=public --add-port=8443/tcp --permanent
firewall-cmd --reload

如果一段時間後發現dashboard無法存取,這樣處理(暫時還沒找到更好辦法)是有效果的:

ceph mgr module disable dashboard
ceph config-key del mgr/dashboard/$name/server_addr
ceph config-key del mgr/dashboard/$name/server_port
ceph config-key del mgr/dashboard/server_addr
ceph config-key del mgr/dashboard/server_port
ceph mgr module enable dashboard
systemctl restart ceph-mgr.target

1.2.3 新增RGW節點

Ceph物件儲存閘道器的使用需要RGW節點。

ceph-deploy rgw create {gateway-node}

預設情況下,RGW監聽7480埠,其他埠可以這樣設定:

[client]
rgw frontends = civetweb port=80

1.3 儲存/讀取物件數據

要在Ceph儲存叢集中儲存物件數據,需要:

  1. 設定物件名稱
  2. 指定一個pool
ceph osd map {poolname} {object-name}

Ceph用戶端會取得最新的叢集map,並用CRUSH演算法計算出如何將物件對映到placement group,然後計算出該placement group在哪個OSD上。

一些命令範例

# 建立一個物件(檔案)
echo {Test-data} > /tmp/testfile.txt

# 建立儲存池
ceph osd pool create mypool 512

# 儲存檔案
# rados put {object-name} {file-path} --pool={pool-name}
rados put testfile /tmp/testfile.txt --pool=mypool

# 檢視物件檔案
rados -p mytest ls

# 下載物件檔案
# rados get {object-name} {file-path} --pool={pool-name}
rados get testfile /tmp/testfile1.txt --pool=mypool

# 檢視物件檔案位置
# ceph osd map {pool-name} {object-name}
ceph osd map mypool testfile

# 刪除物件
rados rm testfile --pool=mypool

# 刪除儲存池
ceph osd pool rm mypool

2 塊裝置服務

2.1 基本操作

0.建立塊裝置儲存池

# 在admin節點,使用`ceph`命令來建立一個pool(`rbd`)
ceph osd pool create rbd 512
# 在admin節點,使用`rbd`命令來初始化pool
rbd pool init rbd

具體pg_num應該如何確定,可以參考這個計算網站

1.在ceph-client節點上,建立一個塊裝置映象。

# rbd create foo --size 4096 --image-feature layering [-m {mon-IP}] [-k /path/to/ceph.client.admin.keyring] [-p {pool-name}]
rbd create rbd1 --size 4096 --image-feature layering -m 192.168.1.102 -k /etc/ceph/ceph.client.admin.keyring -p rbd 

2.在ceph-client節點上,對映到一個塊裝置。

# sudo rbd map foo --name client.admin [-m {mon-IP}] [-k /path/to/ceph.client.admin.keyring] [-p {pool-name}]
rbd map rbd0 --name client.admin -m 192.168.1.102 -k /etc/ceph/ceph.client.admin.keyring -p rbd

如果上一條命令報如下錯誤:

modinfo: ERROR: Module rbd not found.
modprobe: FATAL: Module rbd not found.
rbd: failed to load rbd kernel module (1)

則需升級kernel

3.在塊裝置上建立檔案系統。

# sudo mkfs.ext4 -m0 /dev/rbd/{pool-name}/foo
sudo mkfs.ext4 -m0 /dev/rbd/rbd/rbd0(/dev/rbd0)

4.掛載檔案系統。

sudo mkdir /mnt/ceph-block-device
sudo mount /dev/rbd0 /mnt/ceph-block-device
cd /mnt/ceph-block-device

2.2 rbd命令

2.2.1 建立塊裝置

# 建立塊裝置(單位MB)
rbd create rbd0 --size 10240 --name client.rbd

# 檢視塊裝置
rbd ls --name client.rbd
rbd ls -p rbd --name client.rbd
rbd info --image rbd/rbd0

2.2.2 對映塊裝置

# 預設儲存池是rbd,否則需要指定 -p {pool_name}
rbd map --image rbd/rbd0 --name client.rbd
rbd showmapped --name client.rbd

# 掛載到檔案系統
mkfs.xfs /dev/rbd0
mkdir /mnt/rbd0
mount /dev/rbd0 /mnt/rbd0

# 取消對映
umount /mnt/rbd0
rbd unmap --image rbd/rbd0

掛載需要內核支援,如果在mount的時候提示沒有rbd模組(具體啥錯誤不記得了),可以執行
modprobe rbd,然後,lsmod | grep rbd看看是否已經有該模組了。
如果依然沒有,可能需要升級內核:yum update kernel(這篇文章發出來的時候,CentOS7最新的內核已經有rbd模組了)。

2.2.3 調整RBD大小

# 調整大小
rbd resize --image rbd/rbd0 --size 20480 --name client.rbd
xfs_growfs /dev/rbd0

2.2.4 快照

rbd snap create rbd/rbd0@snapshot1 --name client.rbd
# rollback時需要先unmap RBD
rbd snap rollback rbd/rbd0@snapshot1 --name client.rbd
rbd snap ls rbd/rbd0 --name client.rbd
rbd snap rm rbd/rbd0@snapshot1 --name client.rbd
# 刪除所有快照
rbd snap purge rbd/rbd0 --name client.rbd

2.2.5 克隆

# 建立一個快照用於克隆
rbd snap create rbd/rbd1@snapshot_for_cloning
# 克隆前需要先保護起來,以防被刪除
rbd snap protect rbd/rbd1@snapshot_for_cloning
# 克隆
rbd clone rbd/rbd1@snapshot_for_cloning rbd/rbd1_clone
# 檢視資訊,發現其parent屬性指向快照
rbd info rbd1_clone
# 可以將父映象合併到克隆的映象,這樣克隆的映象就獨立了
rbd flatten rbd/rbd1_clone
# 檢視資訊,發現parent屬性清空
rbd info rbd1_clone
# 這時可以取消保護了
rbd snap unprotect rbd/rbd1@snapshot_for_cloning
# 刪除快照
rbd snap rm rbd/rbd1@snapshot_for_cloning

3 CephFS檔案系統

3.1 前提

設定CephFS前,需要先設定好儲存叢集,並且處於active + clean狀態。

3.2 部署METADATA服務

在部署節點執行如下命令:

ceph-deploy mds create {ceph-node}

3.3 建立一個檔案系統

ceph osd pool create cephfs_data 32
ceph osd pool create cephfs_meta 32
# ceph fs new <CephFS名稱> <元數據儲存池> <檔案數據儲存池>
ceph fs new mycephfs cephfs_meta cephfs_data

建議:儲存池可以命名爲..,這樣上邊的pool可以命名爲cephfs.mycehfs.data和cephfs.mycehfs.meta。

以上兩個儲存池分別用來儲存檔案的實際數據和元數據,可以放在不同的儲存媒介上的,比如元數據儲存池可以放在SSD上,相關操作可以參考同一個ceph叢集分別建立ssd和hdd池

3.4 掛載檔案系統

3.4.1 使用內核驅動

掛載命令如下:

sudo mount -t ceph :{path-to-mounted} {mount-point} -o name={user-name}
sudo mount -t ceph :/ /mnt/mycephfs -o name=admin   # usable version

完整的命令:sudo mount -t ceph {ip-address-of-MON}:{port-number-of-MON}:{path-to-be-mounted} -o name={user-name},secret={secret-key} {mount-point}

{path-to-be-mounted}是CephFS內的路徑,{mount-point}是用戶端要掛載的路徑,{user-name}是具備掛載CephFS許可權的CephX使用者。

3.4.2 使用FUSE

使用FUSE(Filesystem in User Space)來掛載CephFS:

sudo ceph-fuse /mnt/mycephfs

如果要指定掛載目錄可以使用-r

sudo ceph-fuse -r {path-to-be-mounted} /mnt/mycephfs

4 物件儲存

4.1 安裝Ceph物件閘道器程式

ceph-deploy install --rgw <client-node> [<client-node> ...]

4.2 建立Ceph物件儲存範例

ceph-deploy rgw create <client-node>

4.3 設定Ceph物件儲存範例

1.設定埠號

[client.rgw.client-node]
rgw_frontends = "civetweb port=80"

2.重新啓動服務

sudo systemctl restart ceph-radosgw.service

3.開放埠

sudo firewall-cmd --list-all
sudo firewall-cmd --zone=public --add-port 80/tcp --permanent
sudo firewall-cmd --reload

4.檢視API

curl http://<client-node>:80

API響應如下:

<?xml version="1.0" encoding="UTF-8"?>
<ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Owner>
    <ID>anonymous</ID>
    <DisplayName></DisplayName>
  </Owner>
  <Buckets>
  </Buckets>
</ListAllMyBucketsResult>

5 使用者與許可權

5.1 設定用戶端與使用者

1.在ceph-deploy執行節點執行如下命令:

ceph-deploy install client-node

2.將組態檔複製到client-node節點:

ceph-deploy config push client-node

3.一般不建議直接把client.admin複製到用戶端節點,可以建立使用者:

# 建立使用者client.admin
ceph auth get-or-create client.rbd mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool =rbd'

4.將金鑰新增到client-node節點:

ceph auth get-or-create client.rbd | ssh root@client-node tee /etc/ceph/ceph.client.rbd.keyring

5.使用金鑰的時候需要指定使用者名稱

ceph -s --name client.rbd

6 Ceph與OpenStack的整合

6.1 將OpenStack設定爲Ceph用戶端

1.首先設定ceph-deploy節點到OpenStack節點(os-node)的SSH免密登錄。

2.在os-node上安裝Ceph。

ceph-deploy install os-node

3.將ceph組態檔ceph.conf推播到os-node節點。

ceph-deploy config push os-node

4.建立Ceph儲存池。

ceph osd pool create images 128
ceph osd pool create volumes 128
ceph osd pool create vms 128

5.爲cinderglance建立新使用者。

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'
ceph auth get-or-create client.glance mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=images'

6.爲os-node新增keyring。

ceph auth get-or-create client.glance | ssh os-node tee /etc/ceph/ceph.client.glance.keyring
ssh os-node chown glance:glance ceph.client.glance.keyring
ceph auth get-or-create client.cinder | ssh os-node tee /etc/ceph/ceph.client.cinder.keyring
ssh os-node chown cinder:cinder ceph.client.cinder.keyring

7.當從cinder掛載或解除安裝裝置時,libvirt進程需要有存取Ceph叢集的許可權。

# 在ceph節點建立一個臨時的金鑰副本,並傳至OpenStack節點
ceph auth get-key client.cinder | ssh os-node tee /etc/ceph/temp.client.cinder.key
# 在OpenStack節點建立金鑰
# ① 先生成uuid
uuidgen
# ② 用輸出的uuid編寫金鑰檔案
cat > secret.xml <<EOF
<secret ephemeral='no' private='no'>
  <uuid>{剛剛生成的uuid}</uuid>
  <usage type='ceph'>
    <name>client.cinder secret</name>
  </usage>
</secret>
EOF
# ③ 定義金鑰檔案
virsh secret-define --file secret.xml
# ④ 設定好金鑰值
virsh secret-set-value --secret {剛剛生成的uuid} --base64 $(cat temp.client.cinder.key)
virsh secret-list

6.2 設定Ceph爲Glance後端儲存

在OpenStack節點,編輯/etc/glance/glance-api.conf

default_store=rbd
show_image_direct_url=True
...
[glance_store]
stores=rbd
rbd_store_ceph_conf=/etc/ceph/ceph.conf
rbd_store_user=glance
rbd_store_pool=images
rbd_store_chunk_size=8

重新啓動glance-api服務。

systemctl restart openstack-glance-api

測試一下:

glance image-list
# 下載cirros映象,並上傳至glance
glance image-create --name cirros_0.5 --is-public=true --disk-format=qcow2 --container-format=bare < cirros-0.5.1-x86_64-disk.img

glance image-list
# 在ceph中驗證
rados -p images ls --name client.glance --keyring /etc/ceph/ceph.client.glance.keyring | grep -i id

6.3 設定Ceph爲Cinder後端儲存

設定/etc/cinder/cincer.conf檔案。其他包括:

glance_api_version=2
rbd_pool=volumes
rbd_user=cinder
rbd_ceph_conf=/etc/ceph/ceph.conf
rbd_flatten_volume_from_snapshot=false
rbd_secret_uuid=1f4e1d20-3c7f-4809-a2dd-dd88efa36c03
rbd_max_clone_depth=5
rbd_store_chunk_size=4
rados_connect_timeout=-1
volume_driver=cinder.volume.drivers.rbd.RBDDriver

重新啓動Cinder服務:

systemctl restart openstack-cinder-volume

然後測試一下設定是否生效:

cinder list
# 建立一個卷
cinder create --display-name ceph-volume01 --display-description "Cinder volume on CEPH storage" 2
# 檢視cinder和rados
cinder list
rados -p volumes --name client.cinder --keyring ceph-client.cinder.keyring ls | grep -i id

6.4 掛載Ceph RBD到Nova上

編輯/etc/nova/nova.conf,找到nova.virt.libvirt.volume部分,新增以下程式碼行:

rbd_user=cinder
rbd_secret_uuid={secret uuid}

重新啓動nova-compute:

systemctl restart openstack-nova-compute

測試一下效果:

nova list
cinder list
# 將以上兩個命令查到的虛擬機器id和卷id用於以下命令:
cinder volume-attach {vm-id} {volume-id}
# 檢視掛載效果
cinder list

6.5 Nova基於Ceph RBD啓動範例

編輯/etc/nova/nova.conf檔案,在[libvirt]部分編輯如下參數:

inject_partition=-2
images_type=rbd
images_rbd_pool=vms
images_rbd_ceph_conf=/etc/ceph/ceph.conf
rbd_user=cinder
rbd_secret_uuid=da6d95af-f8ba-4beb-8d65-60a916160f88

重新啓動nova-compute服務:

systemctl restart openstack-nova-compute

測試一下效果:

# 將QCOW格式的映象轉換爲RAW格式
qemu-img convert -f qcow2 -O raw cirros-0.5.1-x86_64-disk.img cirros-0.5.1-x86_64-disk.raw
# 用RAW映象建立Glance映象
glance image-create --name cirros_raw_image --is-public=true --disk-format=raw --container-format=bare < cirros-0.5.1-x86_64-disk.raw
# 建立一個可引導的捲來測試從Ceph卷啓動虛擬機器
cinder create --image-id 8d1623ab-c3e1-4c30-a4b0-d6ca7fae9bbb --display-name cirros-ceph-boot-volume 1
# 列出Cinder卷,看是不是bootable的
cinder list
# 基於可引導的卷建立虛擬機器範例
nova boot --flavor 1 --block_device_mapping vda=6525f635-85ed-4754-877a-8b556c86334c::0 --image 8d1623ab-c3e1-4c30-a4b0-d6ca7fae9bbb vm2_on_ceph
# 檢查範例狀態
nova list