Ceph 和防火牆的故事

weixin_34320159發表於2018-08-31

轉自: http://www.xuxiaopang.com/2016/10/31/exp-turn-on-firewalld-of-one-node/
實驗目的
前段時間,有一個儲存節點的系統盤進行了重灌,按照正常流程:重灌系統->配置系統->部署ceph->重建journal->OSD上線,很快就可以恢復了,可是當時這個節點的OSD上線後,導致前臺的VM批量不能開機,緊急處理方法是臨時先將這個節點的OSD下線,VM就能正常開機了,後來思考了半天意識到可能是防火牆沒有關導致的,並且這個問題的現象是可以復現的,於是就有了下面的實驗,目的是探討下一個節點的防火牆沒有關閉,對整個ceph叢集有什麼樣的影響。

實驗過程
這裡完全模擬上述環境進行搭建了一個類似的ceph環境:

CentOS 7.1511 + Hammer 0.94.7。
三個主機ceph-1,ceph-2,ceph-3,每臺上面部署一個MON和一個OSD。
建立三個pool:size-1,size-2,size-3,各有1,2,3個副本。
刪除ceph-2這個節點上的MON,解除安裝OSD,開始實驗。

[root@ceph-1 cluster]# ceph -s
    cluster f1136238-80d6-4c8e-95be-787fba2c2624
     health HEALTH_WARN

            1/3 in osds are down
            1 mons down, quorum 0,2 ceph-1,ceph-3
     monmap e1: 3 mons at {ceph-1=172.23.0.101:6789/0,ceph-2=172.23.0.102:6789/0,ceph-3=172.23.0.103:6789/0}
            election epoch 20, quorum 0,2 ceph-1,ceph-3
     osdmap e31: 3 osds: 2 up, 3 in; 44 remapped pgs
      pgmap v49: 256 pgs, 4 pools, 0 bytes data, 0 objects
            74420 kB used, 4083 GB / 4083 GB avail
                 128 active+undersized+degraded
                  62 active+clean
                  44 active+remapped
                  22 stale+active+clean

開啟ceph-2的防火牆,重灌ceph-2這個節點上的MON和OSD,注意重灌MON我採用的是mon create-initial,重灌OSD我採用的是直接掛載啟動:

[root@ceph-2 mon]# systemctl start  firewalld
[root@ceph-1 cluster]# ceph-deploy mon create-initial
[root@ceph-2 mon]# mount /dev/sdb1  /var/lib/ceph/osd/ceph-1/
[root@ceph-2 mon]# service ceph start osd.1
=== osd.1 === 
create-or-move updated item name 'osd.1' weight 1.99 at location {host=ceph-2,root=default} to crush map
Starting Ceph osd.1 on ceph-2...
Running as unit ceph-osd.1.1477890009.210635415.service.
[root@ceph-2 mon]# ceph -s
    cluster f1136238-80d6-4c8e-95be-787fba2c2624
     health HEALTH_OK
     monmap e1: 3 mons at {ceph-1=172.23.0.101:6789/0,ceph-2=172.23.0.102:6789/0,ceph-3=172.23.0.103:6789/0}
            election epoch 32, quorum 0,1,2 ceph-1,ceph-2,ceph-3
     osdmap e82: 3 osds: 3 up, 3 in
      pgmap v132: 256 pgs, 4 pools, 0 bytes data, 0 objects
            118 MB used, 6125 GB / 6125 GB avail
                 256 active+clean

這時候,叢集是正常的!這是很可怕的事情,注意,osd.1是ceph-2這個節點上的,該節點的防火牆被開啟了。

現在來做幾個有意思的實驗來說明防火牆的影響,我們先找幾個有代表性的PG:

[root@ceph-2 mon]# ceph df
GLOBAL:
    SIZE      AVAIL     RAW USED     %RAW USED 
    6125G     6125G         118M             0 
POOLS:
    NAME       ID     USED     %USED     MAX AVAIL     OBJECTS 
    rbd        0         0         0         2041G           0 
    size-1     1         0         0         6125G           0 
    size-2     2         0         0         3062G           0 
    size-3     3         0         0         2041G           0
Num PG  Pool    OSD
T1  1.1a    size-1  [1]
T2  1.1c    size-1  [2]
2.3 size-2  [2,0]
T3  2.5 size-2  [2,1]
T4  2.25    size-2  [1,0]
3.1 size-3  [1,0,2]

T1: 首先,向PG 1.1a寫入資料,分為在ceph-2節點執行寫入指令,和在其他節點執行寫入指令:

