理解 OpenStack + Ceph (7): Ceph 的基本操作和常見故障排除方法


本系列文章會深入研究 Ceph 以及 Ceph 和 OpenStack 的集成:

(1)安裝和部署

(2)Ceph RBD 接口和工具

(3)Ceph 物理和邏輯結構

(4)Ceph 的基礎數據結構

(5)Ceph 與 OpenStack 集成的實現

(6)QEMU-KVM 和 Ceph RBD 的 緩存機制總結

(7)Ceph 的基本操作和常見故障排除方法

(8)關於Ceph PGs

 

學以致用,本文將介紹 Ceph 集群的一些基本操作和常見的故障排除方法。

0. 測試環境

  將由 Virtulbox 管理的兩個虛機,分別是 ceph1 和 ceph2,作為 OSD 服務器,其中,ceph1 同時作為 MON 服務器。兩個節點上分別有兩個虛擬磁盤作為 OSD 存儲磁盤,每個大小為 5G;還有一個虛擬磁盤作為 Journal 磁盤,1G,分為兩個區,做為數據盤的日志分區。從 ceph1 上使用 ceph-deploy 工具部署。pool 的 size 設置為 2,min_size 也設置為 2.

  每個機器配置兩個網卡,eth0 是 NAT 模式,使用 DHCP 方式獲取IP,用於虛機訪問外網;eth1 是 host-only 模式,配置靜態IP,用於主機訪問虛機,以及虛機之間的互訪。對Ceph 來說,eth0 用於安裝程序,eth1 用於 public 和 cluster network。

 注意在宿主機上要設置防火牆允許 Virtualbox 訪問外網。我機器上安裝了 Symentac Endpoint Protection,不小心 block 了它的互聯網訪問,然后虛機也就無法連接外網了,我在這里花了不少時間折騰:

1. 修改 OSD CRUSH weight

1.1 問題描述

部署完成后,集群處於 PG Degraded 狀態,經查 ceph health detail,發現 PG 的 acting OSD 只有 [0],而不是兩個。查 osd tree,osd 日志等,看不出明顯問題。

1.2 原因分析

  從文章 http://serverfault.com/questions/680492/after-initial-deployment-ceph-cluster-stays-in-activedegraded-state 受到啟發,我的 Ceph 集群的 OSD 的 weight 都是 0!!

root@ceph1:/etc/ceph# ceph osd tree
# id    weight  type name       up/down reweight
-1      0       root default
-2      0               host ceph1
0       0                       osd.0   up      1
2       0                       osd.2   up      1
-3      0               host ceph2
1       0                       osd.1   up      1
3       0                       osd.3   up      1

  我們從上面 ceph osd tree 的結果里面可以看到這里有兩個weight:weight 和 reweight。這篇文章 有詳細的分析。簡單來說:

  • weight:即 osd crush weight,表示設備(device) 容量的相對值,比如如果1TB對應1.00,那么 500MB 對應 0.50。bucket weight 是所有 item weight 之和,item weight 的變化會影響 bucket weight 的變化,也就是 osd.X 會影響host。 對於 straw bucket,如果 item weight 為0,則 item straw 也為0,當CRUSH 算法在 bucket 選擇 item 時,也就不太可能選中該 item。
  • reweight:取值為0~1。osd reweight 並不會影響 host。當 osd 被踢出集群(out)時,osd weight 被設置0,加入集群時,設置為1。它會參與 CRUSH 創建 PG 的過程。CRUSH在選擇 OSD 時,如果發現 weight 為0,就跳過該 OSD。

因此,問題的症結就在於 osd crush weight 為0。至於為什么會這樣,以及該值對 PG 分配的影響,有待進一步查明。

1.3 解決辦法:修改 osd crush weight

ceph osd crush reweight osd.0 1
ceph osd crush reweight osd.1 1
ceph osd crush reweight osd.2 1
ceph osd crush reweight osd.3 1

修改后,集群就回到了 HEALTH_OK 狀態。

注意:修改 OSD 的 crush weight 會帶來部分 PG 之間的數據移動,這可能會影響集群的性能,因此在生產環境中使用要小心。你可以參考 這篇文章 來看數據移動的情況。

