歡迎大家前往騰訊雲+社群,獲取更多騰訊海量技術實踐乾貨哦~
本文為長篇連續劇,將分多個篇幅發表,主要介紹了從動手部署環境到後期運營故障處理過程中常見的問題,內容由淺入深,是居家旅行運維Ceph的必備良藥。
Q1. 環境預準備
絕大多數MON建立的失敗都是由於防火牆沒有關導致的,亦或是SeLinux沒關閉導致的。一定一定一定要關閉每個每個每個節點的防火牆(執行一次就好,沒安裝報錯就忽視):
CentOS
sed -i 's/SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
setenforce 0
systemctl stop firewalld
systemctl disable firewalld
# iptables -F
service iptables stop
複製程式碼
Q2. 清理環境
MON部署不上的第二大問題就是在舊的節點部署MON,或者在這個節點部署MON失敗了,然後重新new
再mon create-initial
,請檢視要部署MON的節點上的/var/lib/ceph/mon/
目錄下是否為空,如果不為空,說明已經在這個目錄部署過MON,再次部署會檢測子目錄下的done
檔案,由於有了這個檔案,就不會再建立新的MON資料庫,並且不會覆蓋之,導致了部署時的各種異常,這裡就不贅述了,直接給出萬能清理大法:
對於任何需要新部署MON的節點,請到這個節點下執行如下指令,確保環境已經清理乾淨:
ps aux|grep ceph |awk '{print $2}'|xargs kill -9
ps -ef|grep ceph
#確保此時所有ceph程式都已經關閉!!!如果沒有關閉,多執行幾次。
rm -rf /var/lib/ceph/mon/*
rm -rf /var/lib/ceph/bootstrap-mds/*
rm -rf /var/lib/ceph/bootstrap-osd/*
rm -rf /var/lib/ceph/bootstrap-rgw/*
rm -rf /etc/ceph/*
rm -rf /var/run/ceph/*
複製程式碼
請直接複製貼上,遇到過好些個自己打錯打漏刪了目錄的。
Q3. 部署前最後的確認
這裡介紹的都是個案,不過還是需要提一下:
- 確保每個節點的
hostname
都設定正確,並且新增至/etc/hosts
檔案中,然後同步到所有節點下。克隆出來的虛擬機器或者批量建的虛擬機器有可能發生此情形。 - 確保以下目錄在各個節點都存在:
/var/lib/ceph/
/var/lib/ceph/mon/
/var/lib/ceph/osd/
/etc/ceph/
/var/run/ceph/
- 上面的目錄,如果Ceph版本大於等於
jewel
,請確認許可權均為ceph:ceph
,如果是root:root
,請自行chown
。
Q4. 安裝Ceph
官網指導方法是使用ceph-deploy install nodeX
,但是因為是國外的源,速度慢得令人髮指,所以我們換到阿里的源,並且使用yum install
的方式安裝,沒差啦其實,這樣反而還快點,畢竟多個節點一起裝。
很多安裝失敗的都是因為沒有新增epel源請在每個儲存節點都執行以下指令,來安裝Ceph:
yum clean all
rm -rf /etc/yum.repos.d/*.repo
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
sed -i '/aliyuncs/d' /etc/yum.repos.d/CentOS-Base.repo
sed -i '/aliyuncs/d' /etc/yum.repos.d/epel.repo
sed -i 's/$releasever/7.2.1511/g' /etc/yum.repos.d/CentOS-Base.repo
echo "
[ceph]
name=ceph
baseurl=http://mirrors.aliyun.com/ceph/rpm-hammer/el7/x86_64/
gpgcheck=0
[ceph-noarch]
name=cephnoarch
baseurl=http://mirrors.aliyun.com/ceph/rpm-hammer/el7/noarch/
gpgcheck=0
" > /etc/yum.repos.d/ceph.repo
yum install ceph ceph-radosgw -y
複製程式碼
這裡是安裝的hammer
版本的Ceph,如果需要安裝jewel
版本的,請執行:
sed -i 's/hammer/jewel/' /etc/yum.repos.d/ceph.repo
yum install ceph ceph-radosgw -y
複製程式碼
如果安裝了jewel
版本的Ceph,想要換回hammer
版本的Ceph,可以執行下面的指令:
解除安裝Ceph客戶端
rpm -qa |grep `ceph -v |awk '{print $3}'` |xargs rpm -e --nodeps
複製程式碼
更改ceph.repo裡面的Ceph版本
sed -i 's/jewel/hammer/' /etc/yum.repos.d/ceph.repo
yum install ceph ceph-radosgw -y
複製程式碼
Q5. ceph-deploy
這裡我要開啟話嘮模式:
① Ceph-deploy 是什麼?
Ceph-deploy是Ceph官方給出的用於部署Ceph的一個工具,這個工具幾乎全部是Python寫的指令碼,其程式碼位於/usr/lib/python2.7/site-packages/ceph_deploy
目錄下(1.5.36
版本)。最主要的功能就是用幾個簡單的指令部署好一個叢集,而不是手動部署操碎了心,敲錯一個地方就可能失敗。所以對於新人來說,或者說以我的經驗,接觸Ceph少於一個月的,又或者說,叢集規模不上PB的,都沒有必要手動部署,Ceph-deploy完全足夠了。
② Ceph-deploy怎麼裝?
這個包在ceph的源裡面:
yum install ceph-deploy -y
複製程式碼
③Ceph-deploy裝在哪?
既然Ceph-deploy只是個部署Ceph的指令碼工具而已,那麼這個工具隨便裝在哪個節點都可以,並不需要單獨為了裝這個工具再搞個節點,我一般習慣放在第一個節點,以後好找部署目錄。
④Ceph-deploy怎麼用?
詳細的指令暫時不介紹,下面會有,在安裝好後,需要在這個節點新建一個目錄,用作部署目錄
,這裡是強烈建議建一個單獨的目錄的,比如我習慣在叢集的第一個節點下建一個/root/cluster
目錄,為了以後好找。Ceph-deploy的所有的指令都需要在這個目錄下執行。包括new,mon,osd
等等一切ceph-deploy的指令都需要在這個部署目錄下執行!最後一遍,所有的ceph-deploy
的指令都要在部署目錄下執行!否則就會報下面的錯:
[ceph_deploy][ERROR ] ConfigError: Cannot load config: [Errno 2] No such file or directory: 'ceph.conf'; has ceph-deploy new been run in this directory?
複製程式碼
⑤ Ceph-deploy怎麼部署叢集?
我們暫且把部署目錄所在的節點叫做部署節點。Ceph-deploy通過SSH到各個節點,然後再在各個節點執行本機的Ceph指令來建立MON或者OSD等。所以在部署之前,你需要從部署節點ssh-copy-id
到各個叢集節點,使其可以免祕鑰登陸。
⑥Ceph-deploy部署的日誌在哪裡?
就在部署目錄下面的ceph-deploy-ceph.log
檔案,部署過程中產生的所有的日誌都會儲存在裡面,比如你大半年前敲的建立OSD的指令。在哪個目錄下執行ceph-deploy指令,就會在這個目錄下生成log,如果你跑到別的目錄下執行,就會在執行目錄裡生成log再記下第四點的錯。當然,這個LOG最有用的地方還是裡面記錄的部署指令,你可以通過cat ceph-deploy-ceph.log |grep "Running command"
檢視到建立一個叢集所需的所有指令,這對你手動建立叢集或者建立祕鑰等等等等有著很大的幫助!!!
⑦ Ceph-deploy版本
寫這段時的最新的版本號為1.5.36
,下載連結為ceph-deploy-1.5.36-0.noarch.rpm, 之前的1.5.35
裡面有點bug在這個版本被修復了,如果使用1.5.25
部署遇到了問題,可以更新至這個版本,會繞過一些坑。更新到1.5.36
之後,腰也不酸了,退了不疼了,Ceph也能部署上了。
Q6. ceph-deploy new 做了什麼
進入部署目錄,執行ceph-deploy new node1 node2 node3
,會生成兩個檔案(第三個是ceph-deploy-ceph.log
,忽視之):
[root@blog cluster]# ls
ceph.conf ceph-deploy-ceph.log ceph.mon.keyring
複製程式碼
new
後面跟的是你即將部署MON的節點的hostname
,推薦三個就夠了,需要是奇數個MON節點。不要因為只有兩個節點就搞兩個MON,兩個節點請用一個MON,因為兩個MON掛掉一個,叢集也就掛了,和一個MON掛掉一個效果是一樣的。生成的ceph.conf
預設情況下長成這樣:
[root@blog cluster]# cat ceph.conf
[global]
fsid = 13b5d863-75aa-479d-84ba-9e5edd881ec9
mon_initial_members = blog
mon_host = 1.2.3.4
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx
複製程式碼
會呼叫uuidgen
生成一個fsid
,用作叢集的唯一ID,再將new
後面的主機加入到mon_initial_members
和mon_host
裡面,剩下的三行大家都是一樣的,預設開啟CephX認證。下面有一節會專門介紹這個,需要注意的是,部署的時候,千萬不要動這三行 下面會有一節介紹之。還有一個檔案ceph.mon.keyring
:
[root@blog cluster]# cat ceph.mon.keyring
[mon.]
key = AQB1yWRYAAAAABAAhMoAcadfCdy9VtAaY79+Sw==
caps mon = allow *
複製程式碼
除了key
的內容不一樣,剩下的都會是一樣的。因為是開啟了CephX認證了,所以MON直接的通訊是需要一個祕鑰的,key
的內容就是祕鑰。是不是對Ceph裡面的明文認證感到吃驚,有總比沒有強。如果,你再次執行new
,會生成新的ceph.conf
和新的ceph.mon.keyring
,並將之前的這兩個檔案給覆蓋掉,新舊檔案唯一不同的就是fsid
和key
的內容,但是對Ceph來說,這就是兩個叢集了。這裡說一下我個人非常非常非常反感的一個問題,有的朋友喜歡在/etc/ceph/
目錄下面執行ceph-deploy的命令,這麼做和在部署目錄下面做一般是沒有差別的,因為這兩個目錄下面都有ceph.conf
和ceph.client.admin.keyring
,但是我還是強烈推薦建立獨立的部署目錄,因為/etc/ceph
目錄是Ceph節點的執行目錄,為了體現各自的功能性,也為了安全性,請不要在**/etc/ceph**
目錄下部署叢集!!!
Q7. 為ceph-deploy新增引數
Ceph-deploy的log還是很有看頭的,檢視ceph-deploy new blog
(blog是我的一臺主機)的log:
[root@blog cluster]# ceph-deploy new blog
[ceph_deploy.conf][DEBUG ] found configuration file at: /root/.cephdeploy.conf
[ceph_deploy.cli][INFO ] Invoked (1.5.36): /usr/bin/ceph-deploy new blog
[ceph_deploy.cli][INFO ] ceph-deploy options:
[ceph_deploy.cli][INFO ] username : None
[ceph_deploy.cli][INFO ] func : <function new at 0x288e2a8>
[ceph_deploy.cli][INFO ] verbose : False
[ceph_deploy.cli][INFO ] overwrite_conf : False
[ceph_deploy.cli][INFO ] quiet : False
[ceph_deploy.cli][INFO ] cd_conf : <ceph_deploy.conf.cephdeploy.Conf instance at 0x28eccf8>
[ceph_deploy.cli][INFO ] cluster : ceph
[ceph_deploy.cli][INFO ] ssh_copykey : True
[ceph_deploy.cli][INFO ] mon : ['blog']
[ceph_deploy.cli][INFO ] public_network : None
[ceph_deploy.cli][INFO ] ceph_conf : None
[ceph_deploy.cli][INFO ] cluster_network : None
[ceph_deploy.cli][INFO ] default_release : False
[ceph_deploy.cli][INFO ] fsid : None
[ceph_deploy.new][DEBUG ] Creating new cluster named ceph
複製程式碼
可以看到有很多的引數被列出來了,比如:mon : ['blog']
,也有很多引數是False或者None, 這些引數能否被設定呢? 因為這裡我們可以看到有fsid : None
這個引數,難道叢集的fsid
可以被指定嗎?抱著這些疑惑,我就去看完了ceph-deploy的所有程式碼,答案是:可以設定。所有上面的引數都可以使用引數的形式進行設定,只需要在前面加上兩個--
,比如對於fsid
可以執行:
ceph-deploy new blog --fsid xx-xx-xx-xxxx
複製程式碼
如果想要檢視每個執行可指定的引數,可以-h
:
[root@blog cluster]# ceph-deploy new -h
usage: ceph-deploy new [-h] [--no-ssh-copykey] [--fsid FSID]
[--cluster-network CLUSTER_NETWORK]
[--public-network PUBLIC_NETWORK]
MON [MON ...]
...
optional arguments:
-h, --help show this help message and exit
--no-ssh-copykey do not attempt to copy SSH keys
--fsid FSID provide an alternate FSID for ceph.conf generation
--cluster-network CLUSTER_NETWORK
specify the (internal) cluster network
--public-network PUBLIC_NETWORK
specify the public network for a cluster
複製程式碼
這裡就可以看到可以指定--cluster-network
,--public-network
,等等,如果optional arguments
裡面沒有介紹這個引數,可以直接使用--xxarg
的方式指定,比如--overwrite-conf
,--verbose
等等,能不能設定這些引數,自己動手試一下就知道了。需要注意的是,引數的位置根據指令而異,比如--overwrite-conf
引數是跟在ceph-deploy
後面的,而--public-network
是跟在new
後面的:
ceph-deploy --overwrite-conf --verbose new blog --fsid a-a-a-a
[root@blog cluster]# cat ceph.conf |grep fsid
fsid = a-a-a-a
複製程式碼
Q8. Public VS Cluster
如果非要在剛剛生成的ceph.conf裡面新增什麼的話,那麼可能就要加public_network或者cluster_network了。那麼這兩個配置項有什麼用呢?這裡簡單得介紹下Ceph的Public(外網或者叫公網或者前端網)和Cluster(內網或者叫叢集網或者叫後端網)這兩個網路,在Ceph中,存在以下三種主要的網路通訊關係:
- client-> mon =>public : 也就是客戶端獲取叢集狀態,或者叫客戶端與MON通訊走的網路,是走的外網。
- client-> osd => public : 也就是客戶端向OSD直接寫入資料走的也是外網。
- osd<-> osd => cluster :也就是OSD之間的資料克隆,恢復走的是內網,客戶端寫第一份資料時通過外網寫,對於三副本剩下的兩個副本OSD之間通過內網完成資料複製。當OSD掛掉之後產生的recover,走的也是內網。
通常,我們會將外網配置為千兆網,而內網配置成萬兆網,這是有一定原因的:
- 客戶端可能由成百上千的計算節點組成,外網配成萬兆成本太高。
- 儲存節點一般只有幾個到幾十個節點,配置了萬兆內網可以大大加快故障恢復速度,而且剩餘的兩副本寫速度會大大加快,萬兆網的價效比極高。舉個例子,叢集壞掉一個OSD千兆需要一小時,那麼萬兆網只需要五六分鐘,一定程度上增加了叢集的安全性。
借用官網的這張圖來說明叢集的網路走勢:再假設你的節點有兩個網段172.23.0.1和3.3.4.1,還記得我們上一節ceph-deploy new
的時候是可以指定public_network
和cluster_network
的嗎!如果不指定這兩個引數,那麼ceph-deploy怎麼知道用哪個IP作為這個節點的mon_host
的IP呢,其實他是隨便選的,如果它選了172網段但是你想使用3.3網段作為這個節點的mon_host
的IP,那麼只需要指定--public-network 172.23.0.0/24
就可以了,其中的/24
就相當於一個掩碼,表示前面的IP的前24位,也就是172.23.0.XXX
,只要你的主機上有一個處於這個範圍內的IP,那麼就會選擇這個IP作為公網IP。類似的,/16
表示範圍:172.23.XXX.XXX
。 如果想指定內網IP,那麼只要指定--cluster-network 3.3.4.1/24
就可以了。
**一般情況下,會在new生成的ceph.conf檔案里加入public_network配置項以指定公網IP。當然你的MON主機上需要有至少一個IP在公網範圍內。**除了在生成的ceph.conf
檔案中加入公網IP的方式,我們還可以使用引數的方式來指定公網IP:
[root@ceph-1 cluster]# ceph-deploy new ceph-1 --public-network 172.23.0.0/24
[ceph_deploy.cli][INFO ] Invoked (1.5.36): /usr/bin/ceph-deploy new ceph-1 --public-network 172.23.0.0/24
[ceph_deploy.cli][INFO ] ceph-deploy options:
...
[ceph_deploy.cli][INFO ] public_network : 172.23.0.0/24
...
[ceph-1][DEBUG ] IP addresses found: [u'172.23.0.101', u'10.0.2.15']
[ceph_deploy.new][DEBUG ] Resolving host ceph-1
[ceph_deploy.new][DEBUG ] Monitor ceph-1 at 172.23.0.101
[ceph_deploy.new][DEBUG ] Monitor initial members are ['ceph-1']
[ceph_deploy.new][DEBUG ] Monitor addrs are [u'172.23.0.101']
[ceph_deploy.new][DEBUG ] Writing monitor keyring to ceph.mon.keyring...
[ceph_deploy.new][DEBUG ] Writing initial config to ceph.conf...
[root@ceph-1 cluster]# cat ceph.conf
[global]
fsid = d2a2bccc-b215-4f3e-922b-cf6019068e76
public_network = 172.23.0.0/24
mon_initial_members = ceph-1
mon_host = 172.23.0.101
auth_cluster_required = cephx
auth_service_required = cephx
auth_client_required = cephx
複製程式碼
檢視部署log可以發現引數配置已經生效,而這個節點有兩個IP,public_nwtwork
這個引數限定了公網IP的搜尋範圍,生成的ceph.conf檔案內也包含了public_network
這個引數。
Q9. 引數是下劃線還是空格分隔
這裡只是簡單的提一下這個小困惑,對於以下的兩個引數書寫方式,哪種會有問題呢:
public_network = 172.23.0.1/24
public network = 172.23.0.1/24
osd_journal_size = 128
osd journal size = 128
複製程式碼
這兩種引數的書寫方式其實都是正確的,說到底是因為底層呼叫的是Python的argparse
模組。這兩種方式都是等效的,所以不需要擔心。
Q10. ceph-deploy mon create-initial如何一次性通過
這一步坑哭了多少迫切加入Ceph世界的新人,看到的最多的就是5s,10s,10s, 15s,20s。。。然後報了錯。再執行,再報錯。所以這裡給出以下的預檢清單,如果被報錯失敗所煩惱,請認真執行各個子項,尤其是失敗後要執行清理環境:
- 請確保所有節點都安裝了Ceph。
- 請確保所有節點的防火牆等都關閉了。參考環境預準備一節
- 請前往各個MON節點清理乾淨,不論你是否相信這個節點是乾淨的。參考清理環境一節。
- 請確保各個MON節點下存在以下目錄,並且對於Jewel版本及之後的請確保目錄許可權為
ceph:ceph
。參考部署前最後的確認一節。 - 請在
ceph-deploy new
生成的ceph.conf
內新增public_network
配置項,參考Public VS Cluster一節。
這些總結來之不易,我幫過上百個人解決過部署問題和叢集故障。我相信在認真確認過之後是肯定可以通過的(反正前三點如果有問題一般是不會建好MON的,為什麼不認真確認下呢),我遇到過絕大多數都是因為防火牆沒關,或者手動刪除了一些目錄,或者沒有修改許可權導致的問題。
相對來說,新環境只要關了防火牆就可以一次性通過,舊環境或者失敗的環境只要清理環境就可以通過了。
Q11. mon create-initial 做了什麼
簡單介紹下流程:
-
ceph-deploy讀取配置檔案中的
mon_initial_members 複製程式碼
的各個主機,然後依次SSH前往各個主機:
- 將部署目錄下的ceph.conf推送到新節點的
/etc/ceph/
目錄下。 - 建立
/var/lib/ceph/mon/$cluster-$hostname/
目錄。 - 檢查MON目錄下是否有
done
檔案,如果有則直接跳到第6步。 - 將
ceph.mon.keyring
拷貝到新節點,並利用該祕鑰在MON目錄下建立MON資料庫。 - 在MON目錄下建立done檔案,防止重新建立MON。
- 啟動MON程式。
- 檢視
/var/run/ceph/$cluster-mon.$hostname.asok
SOCKET檔案,這個是由MON程式啟動後生成的,輸出MON狀態。
- 將部署目錄下的ceph.conf推送到新節點的
-
在所有的MON都建立好後,再次前往各個主機,檢視所有主機是否執行並且到達法定人群(quorum)。如果有沒到到的,直接結束報錯。如果都到達了,執行下一步。
-
呼叫
auth get-or-create 複製程式碼
方法建立(如果不存在)或者拉取(已經存在)MON節點上的以下幾個keyring到
部署目錄
中:
ceph.bootstrap-mds.keyring
ceph.bootstrap-osd.keyring
ceph.bootstrap-rgw.keyring
ceph.client.admin.keyring
-
指令結束。
Q12. mon create-initial 為什麼會失敗
我不喜歡講怎麼做,我願意花很大的篇幅介紹為什麼會造成各種各樣的問題,如果知道了原因,你自然知道該怎麼做,所以才會理解Ceph,而不是機械的去敲指令。
綜合上面的所有小節,我來總結下這一步失敗的基本上所有可能的原因:
- 所謂MON的quorum,相當於多個MON形成的一個群體,它們之間需要通過網路傳送資料包來通訊達成某種協議,如果開啟了防火牆,會阻斷資料交流。所以不能構成群體,一直等待(5s->10s->10s->15s->20s)其他MON的資料包,既然被阻斷了這樣的等待是沒有意義的,等了30s還沒有正常,就可以直接
ctrl+z
去檢查了。 - 我在配置檔案裡面新增了
pubilc_network
,但是有個主機的所有IP都不在公網IP段內,那麼這個MON是建不好的,因為沒有IP用作MON使用,public_network
相當於一個過濾器。 - 搭好了一臺虛擬機器後,直接克隆了兩臺,沒有修改主機名,導致socket檔案路徑名識別錯誤,報了異常,不過這很少發生。
- 如果在舊的MON節點上再次部署新的MON,再又沒有清理環境,之前的MON資料庫會保留著
done
檔案,MON資料庫裡面還是記錄著之前fsid,keyring等等,和新叢集是兩套完全不同的,所以這個節點的MON自然到達不了MON群體。 - 即使你單單刪除了
/var/lib/ceph/mon
下的東西,而沒有清理那些keyring,也有可能會因為收集了舊叢集的祕鑰而發生稀奇古怪的問題。 - 對於Jewel,你一不小心刪除了
/var/lib/ceph/mon
目錄,或者其他的OSD目錄或者/var/run/ceph
目錄,然後又重建了目錄,依然部署不上,是因為Jewel的所有Ceph指定都是執行在ceph:ceph
使用者下的,自然不能在root許可權目錄下建立任何檔案,修改許可權即可。 - Ceph生成MON資料庫是依照主機的
hostname
來命名至目錄/var/lib/ceph/mon/${cluster}-${hostname}
的,而檢測SOCKET檔案則是用ceph.conf
裡面的mon_initial_members
裡面的名字來檢測的 ,如果mon_initial_members
裡面的名字和真是的主機名不一致,就會報錯。
一旦你執行了ceph-deploy mon create-initial
指令,並且失敗了,有極大的可能性已經在某些節點建立好了MON的資料庫,再次執行可能會因為舊的環境導致再次失敗,所以如果失敗了,執行一下第二節中的清理環境
即可。清理完畢後,再執行ceph-deploy mon create-initial
。
相關閱讀
此文已由作者授權騰訊雲+社群釋出,更多原文請點選
搜尋關注公眾號「雲加社群」,第一時間獲取技術乾貨,關注後回覆1024 送你一份技術課程大禮包!
海量技術實踐經驗,盡在雲加社群!