-------在ceph-2寫入,很快返回,寫入成功。

[root@ceph-2 mon]# ceph osd map size-1 file
osdmap e173 pool 'size-1' (1) object 'file' -> pg 1.2e6fb49a (1.1a) -> up ([1], p1) acting ([1], p1)
[root@ceph-2 mon]# rados -p size-1 put file /etc/ceph/ceph.conf 
[root@ceph-2 mon]# 

-------在ceph-1寫入,指令卡死,寫入失敗。

[root@ceph-1 cluster]# rados -p size-1 put file /etc/ceph/ceph.conf
2016-10-31 01:31:10.903053 7fa436afb700  0 -- 172.23.0.101:0/3070569903 >> 172.23.0.102:6800/6965 pipe(0x2f9a010 sd=5 :0 s=1 pgs=0 cs=0 l=1 c=0x2f92a80).fault
^Z
[1]+  已停止               rados -p size-1 put file /etc/ceph/ceph.conf

可見,在ceph-2節點上,可以正常寫入,因為這不需要通過防火牆,而在ceph-1寫入時,客戶端需要連線到ceph-2的osd.1,此時防火牆開啟,請求被擋住了,寫入失敗。

T2: 現在向PG 1.1c寫入資料,同樣分為在ceph-2內外兩種情況:

-------在ceph-2寫入,很快返回,寫入成功。

[root@ceph-2 mon]# ceph osd map size-1 file-2
osdmap e201 pool 'size-1' (1) object 'file-2' -> pg 1.fb2f2dc (1.1c) -> up ([2], p2) acting ([2], p2)
[root@ceph-2 mon]# rados -p size-1 put file-2 /etc/ceph/ceph.conf 
[root@ceph-2 mon]#

-------在ceph-1寫入,很快返回,寫入成功。

[root@ceph-1 cluster]# rados -p size-1 put file-2 /etc/ceph/ceph.conf
[root@ceph-1 cluster]#

因為PG 1.1c位於osd.2即ceph-3這個節點上,所以從ceph-2這個節點寫入沒有問題,同樣從ceph-1節點寫入也沒有問題。

很容易猜測到,向PG 2.3寫入都正常,實驗現象也一致。

T3: 繼續向PG 2.5寫入資料:

--------在ceph-2寫入,很快返回,寫入成功

[root@ceph-2 mon]# ceph osd map size-2 file-1
osdmap e229 pool 'size-2' (2) object 'file-1' -> pg 2.9c8cdcc5 (2.5) -> up ([2,1], p2) acting ([2,1], p2)
[root@ceph-2 mon]# rados -p size-2 put file-1 /etc/ceph/ceph.conf 
[root@ceph-2 mon]#

-------在ceph-1寫入,居然,寫入成功了

[root@ceph-1 cluster]# rados -p size-2 put file-1 /etc/ceph/ceph.conf
[root@ceph-1 cluster]#

很容易理解,在ceph-2中寫入成功。但是在ceph-1中寫入也成功了,這裡我的理解是這樣的,首先客戶端向osd.2寫入主副本,然後osd.2向osd.1進行從副本的拷貝,但是這裡的拷貝應該是失敗的,因為osd.1的防火牆被開啟了,但是這裡是成功的,是因為osd.1在上線時,建立了和osd.2的peer關係,從osd.1->osd.2建立了socket通訊關係,那麼這條通訊線路應該形如osd.1<->osd.2,所以,osd.2就可以向osd.1進行副本拷貝。

T4 : 綜合T1的外部寫入失敗,和T3的外部寫入成功,我找了一個PG,其OSD分佈為[1,0],也就是說,主OSD在osd.1上,實驗結果如下:

[root@ceph-3 ~]# ceph osd map size-2 file-6
osdmap e412 pool 'size-2' (2) object 'file-6' -> pg 2.bc387525 (2.25) -> up ([1,0], p1) acting ([1,0], p1)

------在ceph-2上寫入,很快返回,寫入成功

[root@ceph-2 ~]# rados -p size-2 put file-6 /etc/ceph/ceph.conf 
[root@ceph-2 ~]#

------在ceph-1上寫入,卡死,寫入失敗。

[root@ceph-1 ~]# rados -p size-2 put file-6 /etc/ceph/ceph.conf
2016-10-31 04:51:19.329528 7f20d686b700  0 -- 172.23.0.101:0/3159973327 >> 172.23.0.102:6800/3532 pipe(0x7f20cc00c3b0 sd=6 :0 s=1 pgs=0 cs=0 l=1 c=0x7f20cc010650).fault
^Z
[1]+  已停止               rados -p size-2 put file-6 /etc/ceph/ceph.conf
這裡的情況就很容易理解了,因為客戶端從ceph-1節點上寫入資料時,是建立與osd.1的通訊關係,這時候被防火牆擋住,所以寫入失敗。