2. 修改 CRUSH tunables(可調參數)

2.1 問題描述

將 osd.1 設置為 out 后,集群並沒有開始做 recovery,部分 PG 保持在 remapped 狀態:

root@ceph1:~# ceph -s
    cluster 5ccdcb2d-961d-4dcb-a9ed-e8034c56cf71
     health HEALTH_WARN 88 pgs stuck unclean
     monmap e2: 1 mons at {ceph1=192.168.56.102:6789/0}, election epoch 1, quorum 0 ceph1
     osdmap e71: 4 osds: 4 up, 3 in
      pgmap v442: 256 pgs, 4 pools, 285 MB data, 8 objects
            690 MB used, 14636 MB / 15326 MB avail
                  88 active+remapped
                 168 active+clean

2.2 原因分析

(1). 查看 ceph health detail

root@ceph1:~# ceph health detail
HEALTH_WARN 88 pgs stuck unclean
pg 1.23 is stuck unclean for 337.342290, current state active+remapped, last acting [0,1]
pg 0.1f is stuck unclean for 336.838743, current state active+remapped, last acting [0,1]
pg 1.1f is stuck unclean for 337.355851, current state active+remapped, last acting [0,1]

Remapped(重映射):當 PG 的 acting set 變化后,數據將會從舊 acting set 遷移到新 action set。新主 OSD 需要過一段時間后才能提供服務。因此,它會讓老的主 OSD 繼續提供服務,直到 PG 遷移完成。數據遷移完成后,PG map 將使用新 acting set 中的主OSD。

以 PG 為例,比較在 osd.1 out 前后的 PG map:

state           state_stamp                     v       reported        up      up_primary      acting      acting_primary
active+clean    2016-06-03 00:31:44.220896      0'0     57:74           [0,1]    0              [0,1]       0               #osd.1 out 之前
active+remapped 2016-06-03 00:47:12.703537      0'0     71:109          [0]      0              [0,1]       0               #osd.1 out 之后

2.3 解決辦法

2.3.1 之一:將 crush tunables 設置為 optimal

(2)從這篇文章中獲得線索,這可能和 crush tunables 有關系。它的默認值應該是 legacy,運行下面的命令將其修改為 optimal 后,集群狀態回到正常。

ceph osd crush tunables optimal

(3)繼續找原因,Red Hat 這篇文章 給出了一些線索。 

  在新版本的Ceph 集群中使用 legacy 值可能會有一些問題,包括:

  • 當葉子bucket(往往是 host)所擁有的設備數目很小時,一些 PG 被映射到的 OSD 數目少於存儲池的size。這在 host 節點的 OSD 數目為 1-3 時較為常見。
  • 大型集群中,小部分的 PG 被映射到的 OSD 數目小於規定的數目。這在 CRUSH 層級結構中好幾層(比如 row,rack,host,osd 等)時比較常見。
  • 當一些 OSD 被標記為 out 時,重新分布的數據會更多地在附近的 OSD 上而不是整個層級結構中。

  而第一種情況正是我的測試集群所遇到的情況,每個 host 擁有的 OSD 數目在3個以內,然后部分 PG 所在的 OSD 數目較 replica 少一些。

  關於 CRUSH tunables 的詳細信息,請閱讀有關文檔。請注意在生產環境操作時有一定的風險。

2.3.2 之二:將 OSD 的 reweight 修改為 0 而不是使用 out 命令

    Ceph 官方的這篇文章 給出了另一個思路。它認為在主機數目很小的集群中,當一個 OSD 被 out 后,部分 PG 限於 active+remapped 狀態是經常出現的。解決辦法是先運行 ceph osd in {osd-num} 將集群狀態恢復到初始狀態,然后運行 ceph osd crush reweight osd.{osd-num} 0 來將這個 osd 的 crush weight 修改為 0,然后集群會開始數據遷移。對小集群來說,reweight 命令甚至更好些。

   當集群中 PG 限於 active + remapped 狀態時,可以通過 reweight 命令來使得集群恢復正常。當往集群中新加入 OSD 時,為了減少數據移動對集群性能的影響,Ceph 官方建議逐漸地增加 OSD 的 crush weight,比如起始值為0,先設置為 0.2,等數據遷移結束,再設置為 0.4,依此類推,逐漸增加為 0.6,0.8 和 1 甚至更高。在要停用一個 OSD 時,建議采用相反操作,逐漸減少 OSD 的 crush weight 直至 0.

