前言
最近在學習 kubernetes 過程中,想實現 pod 數據的持久化。在調研的過程中,發現 ceph 在最近幾年發展火熱,也有很多案例落地企業。在選型方面,個人更加傾向於社區火熱的項目,GlusterFS、Ceph 都在考慮的范圍之內,但是由於 GlusterFS 只提供對象存儲和文件系統存儲,而 Ceph 則提供對象存儲、塊存儲以及文件系統存儲。懷着對新事物的向往,果斷選擇 Ceph 來實現 Ceph 塊存儲對接 kubernetes 來實現 pod 的數據持久化。
一、初始 Ceph
1.1 了解什么是塊存儲/對象存儲/文件系統存儲?
直接進入主題,ceph 目前提供對象存儲(RADOSGW)、塊存儲RDB以及 CephFS 文件系統這 3 種功能。對於這3種功能介紹,分別如下:
1.對象存儲,也就是通常意義的鍵值存儲,其接口就是簡單的GET、PUT、DEL 和其他擴展,代表主要有 Swift 、S3 以及 Gluster 等;
2.塊存儲,這種接口通常以 QEMU Driver 或者 Kernel Module 的方式存在,這種接口需要實現 Linux 的 Block Device 的接口或者 QEMU 提供的 Block Driver 接口,如 Sheepdog,AWS 的 EBS,青雲的雲硬盤和阿里雲的盤古系統,還有 Ceph 的 RBD(RBD是Ceph面向塊存儲的接口)。在常見的存儲中 DAS、SAN 提供的也是塊存儲;
3.文件存儲,通常意義是支持 POSIX 接口,它跟傳統的文件系統如 Ext4 是一個類型的,但區別在於分布式存儲提供了並行化的能力,如 Ceph 的 CephFS (CephFS是Ceph面向文件存儲的接口),但是有時候又會把 GlusterFS ,HDFS 這種非POSIX接口的類文件存儲接口歸入此類。當然 NFS、NAS也是屬於文件系統存儲;
1.2 Ceph 組件介紹
從下面這張圖來簡單學習下,Ceph 的架構組件。(提示:本人在學習過程中所繪,如果發現問題歡迎留言,不要噴我喲)
Monitor, 負責監視整個集群的運行狀況,信息由維護集群成員的守護程序來提供,各節點之間的狀態、集群配置信息。Ceph monitor map主要包括OSD map、PG map、MDS map 和 CRUSH 等,這些 map 被統稱為集群 Map。ceph monitor 不存儲任何數據。下面分別開始介紹這些map的功能:
- Monitor map:包括有關monitor 節點端到端的信息,其中包括 Ceph 集群ID,監控主機名和IP以及端口。並且存儲當前版本信息以及最新更改信息,通過 "ceph mon dump" 查看 monitor map。
- OSD map:包括一些常用的信息,如集群ID、創建OSD map的 版本信息和最后修改信息,以及pool相關信息,主要包括pool 名字、pool的ID、類型,副本數目以及PGP等,還包括數量、狀態、權重、最新的清潔間隔和OSD主機信息。通過命令 "ceph osd dump" 查看。
- PG map:包括當前PG版本、時間戳、最新的OSD Map的版本信息、空間使用比例,以及接近占滿比例信息,同事,也包括每個PG ID、對象數目、狀態、OSD 的狀態以及深度清理的詳細信息。通過命令 "ceph pg dump" 可以查看相關狀態。
- CRUSH map: CRUSH map 包括集群存儲設備信息,故障域層次結構和存儲數據時定義失敗域規則信息。通過 命令 "ceph osd crush map" 查看。
- MDS map:MDS Map 包括存儲當前 MDS map 的版本信息、創建當前的Map的信息、修改時間、數據和元數據POOL ID、集群MDS數目和MDS狀態,可通過"ceph mds dump"查看。
OSD,Ceph OSD 是由物理磁盤驅動器、在其之上的 Linux 文件系統以及 Ceph OSD 服務組成。Ceph OSD 將數據以對象的形式存儲到集群中的每個節點的物理磁盤上,完成存儲數據的工作絕大多數是由 OSD daemon 進程實現。在構建 Ceph OSD的時候,建議采用SSD 磁盤以及xfs文件系統來格式化分區。BTRFS 雖然有較好的性能,但是目前不建議使用到生產中,目前建議還是處於圍觀狀態。
Ceph 元數據,MDS。ceph 塊設備和RDB並不需要MDS,MDS只為 CephFS服務。
RADOS,Reliable Autonomic Distributed Object Store。RADOS是ceph存儲集群的基礎。在ceph中,所有數據都以對象的形式存儲,並且無論什么數據類型,RADOS對象存儲都將負責保存這些對象。RADOS層可以確保數據始終保持一致。
librados,librados庫,為應用程度提供訪問接口。同時也為塊存儲、對象存儲、文件系統提供原生的接口。
ADOS塊設備,它能夠自動精簡配置並可調整大小,而且將數據分散存儲在多個OSD上。
RADOSGW,網關接口,提供對象存儲服務。它使用librgw和librados來實現允許應用程序與Ceph對象存儲建立連接。並且提供S3 和 Swift 兼容的RESTful API接口。
CephFS,Ceph文件系統,與POSIX兼容的文件系統,基於librados封裝原生接口。
簡單說下CRUSH,Controlled Replication Under Scalable Hashing,它表示數據存儲的分布式選擇算法, ceph 的高性能/高可用就是采用這種算法實現。CRUSH 算法取代了在元數據表中為每個客戶端請求進行查找,它通過計算系統中數據應該被寫入或讀出的位置。CRUSH能夠感知基礎架構,能夠理解基礎設施各個部件之間的關系。並且CRUSH保存數據的多個副本,這樣即使一個故障域的幾個組件都出現故障,數據依然可用。CRUSH 算是使得 ceph 實現了自我管理和自我修復。
RADOS 分布式存儲相較於傳統分布式存儲的優勢在於:
1. 將文件映射到object后,利用Cluster Map 通過CRUSH 計算而不是查找表方式定位文件數據存儲到存儲設備的具體位置。優化了傳統文件到塊的映射和Block MAp的管理。
2. RADOS充分利用OSD的智能特點,將部分任務授權給OSD,最大程度地實現可擴展。
二、安裝 Ceph
2.1 環境准備
## 環境說明
主機 IP 功能
ceph-node01 192.168.58.128 deploy、mon*1、osd*3
ceph-node02 192.168.58.129 mon*1、 osd*3
ceph-node03 192.168.58.130 mon*1 、osd*3
## 准備 yum 源
cd /etc/yum.repos.d/ && sudo mkdir bak sudo mv *.repo bak/ sudo wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo sudo wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo sudo sed -i '/aliyuncs/d' /etc/yum.repos.d/CentOS-Base.repo sudo sed -i '/aliyuncs/d' /etc/yum.repos.d/epel.repo sudo sed -i 's/$releasever/7/g' /etc/yum.repos.d/CentOS-Base.repo
## 添加 Ceph 源
sudo cat <<EOF > /etc/yum.repos.d/ceph.repo [Ceph] name=Ceph packages for x86_64 baseurl=https://mirrors.aliyun.com/ceph/rpm-jewel/el7/x86_64/ enabled=1 gpgcheck=1 type=rpm-md gpgkey=https://mirrors.aliyun.com/ceph/keys/release.asc [Ceph-noarch] name=Ceph noarch packages baseurl=https://mirrors.aliyun.com/ceph/rpm-jewel/el7/noarch/ enabled=1 gpgcheck=1 type=rpm-md gpgkey=https://mirrors.aliyun.com/ceph/keys/release.asc [ceph-source] name=Ceph source packages baseurl=https://mirrors.aliyun.com/ceph/rpm-jewel/el7/SRPMS/ enabled=1 gpgcheck=1 type=rpm-md gpgkey=https://mirrors.aliyun.com/ceph/keys/release.asc EOF
## 配置免密鑰(略)
提示:如果使用普通用戶進行安裝,請授予用戶相關權限,如下:
a. 將 yangsheng 用戶加入到sudo權限(yangsheng ALL=(ALL) NOPASSWD: ALL)
b. 將 /etc/sudoers 中的 “Defaults requiretty” 注釋
2.2 開始安裝
## 安裝部署工具(在 192.168.58.128 執行如下操作)
yum makecache yum -y install ceph-deploy ceph-deploy --version 1.5.39
## 初始化monitor
mkdir ceph-cluster && cd ceph-cluster ceph-deploy new ceph-node01 ceph-node02 ceph-node03
根據自己的IP配置向ceph.conf中添加public_network,並稍微增大mon之間時差允許范圍(默認為0.05s,現改為2s):
# change default replica 3 to 2 osd pool default size = 2 public network = 192.168.58.0/24 cluster network = 192.168.58.0/24
## 安裝 ceph
ceph-deploy install ceph-node01 ceph-node02 ceph-node03
## 開始部署monitor
ceph-deploy mon create-initial [root@ceph-node01 ceph]# ls ceph.bootstrap-mds.keyring ceph.bootstrap-osd.keyring ceph.client.admin.keyring ceph-deploy-ceph.log rbdmap ceph.bootstrap-mgr.keyring ceph.bootstrap-rgw.keyring ceph.conf ceph.mon.keyring
查看集群狀態
[root@ceph-node01 ceph]# ceph -s
cluster b5108a6c-7e3d-4295-88fa-88dc825be3ba
health HEALTH_ERR
no osds
monmap e1: 3 mons at {ceph-node01=192.168.58.128:6789/0,ceph-node02=192.168.58.129:6789/0,ceph-node03=192.168.58.130:6789/0}
election epoch 6, quorum 0,1,2 ceph-node01,ceph-node02,ceph-node03
osdmap e1: 0 osds: 0 up, 0 in
flags sortbitwise,require_jewel_osds
pgmap v2: 64 pgs, 1 pools, 0 bytes data, 0 objects
0 kB used, 0 kB / 0 kB avail
64 creating
提示:Monitor創建成功后,檢查集群的狀態,此時集群狀態並不處於健康狀態。
## 開始部署OSD
### 列出節點所有磁盤信息 ceph-deploy disk list ceph-node01 ceph-node02 ceph-node03 ### 清除磁盤分區和內容 ceph-deploy disk zap ceph-node01:sdb ceph-node02:sdb ceph-node03:sdb ### 分區格式化並激活 ceph-deploy osd create ceph-node01:sdb ceph-node02:sdb ceph-node03:sdb ceph-deploy osd activate ceph-node01:sdb ceph-node02:sdb ceph-node03:sdb
此時,再次查看集群狀態
[root@ceph-node01 ceph-cluster]# ceph -s
cluster 86fb7c8b-9ad1-4eaf-a24c-0d2d9f36ab29
health HEALTH_OK
monmap e2: 3 mons at {ceph-node01=192.168.58.128:6789/0,ceph-node02=192.168.58.129:6789/0,ceph-node03=192.168.58.130:6789/0}
election epoch 6, quorum 0,1,2 ceph-node01,ceph-node02,ceph-node03
osdmap e15: 3 osds: 3 up, 3 in
flags sortbitwise,require_jewel_osds
pgmap v32: 64 pgs, 1 pools, 0 bytes data, 0 objects
100 MB used, 45946 MB / 46046 MB avail
64 active+clean
2.3 清理環境
如果之前部署失敗了,不必刪除ceph客戶端,或者重新搭建虛擬機,只需要在每個節點上執行如下指令即可將環境清理至剛安裝完ceph客戶端時的狀態!強烈建議在舊集群上搭建之前清理干凈環境,否則會發生各種異常情況。
sudo ps aux|grep ceph | grep -v "grep"| awk '{print $2}'|xargs kill -9 sudo ps -ef|grep ceph sudo umount /var/lib/ceph/osd/* sudo rm -rf /var/lib/ceph/osd/* sudo rm -rf /var/lib/ceph/mon/* sudo rm -rf /var/lib/ceph/mds/* sudo rm -rf /var/lib/ceph/bootstrap-mds/* sudo rm -rf /var/lib/ceph/bootstrap-osd/* sudo rm -rf /var/lib/ceph/bootstrap-rgw/* sudo rm -rf /var/lib/ceph/tmp/* sudo rm -rf /etc/ceph/* sudo rm -rf /var/run/ceph/*
三、配置客戶端
3.1 安裝客戶端
ssh-copy-id 192.168.58.131 ceph-deploy install 192.168.58.131
將Ceph 配置文件復制到 192.168.58.131。
ceph-deploy config push 192.168.58.131
3.2 新建用戶密鑰
客戶機需要 ceph 秘鑰去訪問 ceph 集群。ceph創建了一個默認的用戶client.admin,它有足夠的權限去訪問ceph集群。但是不建議把 client.admin 共享到所有其他的客戶端節點。這里我用分開的秘鑰新建一個用戶 (client.rdb) 去訪問特定的存儲池。
ceph auth get-or-create client.rbd mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=rbd'
為 192.168.58.131 上的 client.rbd 用戶添加秘鑰
ceph auth get-or-create client.rbd | ssh 192.168.58.131 tee /etc/ceph/ceph.client.rbd.keyring
到客戶端(192.168.58.131)檢查集群健康狀態
[root@localhost ~]# cat /etc/ceph/ceph.client.rbd.keyring >> /etc/ceph/keyring [root@localhost ~]# ceph -s --name client.rbd cluster 86fb7c8b-9ad1-4eaf-a24c-0d2d9f36ab29 health HEALTH_OK monmap e2: 3 mons at {ceph-node01=192.168.58.128:6789/0,ceph-node02=192.168.58.129:6789/0,ceph-node03=192.168.58.130:6789/0} election epoch 6, quorum 0,1,2 ceph-node01,ceph-node02,ceph-node03 osdmap e15: 3 osds: 3 up, 3 in flags sortbitwise,require_jewel_osds pgmap v32: 64 pgs, 1 pools, 0 bytes data, 0 objects 100 MB used, 45946 MB / 46046 MB avail 64 active+clean
3.3 創建塊設備
rbd create foo --size 4096 --name client.rbd # 創建一個 4096MB 大小的RADOS塊設備 rbd create rbd01 --size 10240 --name client.rbd # 創建一個 10240MB 大小的RADOS塊設備
映射塊設備
[root@localhost ceph]# rbd create rbd02 --size 10240 --image-feature layering --name client.rbd [root@localhost ceph]# rbd map --image rbd02 --name client.rbd /dev/rdb02 /dev/rbd0
提示:在 映射塊設備的時候,發生了如下錯誤。
[root@localhost ceph]# rbd map --image rbd01 --name client.rbd /dev/rdb01 rbd: sysfs write failed RBD image feature set mismatch. You can disable features unsupported by the kernel with "rbd feature disable". In some cases useful info is found in syslog - try "dmesg | tail" or so. rbd: map failed: (6) No such device or address
解決該辦法有多種方式,分別如下所示:
1. 在創建的過程中加入如下參數 "--image-feature layering" 也解決該問題。
2. 手動disable 掉相關參數,如下所示:
rbd feature disable foo exclusive-lock, object-map, fast-diff, deep-flatten
3. 在每個 ceph 節點的配置文件中,加入該配置項 "rbd_default_features = 1"。
3.4 檢查被映射的塊設備
[root@localhost ceph]# rbd showmapped --name client.rbd id pool image snap device 0 rbd rbd02 - /dev/rbd0
創建並掛載該設備
fdisk -l /dev/rbd0 mkfs.xfs /dev/rbd0 mkdir /mnt/ceph-disk1 mount /dev/rbd1 /mnt/ceph-disk1
驗證
[root@localhost ceph]# df -h /mnt/ceph-disk1/ 文件系統 容量 已用 可用 已用% 掛載點 /dev/rbd0 10G 33M 10G 1% /mnt/ceph-disk1
一個 ceph 塊設備就創建完成。