對於三副本,我們可以按照剛剛四個實驗進行猜測,對於形如[1,0,2]的PG,只要從外部寫入都會是失敗的,因為主OSD:osd.1的防火牆被開啟,無法建立通訊,但是對於形如[0,1,2]的PG,寫入會成功,因為主OSD可以正常通訊,然後osd.1和其他OSD從osd.1的主機內部向外建立通訊關係,使得他們之間的通訊是沒有被防火牆阻礙的。這些猜測已經證實過,沒有問題。

在實驗過程中,檢視ceph -w可以看到如下一段log:


mon.0 [INF] pgmap v846: 256 pgs: 256 active+clean; 1190 bytes data, 133 MB used, 6125 GB / 6125 GB avail
mon.0 [INF] osd.1 172.23.0.102:6800/3532 failed (8 reports from 2 peers after 21.271377 >= grace 20.995909)
mon.0 [INF] osdmap e546: 3 osds: 2 up, 3 in
mon.0 [INF] pgmap v847: 256 pgs: 89 stale+active+clean, 167 active+clean; 1190 bytes data, 133 MB used, 6125 GB / 6125 GB avail
mon.0 [INF] osdmap e547: 3 osds: 2 up, 3 in
mon.0 [INF] pgmap v848: 256 pgs: 89 stale+active+clean, 167 active+clean; 1190 bytes data, 133 MB used, 6125 GB / 6125 GB avail
mon.0 [INF] osd.1 172.23.0.102:6800/3532 boot
mon.0 [INF] osdmap e548: 3 osds: 3 up, 3 in
mon.0 [INF] pgmap v849: 256 pgs: 89 stale+active+clean, 167 active+clean; 1190 bytes data, 133 MB used, 6125 GB / 6125 GB avail
mon.0 [INF] osdmap e549: 3 osds: 3 up, 3 in
mon.0 [INF] pgmap v850: 256 pgs: 89 stale+active+clean, 167 active+clean; 1190 bytes data, 133 MB used, 6125 GB / 6125 GB avail
osd.1 [WRN] map e547 wrongly marked me down
mon.0 [INF] pgmap v851: 256 pgs: 89 stale+active+clean, 167 active+clean; 1190 bytes data, 132 MB used, 6125 GB / 6125 GB avail
mon.0 [INF] pgmap v852: 256 pgs: 256 active+clean; 1190 bytes data, 137 MB used, 6125 GB / 6125 GB avail
有幾個關鍵字:

8 reports from 2 peers after 21.271377 >= grace 20.995909
3 osds: 2 up, 3 in
osd.1 172.23.0.102:6800/3532 boot
map e547 wrongly marked me down
pgmap v852: 256 pgs: 256 active+clean;
也就是說在一些peer關係的OSD報告這個osd.1無法建立peer關係後,也就是osd.0和osd.2從外部向osd.1建立peer關係失敗了,叢集就會主動上報osd.1為down,但是實際上,osd.1並沒有掛掉,因為它無法接受從外部過來的通訊請求,所以它向叢集彙報自己被錯誤的標記為down了,這時候是osd.1自內向外傳送請求,所以不會被堵塞,然後叢集在接收到自UP資訊之後,會再次將該OSD標記為UP,然後就進入了一個死迴圈,如果grace時間被設定較長,那麼很容忽略掉這個OSD的down的過程,而長時間認為這個OSD是UP的,從人為角度來看,UP的OSD寫入資料是沒有問題的,但是實際上,Openstack+Ceph的寫入可以看做都是從外部寫入的,所以對於主OSD的防火牆被開啟的PG,所有請求會被阻塞。再回過頭來看最開始的VM無法開機的情況就可以理解了,同時,關閉那個節點的所有OSD後,主OSD被轉移到其他節點的副OSD上了,寫入就可以成功了。

實驗結論
這個實驗正好驗證了ceph的寫入過程:client-> osd.primary -> osd.secondary,開啟防火牆會阻塞client->osd.primary的寫操作,但是不會阻塞副本間的拷貝操作,我的理解就是osd.primary<->osd.secondary 通訊關係可以從防火牆內部向外部建立,一旦建立就不會受防火牆阻塞,所以儘管osd.seconday防火牆被開啟,也可以正常寫入。

相關文章