3. 修改 CRUSH ruleset

3.1 問題描述

繼續將跟 osd.1 在同意個host 上的 osd.3 out,看看 Ceph 集群能不能繼續恢復。Ceph 集群中部分 PG 再次進入 remapped 狀態: 

root@ceph1:~# ceph -s
    cluster 5ccdcb2d-961d-4dcb-a9ed-e8034c56cf71
     health HEALTH_WARN 256 pgs stuck unclean
     monmap e2: 1 mons at {ceph1=192.168.56.102:6789/0}, election epoch 1, quorum 0 ceph1
     osdmap e77: 4 osds: 4 up, 2 in
      pgmap v480: 256 pgs, 4 pools, 285 MB data, 8 objects
            625 MB used, 9592 MB / 10217 MB avail
                 256 active+remapped

運行 ceph pg 1.0 query 查看 PG 1.0 的狀態:

"recovery_state": [
        { "name": "Started\/Primary\/Active",
          "enter_time": "2016-06-03 01:31:22.045434",
          "might_have_unfound": [],
          "recovery_progress": { "backfill_targets": [],
              "waiting_on_backfill": [],
              "last_backfill_started": "0\/\/0\/\/-1",
              "backfill_info": { "begin": "0\/\/0\/\/-1",
                  "end": "0\/\/0\/\/-1",
                  "objects": []},
              "peer_backfill_info": [],
              "backfills_in_flight": [],
              "recovering": [],
              "pg_backend": { "pull_from_peer": [],
                  "pushing": []}},
          "scrub": { "scrubber.epoch_start": "0",
              "scrubber.active": 0,
              "scrubber.block_writes": 0,
              "scrubber.finalizing": 0,
              "scrubber.waiting_on": 0,
              "scrubber.waiting_on_whom": []}},
        { "name": "Started",
          "enter_time": "2016-06-03 01:31:20.976290"}],

可見它已經開始 recovery 了,但是沒完成。

3.2 原因分析

PG 的分布和 CRUSH ruleset 有關。我的集群當前只有一個默認的 ruleset:

root@ceph1:~# ceph osd crush rule dump
[
    { "rule_id": 0,
      "rule_name": "replicated_ruleset",
      "ruleset": 0,
      "type": 1,
      "min_size": 1,
      "max_size": 10,
      "steps": [
            { "op": "take",
              "item": -1,
              "item_name": "default"},
            { "op": "chooseleaf_firstn",
              "num": 0,
              "type": "host"},
            { "op": "emit"}]}]

注意其 type 為 “host”,也就是說 CRUSH 不會為一個 PG 選擇在同一個 host 上的兩個 OSD。而我的環境中,目前只有 ceph1 上的兩個 OSD 是in 的,因此,CRUSH 無法為所有的 PG 重新選擇一個新的 OSD 來替代 osd.3.

3.3 解決辦法

按照以下步驟,將 CRUSH ruleset 的 type 由 “host” 修改為 “osd”,使得 CRUSH 為 PG 選擇 OSD 時不再局限於不同的 host。

root@ceph1:~# ceph osd getcrushmap -o crushmap_compiled_file
got crush map from osdmap epoch 77
root@ceph1:~# crushtool -d crushmap_compiled_file -o crushmap_decompiled_file
root@ceph1:~# vi crushmap_decompiled_file
rule replicated_ruleset {
        ruleset 0
        type replicated
        min_size 1
        max_size 10
        step take default
        step chooseleaf firstn 0 type osd #將 type 由 “host” 修改為 “osd”
        step emit
}
root@ceph1:~# crushtool -c crushmap_decompiled_file -o newcrushmap
root@ceph1:~# ceph osd setcrushmap -i newcrushmap
set crush map

以上命令執行完畢后,可以看到 recovery 過程繼續進行,一段時間后,集群恢復 OK 狀態。

root@ceph1:~# ceph -s
    cluster 5ccdcb2d-961d-4dcb-a9ed-e8034c56cf71
     health HEALTH_WARN 256 pgs stuck unclean
     monmap e2: 1 mons at {ceph1=192.168.56.102:6789/0}, election epoch 1, quorum 0 ceph1
     osdmap e80: 4 osds: 4 up, 2 in
      pgmap v493: 256 pgs, 4 pools, 285 MB data, 8 objects
            552 MB used, 9665 MB / 10217 MB avail
                 256 active+remapped
root@ceph1:~# ceph -s
    cluster 5ccdcb2d-961d-4dcb-a9ed-e8034c56cf71
     health HEALTH_WARN 137 pgs stuck unclean
     monmap e2: 1 mons at {ceph1=192.168.56.102:6789/0}, election epoch 1, quorum 0 ceph1
     osdmap e80: 4 osds: 4 up, 2 in
      pgmap v494: 256 pgs, 4 pools, 285 MB data, 8 objects
            677 MB used, 9540 MB / 10217 MB avail
                 137 active+remapped
                 119 active+clean
recovery io 34977 B/s, 0 objects/s
root@ceph1:~# ceph -s
    cluster 5ccdcb2d-961d-4dcb-a9ed-e8034c56cf71
     health HEALTH_OK
     monmap e2: 1 mons at {ceph1=192.168.56.102:6789/0}, election epoch 1, quorum 0 ceph1
     osdmap e80: 4 osds: 4 up, 2 in
      pgmap v495: 256 pgs, 4 pools, 285 MB data, 8 objects
            679 MB used, 9538 MB / 10217 MB avail
                 256 active+clean
recovery io 18499 kB/s, 0 objects/s

4. 將一個 OSD 移出集群

(1)將該 osd 設置為 out

root@ceph1:/home/s1# ceph osd out osd.1
marked out osd.1.

(2)集群做 recovery

2016-06-03 01:54:21.596632 mon.0 [INF] osdmap e90: 4 osds: 4 up, 3 in
2016-06-03 01:54:21.608675 mon.0 [INF] pgmap v565: 256 pgs: 256 active+clean; 1422 MB data, 2833 MB used, 12493 MB / 15326 MB avail
2016-06-03 01:54:26.352909 mon.0 [INF] pgmap v566: 256 pgs: 1 active, 255 active+clean; 1422 MB data, 2979 MB used, 12347 MB / 15326 MB avail; 2/40 objects degraded (5.000%); 51033 B/s, 0 objects/s recovering
2016-06-03 01:54:28.624334 mon.0 [INF] pgmap v567: 256 pgs: 4 active, 252 active+clean; 1422 MB data, 3427 MB used, 11899 MB / 15326 MB avail; 8/40 objects degraded (20.000%); 51053 B/s, 0 objects/s recovering
2016-06-03 01:54:31.320973 mon.0 [INF] pgmap v568: 256 pgs: 3 active, 253 active+clean; 1422 MB data, 3539 MB used, 11787 MB / 15326 MB avail; 6/40 objects degraded (15.000%); 19414 kB/s, 0 objects/s recovering
2016-06-03 01:54:32.323443 mon.0 [INF] pgmap v569: 256 pgs: 256 active+clean; 1422 MB data, 3730 MB used, 11595 MB / 15326 MB avail; 77801 kB/s, 0 objects/s recovering
^[[A2016-06-03 01:56:10.949077 mon.0 [INF] pgmap v570: 256 pgs: 256 active+clean; 1422 MB data, 3730 MB used, 11595 MB / 15326 MB avail

(3)完成后,該 osd 的狀態還是 up,表示它的服務還在運行。現在將其服務停掉。

root@ceph1:/home/s1# ssh ceph2 service ceph stop osd.1
/etc/init.d/ceph: osd.1 not found (/etc/ceph/ceph.conf defines , /var/lib/ceph defines )

該命令出錯,需要將 osd.1 加入 ceph.conf 中。在 ceph1 上的 ceph.conf 中添加:

[osd]

[osd.1]
host = ceph2

[osd.2]
host = ceph1

[osd.3]
host = ceph2

[osd.0]
host = ceph1

然后運行 ceph-deploy --overwrite-conf config push ceph2 將它拷貝到 ceph2 上。重啟所有的 osd 服務。詭異的事情出現了:

root@ceph1:/etc/ceph# ceph osd tree
# id    weight  type name       up/down reweight
-1      4       root default
-2      4               host ceph1
0       1                       osd.0   up      1
2       1                       osd.2   up      1
1       1                       osd.1   up      0
3       1                       osd.3   up      1
-3      0               host ceph2

osd.1 和 osd.3 跑到了 ceph1 節點上!查看 start 命令,它將 curshmap 中的 osd.1 的 host 修改為了 ceph2:

root@ceph1:/etc/ceph# /etc/init.d/ceph -a start osd
=== osd.1 ===
df: ‘/var/lib/ceph/osd/ceph-1/.’: No such file or directory
create-or-move updating item name 'osd.1' weight 1 at location {host=ceph1,root=default} to crush map
Starting Ceph osd.1 on ceph2...
starting osd.1 at :/0 osd_data /var/lib/ceph/osd/ceph-1 /var/lib/ceph/osd/ceph-1/journal

這篇文章 可以看出,這其實是Ceph的一個 bug:make osd crush placement on startup handle multiple trees (e.g., ssd + sas)。該bug 在 OSD location reset after restart 中也有討論。目前 Ceph 沒有機制可以確保 CRUSH map 結構不變,最簡單的辦法是在 ceph.conf 中 [OSD] 部分設置 osd crush update on start  = false。

嘗試手工挪動 osd.1 和 osd.3:

root@ceph1:/etc/ceph# ceph osd crush remove osd.1
removed item id 1 name 'osd.1' from crush map
root@ceph1:/etc/ceph# ceph osd crush remove osd.3
removed item id 3 name 'osd.3' from crush map
root@ceph1:/etc/ceph# ceph osd tree
# id    weight  type name       up/down reweight
-1      2       root default
-2      2               host ceph1
0       1                       osd.0   up      1
2       1                       osd.2   up      1
-3      0               host ceph2
1       0       osd.1   up      0
3       0       osd.3   up      1
root@ceph1:/etc/ceph# ceph osd crush set 1 1 root=default host=ceph2
Error ENOENT: unable to set item id 1 name 'osd.1' weight 1 at location {host=ceph2,root=default}: does not exist

該錯誤的原因待查。索性直接修改 crush map,然后正確的結果就回來了:

root@ceph1:/etc/ceph# ceph osd tree
# id    weight  type name       up/down reweight
-1      2       root default
-2      2               host ceph1
0       1                       osd.0   up      1
2       1                       osd.2   up      1
-3      0               host ceph2
1       1                       osd.1   up      0
3       1                       osd.3   up      1

繼續運行命令 ssh ceph2 /etc/init.d/ceph stop osd.1 去停止 osd.1 的服務,但是無法停止。據說是因為用 ceph-deploy 部署的 OSD 的服務都沒法停止。只能想辦法把進程殺掉了。

然后繼續執行:

root@ceph1:/etc/ceph# ceph osd crush remove osd.1
removed item id 1 name 'osd.1' from crush map
root@ceph1:/etc/ceph# ceph auth del osd.1
updated
root@ceph1:/etc/init# ceph osd rm osd.1
removed osd.1

此時,osd tree 中再也沒有 osd.1 了:

root@ceph1:/etc/ceph# ceph osd tree
# id    weight  type name       up/down reweight
-1      3       root default
-2      2               host ceph1
0       1                       osd.0   up      1
2       1                       osd.2   up      1
-3      1               host ceph2
3       1                       osd.3   up      1

5. 將一個 OSD 加入集群

 (1)將 /dev/sdb1 分區刪除

(2)清理磁盤:ceph-deploy disk zap ceph2:/dev/sdb

(3)創建 OSD:ceph-deploy osd create ceph2:sdb:/dev/sdd1

結果OSD就回來了:

root@ceph1:~# ceph-deploy osd create ceph2:sdb:/dev/sdd1c^C
root@ceph1:~# ceph osd tree
# id    weight  type name       up/down reweight
-1      2       root default
-2      2               host ceph1
0       1                       osd.0   up      1
2       1                       osd.2   up      1
-3      0               host ceph2
4       0                       osd.4   up      1
1       0                       osd.1   up      1

其實將上面第四步和第五步合並在一起,就是替換一個故障磁盤的過程。

6. 在特定 OSD 上創建存儲池

    我們假設 osd.0 和 osd.2 的磁盤是 SSD 磁盤,osd.1 和 osd.4 的磁盤是 SATA 磁盤。我們將創建兩個pool:pool-ssd 和 pool-sata,並確保 pool-ssd 中的對象都保存在 osd.0 和 osd.2 上,pool-sata 中的對象都保存在 osd.1 和 osd.4 上。

(1)修改 CRUSH map

root@ceph1:~# ceph osd getcrushmap -o crushmapdump
got crush map from osdmap epoch 124
root@ceph1:~# crushtool -d crushmapdump -o crushmapdump-decompiled
root@ceph1:~# vi crushmapdump-decompiled
root@ceph1:~# crushtool -c crushmapdump-decompiled -o crushmapdump-compiled
root@ceph1:~# ceph osd setcrushmap -i crushmapdump-compiled

在 crushmapdump-decompiled 文件中添加如下內容:

root ssd {
        id -5
        alg straw
        hash 0
        item osd.0 weight 1
        item osd.2 weight 1
}

root sata {
        id -6
        alg straw
        hash 0
        item osd.1 weight 1
        item osd.4 weight 1
}

# rules
...

rule ssd-pool {
        ruleset 1
        type replicated
        min_size 1
        max_size 10
        step take ssd
        step chooseleaf firstn 0 type osd
        step emit
}

rule sata-pool {
        ruleset 2
        type replicated
        min_size 1
        max_size 10
        step take sata
        step chooseleaf firstn 0 type osd
        step emit
}

(2) ceph osd tree 如下:

root@ceph1:~# ceph osd tree
# id    weight  type name       up/down reweight
-6      2       root sata
1       1               osd.1   up      1
4       1               osd.4   up      1
-5      2       root ssd
0       1               osd.0   up      1
2       1               osd.2   up      1
-1      2       root default
-2      2               host ceph1
0       1                       osd.0   up      1
2       1                       osd.2   up      1
-3      0               host ceph2
4       0                       osd.4   up      1
1       0                       osd.1   up      1

(3)創建 ssd-pool,其默認的 ruleset 為 0:

root@ceph1:~# ceph osd pool create ssd-pool 8 8
pool 'ssd-pool' created
root@ceph1:~# ceph osd dump | grep -i ssd
pool 4 'ssd-pool' replicated size 2 min_size 1 crush_ruleset 0 object_hash rjenkins pg_num 8 pgp_num 8 last_change 126 flags hashpspool stripe_width 0

(4)修改 ssd-pool 的 ruleset 為 ssd-pool 其id 為 1:

root@ceph1:~# ceph osd pool set ssd-pool crush_ruleset 1
set pool 4 crush_ruleset to 1
root@ceph1:~# ceph osd dump | grep -i ssd
pool 4 'ssd-pool' replicated size 2 min_size 1 crush_ruleset 1 object_hash rjenkins pg_num 8 pgp_num 8 last_change 128 flags hashpspool stripe_width 0

(5)類似地創建 sata-pool 並設置其 cursh ruleset 為 sata-pool 其id 為 2:

root@ceph1:~# ceph osd pool create sata-pool 8 8
pool 'sata-pool' created
root@ceph1:~# ceph osd pool set sata-pool crush_ruleset 2
set pool 5 crush_ruleset to 2
root@ceph1:~# ceph osd dump | grep -i sata
pool 5 'sata-pool' replicated size 2 min_size 1 crush_ruleset 2 object_hash rjenkins pg_num 8 pgp_num 8 last_change 131 flags hashpspool stripe_width 0

(6)分別放一個文件進這兩個pool:

root@ceph1:/home/s1# rados -p ssd-pool put root-id_rsa root-id_rsa
root@ceph1:/home/s1# rados -p sata-pool put root-id_rsa root-id_rsa
root@ceph1:/home/s1# rados -p ssd-pool ls
root-id_rsa
root@ceph1:/home/s1# rados -p sata-pool ls
root-id_rsa

(7)查看對象所在的 OSD

root@ceph1:/home/s1# ceph osd map ssd-pool root-id_rsa
osdmap e132 pool 'ssd-pool' (4) object 'root-id_rsa' -> pg 4.38e001ef (4.7) -> up ([2,0], p2) acting ([2,0], p2)
root@ceph1:/home/s1# ceph osd map sata-pool root-id_rsa
osdmap e132 pool 'sata-pool' (5) object 'root-id_rsa' -> pg 5.38e001ef (5.7) -> up ([4,1], p4) acting ([4,1], p4)

可見,兩個pool各自在ssd 和 sata 磁盤上。

7. rbd map 失敗:Input/output error

7.1 問題描述

   先准備好機器,然后在Ceph集群管理節點上運行 ceph-deploy install client 和 ceph-deploy admin client 來安裝和配置該節點。詳細過程可以參考 Oracle 這篇文章。 注意第二個命令需要在 /etc/ceph 目錄下執行,否則,拷貝到 client 節點上的 ceph.conf 會不正確,運行 ceph -s 也會碰到錯誤 0 librados: client.admin authentication error (1) Operation not permitted。

  然后執行下面的命令來創建一個卷並mount給該客戶端:

root@client:~# rbd create -p pool1 bd1 --size 100
root@client:~# rbd info --image bd1 -p pool1
rbd image 'bd1':
        size 102400 kB in 25 objects
        order 22 (4096 kB objects)
        block_name_prefix: rb.0.383a.2ae8944a
        format: 1
root@client:~# rbd map -p pool1 bd1

rbd: add failed: (5) Input/output error

7.2 問題解決和原因分析

這篇文章 中獲得線索,需要修改 crushmap 中的

root@client:/home/s1# ceph osd getcrushmap -o crush
got crush map from osdmap epoch 138
root@client:/home/s1# crushtool -i crush --set-chooseleaf_vary_r 0 -o crush.newroot@client:/home/s1# ceph osd setcrushmap -i crush.new
set crush map
root@client:/home/s1# rbd map -p pool1 bd1

初步看起來,這個問題和 linux 內核版本(我的內核版本是 1.13)以及 crush tunables 有關。在 3.15 之前的版本中,chooseleaf_vary_r 的值必須為0。根本原因需要進一步研究。

8. 修復 stale 狀態 PG

8.1 問題描述

root@client:/home/s1# ceph -s
    cluster 5ccdcb2d-961d-4dcb-a9ed-e8034c56cf71
     health HEALTH_WARN 8 pgs stale; 8 pgs stuck stale
     monmap e2: 1 mons at {ceph1=192.168.56.102:6789/0}, election epoch 1, quorum 0 ceph1
     osdmap e182: 4 osds: 4 up, 4 in
      pgmap v2569: 336 pgs, 8 pools, 5763 MB data, 1171 objects
            13763 MB used, 6672 MB / 20435 MB avail
                   8 stale+active+clean
                 328 active+clean

學習一下 stale 狀態的概念:PG 的狀態沒有被 ceph-osd 上報給 MON,這意味着存放該 PG 的所有 OSD 都是down 的。MON 將主 OSD down 掉了的 PG 的狀態狀態設置為 stale。

8.2 問題定位

(1).找出哪些 PG 處於 stale 狀態

root@ceph1:~# ceph pg dump | grep stale
dumped all in format plain
5.2     0       0       0       0       0       0       0       stale+active+clean      2016-06-03 03:50:07.049571      0'0     132:6      [4,1]   4       [4,1]   4       0'0     2016-06-03 03:49:50.301465      0'0     2016-06-03 03:49:50.301465
5.3     0       0       0       0       0       0       0       stale+active+clean      2016-06-03 03:50:07.034290      0'0     132:6      [4,1]   4       [4,1]   4       0'0     2016-06-03 03:49:50.302140      0'0     2016-06-03 03:49:50.302140

但是現在 OSD Tree 中不再有 osd.1 和 osd.4,因為這兩個 OSD 的盤之前丟了!后來重做成了 osd.3 和 osd.5。這和上面的 stale 狀態的概念吻合。重做的時候 OSD磁盤的分區被刪除過,不知道數據是否還在。看來,丟失數據也是很容易的事情啊。看來,下次看到某個 OSD down 掉了時,首先應該做的是要將它重新 up 起來。

(2)修復不行

root@ceph1:~# ceph pg repair 5.2
Error EAGAIN: pg 5.2 primary osd.4 not up

(3)只能刪除它所屬於的 pool 了。注意 PG ID 的前半部分是 pool id,后半部分才是 PG 自己的 id。

root@ceph1:~# ceph osd pool delete sata-pool sata-pool  --yes-i-really-really-mean-it
pool 'sata-pool' removed

其實這么做也不對,因為一個 pool 有多個 PG,其中只有部分是 stale 狀態,因此在刪除之前要看清楚。這一步驟要十分小心!

(4)ceph -s 恢復正常。

9. 分離 public network 和 cluster network

9.1 分離的好處

(1)提高性能:消除副本創建、數據恢復和再平衡對 public network 的壓力;增強 OSD 心跳網絡的可靠性。

(2)安全性:使用一個徹底與外網分離的內部網絡作為 cluster network,可以防止比如 DDOS 這樣的網絡攻擊。

更多信息,請參閱 NETWORK CONFIGURATION REFERENCE

9.2 分離的方法

(1)配置網絡

給每個 OSD 節點增加一塊網卡,它的連接方式為 “內部網絡”;在虛機內配置靜態IP地址,網段為 192.168.1.100/24 (其實用不了這么大的網段).

(2)在 ceph1 上修改 ceph.conf 文件

[global]
...

public network = 192.168.56.100/24
cluster network = 192.168.1.100/24

[mon]
[mon.ceph1] # MON 守護進程只在public network 內 host
= ceph1 mon addr = 192.168.56.102:6789 [osd] osd journal size = 500 osd crush update on start = false [osd.3] #OSD 守護進程同時在 public 和 cluster network 上 host = ceph2 public addr = 192.168.56.103 cluster addr = 192.168.1.103 [osd.0] host = ceph1 public addr = 192.168.56.102 cluster addr = 192.168.1.102 [osd.5] host = ceph2 public addr = 192.168.56.103 cluster addr = 192.168.1.103 [osd.2] host = ceph1 public addr = 192.168.56.102 cluster addr = 192.168.1.102

(3)將新的 ceph.conf 分發到其它節點上,比如 ceph-deploy --overwrite-conf config push ceph2

(4)重啟所有 OSD 和 MON 守護進程

可以在 osd 日志中看到內部網絡IP地址被啟用了。

10. 啟用客戶端 rbd cache

10.1 步驟

編輯在客戶端的 ceph.conf 文件,添加下面的配置項

[client]
rbd cache = true
rbd cache writethrough until flush = true
admin socket = /var/run/ceph/$cluster-$type.$id.$pid.$cctid.asok
log file = /var/log/ceph/

啟動使用 librbd 的應用,比如 fio + rbd ioengine,然后從 client admin socket 中確認cache 被啟用了:

root@client:/var/run/ceph# ls
ceph-client.admin.23789.140009021853536.asok
root@client:/var/run/ceph# ceph --admin-daemon ceph-client.admin.23789.140009021853536.asok  config show | grep rbd_cache
  "rbd_cache": "true",
  "rbd_cache_writethrough_until_flush": "false",
  "rbd_cache_size": "33554432",
  "rbd_cache_max_dirty": "25165824",
  "rbd_cache_target_dirty": "16777216",
  "rbd_cache_max_dirty_age": "1",
  "rbd_cache_max_dirty_object": "0",
  "rbd_cache_block_writes_upfront": "false",

注意rbd cache 只對 librbd 起作用,對 kernel rbd 不起作用。

 

 

[更多內容,將來會繼續添加]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM