はじめに
停電から回復したKubernetesクラスターの状態を確認していたところ、1つのPod(gitbucket)だけがContainerCreating状態のまま長時間停止していることが分かりました。
原因はPVCがmountできないことだったのですが、原因は停電によってext4のjournal dataが残ったままになっていた事にあります。
回復のためにfsck.ext4を実行すれば良いことはすぐに分かったのですが、どのボリュームに対して実行すれば良いのか直感的には分かりにくかったのでメモを残しておきます。
環境
- Kubernetes v1.16.9 deployed by Kubespray
- Rook/Ceph v1.1.9 with FlexVolumes (BlockStorage using ext4)
パーティションが破壊された事に起因するデータ破壊については、以下のバージョンで発生しています。
- Rook/Ceph v1.6.7 with CSI BlueStore (with HDD 4TBx2)
状態
kubectlコマンドで確認したところ次のような状態になっています。
$ kubectl -n gitbucket get all
NAME READY STATUS RESTARTS AGE
pod/bucket-9b8d9799-khsm8 0/1 Init:1/2 1 27h
pod/mysql-84d459c89c-w8pb6 0/1 ContainerCreating 0 15m
Pod:bucketはinitContainersでmysqlの起動を待っているので、init状態のまま停止しています。mysqlのコンテナが起動すれば、bucketコンテナは自然に回復するはずなので、まずmysqlコンテナの回復を目指します。
BlockStorageの不具合
エラーの状況
kubectl describeで起動時の状態を確認すると次のようになっていました。
$ kubectl -n gitbucket describe pod/mysql-84d459c89c-w8pb6
....
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 16m default-scheduler Successfully assigned gitbucket/mysql-84d459c89c-w8pb6 to node04
Warning FailedMount 15m (x5 over 16m) kubelet, node04 MountVolume.SetUp failed for volume "pvc-8aaa318c-1212-415d-b00f-e88b9c3c3087" : mount command failed, status: Failure, reason: Rook: Mount volume failed: failed to attach volume pvc-8aaa318c-1212-415d-b00f-e88b9c3c3087 for pod gitbucket/mysql-84d459c89c-w8pb6. Volume is already attached by pod gitbucket/mysql-84d459c89c-rllg6. Status Pending
Warning FailedMount 2m46s (x3 over 11m) kubelet, node04 Unable to attach or mount volumes: unmounted volumes=[mysql-persistent-storage], unattached volumes=[database-auth-conf default-token-txprc mysql-persistent-storage]: timed out waiting for the condition
Warning FailedMount 92s (x10 over 15m) kubelet, node04 MountVolume.SetUp failed for volume "pvc-8aaa318c-1212-415d-b00f-e88b9c3c3087" : mount command failed, status: Failure, reason: failed to mount volume /dev/rbd2 [ext4] to /var/lib/kubelet/plugins/ceph.rook.io/rook-ceph/mounts/pvc-8aaa318c-1212-415d-b00f-e88b9c3c3087, error 'fsck' found errors on device /dev/rbd2 but could not correct them: fsck from util-linux 2.31.1
/dev/rbd2: Superblock needs_recovery flag is clear, but journal has data.
/dev/rbd2: Run journal anyway
/dev/rbd2: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
(i.e., without -a or -p options)
.
Warning FailedMount 32s (x4 over 14m) kubelet, node04 Unable to attach or mount volumes: unmounted volumes=[mysql-persistent-storage], unattached volumes=[mysql-persistent-storage database-auth-conf default-token-txprc]: timed out waiting for the condition
このエラーメッセージから、ノードnode04と**/dev/rbd2**で問題が発生していることが分かります。
node04上での修正
最初は、どう対応して良いか分からなかったのですが、node04にログインして/dev/を確認してみると、rbd2が存在しているので、これをfsck.ext4コマンドの引数に与えてみることにしました。
$ ssh node04
$ sudo fsck.ext4 /dev/rbd2
e2fsck 1.44.1 (24-Mar-2018)
Superblock needs_recovery flag is clear, but journal has data.
Run journal anyway<y>? yes
/dev/rbd2: recovering journal
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Free blocks count wrong (5067650, counted=5067649).
Fix<y>? yes
Free inodes count wrong (1310519, counted=1310518).
Fix<y>? yes
/dev/rbd2: ***** FILE SYSTEM WAS MODIFIED *****
/dev/rbd2: 202/1310720 files (14.9% non-contiguous), 175231/5242880 blocks
このまま時間が経過すると無事にPodが動き始めました。
$ kubectl -n gitbucket get all
NAME READY STATUS RESTARTS AGE
pod/bucket-9b8d9799-khsm8 0/1 Init:1/2 1 27h
pod/mysql-84d459c89c-w8pb6 0/1 Running 0 27m
xfsで構成した方が良かったかなと(xfsでも問題が発生する可能性はありますが)少し後悔しています。
以上
その後に発生した障害
今回はHarborで利用しているPVCがmountできなくなったのですが、原因はまた別でした。
$ kubectl -n harbor describe pod/my-harbor-harbor-redis-0
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedMount 12m (x228 over 7h42m) kubelet, node01 MountVolume.SetUp failed for volume "pvc-d37fd3f0-22ac-42c2-a90d-7427c2fa91d7" : mount command failed, status: Failure, reason: Rook: Mount volume failed: failed to attach volume pvc-d37fd3f0-22ac-42c2-a90d-7427c2fa91d7 for pod harbor/my-harbor-harbor-redis-0. Volume is already attached by pod harbor/my-harbor-harbor-redis-0. Status Pending
Warning FailedMount 7m18s (x151 over 7h40m) kubelet, node01 Unable to attach or mount volumes: unmounted volumes=[data], unattached volumes=[data default-token-nnqmn]: timed out waiting for the condition
Warning FailedMount 2m47s (x51 over 7h38m) kubelet, node01 Unable to attach or mount volumes: unmounted volumes=[data], unattached volumes=[default-token-nnqmn data]: timed out waiting for the condition
この時に PV: pvc-d37fd3f0-22ac-42c2-a90d-7427c2fa91d7 の状態がどうなっているのか確認します。
$ kubectl -n harbor get pv pvc-d37fd3f0-22ac-42c2-a90d-7427c2fa91d7
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM
STORAGECLASS REASON AGE
pvc-d37fd3f0-22ac-42c2-a90d-7427c2fa91d7 1Gi RWO Delete Bound harbor/data-my-harbor-harbor-redis-0 rook-ceph-block 232d
Rook/Cephの側からみると特別な問題は発生していません。
$ kubectl -n harbor get pvc data-my-harbor-harbor-redis-0
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-my-harbor-harbor-redis-0 Bound pvc-d37fd3f0-22ac-42c2-a90d-7427c2fa91d7 1Gi RWO rook-ceph-block 232d
$ kubectl -n rook-ceph exec -it rook-ceph-tools-7764cdbbc4-wkc64 ceph status
cluster:
id: 89ddf8a3-e7ce-41e6-a081-b6b5fab8b8e0
health: HEALTH_OK
services:
mon: 3 daemons, quorum v,w,y (age 7h)
mgr: a(active, since 7h)
mds: myfs:1 {0=myfs-a=up:active} 1 up:standby-replay
osd: 4 osds: 4 up (since 7h), 4 in (since 7h)
data:
pools: 13 pools, 104 pgs
objects: 2.64k objects, 6.1 GiB
usage: 567 GiB used, 6.6 TiB / 7.2 TiB avail
pgs: 104 active+clean
io:
client: 938 B/s rd, 9.5 KiB/s wr, 1 op/s rd, 0 op/s wr
$ kubectl -n rook-ceph logs -l rook-ceph-agent
...
2020-09-04 01:59:27.976756 I | flexdriver: calling agent to attach volume replicapool/pvc-d37fd3f0-22ac-42c2-a90d-7427c2fa91d7
2020-09-04 01:59:27.979645 I | flexvolume: volume attachment record rook-ceph/pvc-d37fd3f0-22ac-42c2-a90d-7427c2fa91d7 exists for pod: harbor/my-harbor-harbor-redis-0
...
対応
どうにもStatefulSetの定義から削除する以外に対応が思いつかなかったので、helmで導入していたので、helmから削除して、再度インストールすることにしました。
$ (cd harbor-helm; helm delete my-harbor)
$ (cd harbor-helm; helm install --replace --name my-harbor --namespace harbor .)
さすがにこの後は問題なくPVCがマウントできました。
調べてみると定期的に実施している夜間のノード毎の再起動タイミングが非常に近かったので、これを十分に話して不整合が発生しにくくしてしばらく様子をみることにしました。
Filesystemの不具合
また別のPodではfilesystemがマウントできない状況になりました。
Warning FailedMount 13m kubelet, node04 MountVolume.SetUp failed for volume "rook-data" : mount command failed, stat
us: Failure, reason: failed to mount filesystem myfs to /var/lib/kubelet/pods/297a0883-0d02-41c9-855b-b193f02210ec/volumes/c
eph.rook.io~rook/rook-data with monitor 10.233.32.156:6789,10.233.62.103:6789,10.233.34.233:6789:/ and options [name=admin s
ecret=AQBuk+pctG/7JBAATogIHHCDNN7W7u4zppFtaw== mds_namespace=myfs]: mount failed: exit status 32
Mounting command: systemd-run
Mounting arguments: --description=Kubernetes transient mount for /var/lib/kubelet/pods/297a0883-0d02-41c9-855b-b193f02210ec/
volumes/ceph.rook.io~rook/rook-data --scope -- mount -t ceph -o name=admin,secret=AQBuk+pctG/7JBAATogIHHCDNN7W7u4zppFtaw==,m
ds_namespace=myfs 10.233.32.156:6789,10.233.62.103:6789,10.233.34.233:6789:/ /var/lib/kubelet/pods/297a0883-0d02-41c9-855b-b
193f02210ec/volumes/ceph.rook.io~rook/rook-data
Output: Running scope as unit: run-r35a1db0e9e564106b94b7ea5d1973fb3.scope
mount: /var/lib/kubelet/pods/297a0883-0d02-41c9-855b-b193f02210ec/volumes/ceph.rook.io~rook/rook-data: mount(2) system call
failed: No route to host.
Warning FailedMount 13m kubelet, node04 MountVolume.SetUp failed for volume "rook-data" : mount command failed, stat
us: Failure, reason: failed to mount filesystem myfs to /var/lib/kubelet/pods/297a0883-0d02-41c9-855b-b193f02210ec/volumes/c
eph.rook.io~rook/rook-data with monitor 10.233.32.156:6789,10.233.62.103:6789,10.233.34.233:6789:/ and options [name=admin s
ecret=AQBuk+pctG/7JBAATogIHHCDNN7W7u4zppFtaw== mds_namespace=myfs]: mount failed: exit status 32
対応
MDSノードでも特にエラーメッセージは確認できませんでしたが、ノードをリスタートしてみます。
念のためStandbyになっている方からリスタートします。
$ kubectl -n rook-ceph exec -it rook-ceph-tools-6dd7c595bc-xvk92 ceph status
...
services:
mon: 3 daemons, quorum bm,bs,bu (age 15m)
mgr: a(active, since 13m)
mds: myfs:1 {0=myfs-a=up:active} 1 up:standby-replay
osd: 4 osds: 4 up (since 60m), 4 in (since 5w)
...
## "a=up:active"の表示から、b側をまず再起動しておく
$ kubectl -n rook-ceph delete pod rook-ceph-mds-myfs-b-78ccfc6754-jff2f
## kubectl -n rook-ceph get pod でmyfs-bが正常に動いていることを確認してから、a側をリスタートする
$ kubectl -n rook-ceph delete pod rook-ceph-mds-myfs-a-87448c57b-lp7hl
一応は、この方法でMDSノードを再起動して無事にfilesystemにアクセスできるようになりました。
HEALTH_ERR への対応
気がつくとノード全体が機能を停止していて、いろいろPodがPending状態やらTerminatingのまま固まっていたりとか、それらを解消した後にceph statusがエラーになっていました。
そもそものノードエラーはshutdown -r now
でシステム全体をリスタートしました。この部分の根本原因については、推測はしていますが、追求していません。
その上で発生し続けたエラーについてメモを残しておきます。
エラーの状況
ノードを再起動する前には、TerminatingなPodとPendingなPodの2つが同時に存在し続ける変な感じになっていたのですが、再起動してみるとRook/Cephが妙な結果になっている事に気がつきました。
$ kubectl -n rook-ceph exec -it ... -- ceph status
cluster:
id: 3cedbf9c-82a4-4ce8-988b-9e64b1b3d97a
health: HEALTH_ERR
Module 'rook' has failed: HTTPSConnectionPool(host='10.233.0.1', port=443): Max retries exceeded with url: /api/v1/namespaces/rook-ceph/pods (Caused by ProtocolError('Connection aborted.', error(99, 'Cannot assign requested address')))
services:
mon: 3 daemons, quorum bm,bs,bu (age 104s)
mgr: a(active, since 5m)
mds: myfs:1 {0=myfs-b=up:active} 1 up:standby-replay
osd: 4 osds: 4 up (since 112m), 4 in (since 8w)
data:
pools: 3 pools, 300 pgs
objects: 2.01M objects, 11 GiB
usage: 970 GiB used, 13 TiB / 14 TiB avail
pgs: 300 active+clean
io:
client: 1.2 KiB/s rd, 46 KiB/s wr, 2 op/s rd, 2 op/s wr
つまり、問題なくMDS/OSDは稼動しているのに、HEALTH_ERRとなっている点に気がつきました。
いろいろ試行錯誤した後に、mgr podを再起動しました。
$ kubectl -n rook-ceph delete replicaset.apps/rook-ceph-mgr-a-7644684465
replicaset.apps "rook-ceph-mgr-a-7644684465" deleted
しばらくしてからceph statusを確認し、問題が修正されたことを確認しました。
$ kubectl -n rook-ceph exec -it ... -- ceph status
cluster:
id: 3cedbf9c-82a4-4ce8-988b-9e64b1b3d97a
health: HEALTH_OK
...
実際にはmds podの内部でエラーが発生していたり、いろいろあったので、standby側からリスタートしたり、全ての稼動しているPodのログは確認した上での作業でした。
本家のissuesでも解決策までは載っていなかったので、moduleをdisabled/enabledするべきなのか、他の方法で対応するべきなのか判断がつかなかったのですが、ひとまず問題はcloseしたので良かったです。
全台shutdownの影響によるrace conditionに遭遇した時のメモ
このメモはリカバリーの記録ではありません。単純にテスト系で発生した事象に対して行なった操作と結果を残しているだけです。データの保全が必要な場合には別途方法を検討してください。
【2021/08/18追記】
この現象では、/dev/sdb2,/dev/sdc2などがbluestoreになっている事がデータ破壊の根本原因となっています。公式のドキュメントが更新され、v1.6.0以降のバージョンで現象が発生すること、v1.6.8以降へのアップグレードが推奨されています。解決策は、v1.6.8以降に更新した後、OSDを削除し、問題となっているディスクの初期化、再認識による正常化が指示されています。
https://rook.github.io/docs/rook/v1.6/ceph-common-issues.html#unexpected-partitions-created
2021/07にテスト系のk8sシステム全体をshutdownしてメンテナンスを行なってからシステムを再起動したところ次のような状況になりました。
少し冗長ですがメンテナンス用のBASH関数についても掲載しています。
race conditionが発生することは度々リポートされていて、issuesにも記録が残っています。
cri-oにすれば遭遇しないといったメモもありますが、VMware上でテストした範囲ではlibcephのエラーは発生していて違いは観測されませんでした。
今回発生したのは、最初のリンク先にあるRaw Deviceがおかしくなった点にあります。
クラスター全体では4TBのディスクを各ノード2つ、4ノードで計32TBを利用しています。
$ lsblk -l
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 55.4M 1 loop /snap/core18/1944
loop1 7:1 0 55.5M 1 loop /snap/core18/2074
loop2 7:2 0 67.6M 1 loop /snap/lxd/20326
loop3 7:3 0 32.3M 1 loop /snap/snapd/12159
loop5 7:5 0 32.3M 1 loop /snap/snapd/12398
loop6 7:6 0 70.3M 1 loop /snap/lxd/21029
sda 8:0 0 465.8G 0 disk
sda1 8:1 0 512M 0 part
sda2 8:2 0 465.3G 0 part /
sdb 8:16 0 3.7T 0 disk
sdb2 8:18 0 48G 0 part
sdb3 8:19 0 6.7M 0 part
sdc 8:32 0 3.7T 0 disk
sdc2 8:34 0 48G 0 part
sdc3 8:35 0 6.2M 0 part
sr0 11:0 1 1024M 0 rom
$ lsblk -f
NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
loop0 squashfs 0 100% /snap/core18/1944
loop1 squashfs 0 100% /snap/core18/2074
loop2 squashfs 0 100% /snap/lxd/20326
loop3 squashfs 0 100% /snap/snapd/12159
loop5 squashfs 0 100% /snap/snapd/12398
loop6 squashfs 0 100% /snap/lxd/21029
sda
├─sda1 vfat 5AD4-66D1
└─sda2 ext4 42db9b49-9bb0-4590-a0f5-846f1a74058b 420.2G 3% /
sdb ceph_bluestore
├─sdb2 ceph_bluestore
└─sdb3
sdc ceph_bluestore
├─sdc2 ceph_bluestore
└─sdc3
sr0
期待するのは、/dev/sdb全体をceph_bluestoreとして利用している状態で、/dev/sdb{2,3}は存在自体が想定外のパーティションです。
$ type get_toolbox_podname
get_toolbox_podname is a function
get_toolbox_podname ()
{
sudo kubectl -n rook-ceph get pod -l app=rook-ceph-tools -o jsonpath='{.items[*].metadata.name}'
}
$ type ceph_status
ceph_status is a function
ceph_status ()
{
name=$(get_toolbox_podname);
sudo kubectl -n rook-ceph exec -it "${name}" -- ceph status
}
## ここからがログ
$ ceph_status
cluster:
id: 454d7e30-a1f5-4369-b1e5-6b9b2700054c
health: HEALTH_ERR
4/507 objects unfound (0.789%)
1487 scrub errors
Too many repaired reads on 5 OSDs
Possible data damage: 4 pgs recovery_unfound, 26 pgs inconsistent
Degraded data redundancy: 12/1521 objects degraded (0.789%), 4 pgs degraded
3 pgs not deep-scrubbed in time
4 pgs not scrubbed in time
6 slow ops, oldest one blocked for 1584994 sec, daemons [osd.0,osd.1,osd.2,osd.4,osd.5] have slow
ops.
services:
mon: 3 daemons, quorum a,b,c (age 2w)
mgr: a(active, since 2w)
mds: myfs:1 {0=myfs-b=up:active} 1 up:standby-replay
osd: 16 osds: 16 up (since 2w), 16 in (since 2w)
rgw: 1 daemon active (my.store.a)
task status:
data:
pools: 11 pools, 177 pgs
objects: 507 objects, 686 MiB
usage: 19 GiB used, 29 TiB / 29 TiB avail
pgs: 12/1521 objects degraded (0.789%)
4/507 objects unfound (0.789%)
148 active+clean
13 active+clean+inconsistent
12 active+clean+inconsistent+failed_repair
3 active+recovery_unfound+degraded
1 active+recovery_unfound+degraded+inconsistent+failed_repair
io:
client: 1.2 KiB/s rd, 2 op/s rd, 0 op/s wr
このログは、障害が発生してから数日経過した状態で出力したものです。
Clean-upのために、全てのPVCを削除すると、8時間ほど経過しても削除処理が完了せずに、このログは次のようになりました。
$ ceph_status
cluster:
id: 454d7e30-a1f5-4369-b1e5-6b9b2700054c
health: HEALTH_ERR
6/507 objects unfound (1.183%)
1213 scrub errors
Too many repaired reads on 5 OSDs
Possible data damage: 6 pgs recovery_unfound, 20 pgs inconsistent
Degraded data redundancy: 18/1521 objects degraded (1.183%), 6 pgs degraded
3 pgs not deep-scrubbed in time
4 pgs not scrubbed in time
8 slow ops, oldest one blocked for 1614550 sec, daemons [osd.0,osd.1,osd.2,osd.4,osd.5] have slow
ops.
services:
mon: 3 daemons, quorum a,b,c (age 2w)
mgr: a(active, since 2w)
mds: myfs:1 {0=myfs-b=up:active} 1 up:standby-replay
osd: 16 osds: 16 up (since 2w), 16 in (since 2w)
rgw: 1 daemon active (my.store.a)
task status:
data:
pools: 11 pools, 177 pgs
objects: 507 objects, 686 MiB
usage: 19 GiB used, 29 TiB / 29 TiB avail
pgs: 18/1521 objects degraded (1.183%)
6/507 objects unfound (1.183%)
154 active+clean
10 active+clean+inconsistent+failed_repair
7 active+clean+inconsistent
3 active+recovery_unfound+degraded
3 active+recovery_unfound+degraded+inconsistent+failed_repair
io:
client: 1.2 KiB/s rd, 2 op/s rd, 0 op/s wr
この時のPVCの状態は次のようなもので、たまたま最後に削除したRook/Cassandraが利用するPVCだけが残っています。
削除手順自体はドキュメントに従っています。
$ sudo kubectl get pvc --all-namespaces
NAMESPACE NAME STATUS VOLUME
CAPACITY ACCESS MODES STORAGECLASS AGE
rook-cassandra rook-cassandra-data-rook-cassandra-us-east-1-us-east-1a-0 Terminating pvc-77d3d697-edd5-4
633-8b81-a8474eb94043 5Gi RWO rook-ceph-block 26d
rook-cassandra rook-cassandra-data-rook-cassandra-us-east-1-us-east-1a-1 Terminating pvc-c6bc0341-ba1d-4
419-b280-c143edf240bb 5Gi RWO rook-ceph-block 26d
rook-cassandra rook-cassandra-data-rook-cassandra-us-east-1-us-east-1a-2 Terminating pvc-c4261458-7d46-4
33a-a05f-7c94e93b7034 5Gi RWO rook-ceph-block 26d
とりあえず ceph health detail
の出力はエラーのオンパレードのような状況になっています。
全てのPVを削除している状況なので、いろいろ試してみます。
# ceph health detail
HEALTH_ERR 1/397 objects unfound (0.252%); 920 scrub errors; Too many repaired reads on 5 OSDs; Possible data
damage: 1 pg recovery_unfound, 19 pgs inconsistent; Degraded data redundancy: 3/1191 objects degraded (0.252%)
, 1 pg degraded; 1 pgs not deep-scrubbed in time; 1 pgs not scrubbed in time; 4 slow ops, oldest one blocked f
or 1626835 sec, daemons [osd.1,osd.2,osd.5] have slow ops.
[WRN] OBJECT_UNFOUND: 1/397 objects unfound (0.252%)
pg 2.1a has 1 unfound objects
[ERR] OSD_SCRUB_ERRORS: 920 scrub errors
[WRN] OSD_TOO_MANY_REPAIRS: Too many repaired reads on 5 OSDs
osd.3 had 16 reads repaired
osd.1 had 18 reads repaired
osd.7 had 31 reads repaired
osd.2 had 32 reads repaired
osd.4 had 34 reads repaired
[ERR] PG_DAMAGED: Possible data damage: 1 pg recovery_unfound, 19 pgs inconsistent
pg 2.1 is active+clean+inconsistent+failed_repair, acting [7,0,6]
pg 2.3 is active+clean+inconsistent+failed_repair, acting [3,5,6]
pg 2.5 is active+clean+inconsistent, acting [6,4,1]
pg 2.7 is active+clean+inconsistent+failed_repair, acting [1,7,4]
pg 2.8 is active+clean+inconsistent+failed_repair, acting [3,2,0]
pg 2.a is active+clean+inconsistent+failed_repair, acting [2,4,7]
pg 2.11 is active+clean+inconsistent+failed_repair, acting [7,1,4]
pg 2.18 is active+clean+inconsistent+failed_repair, acting [3,1,2]
pg 2.1a is active+recovery_unfound+degraded, acting [5,6,4], 1 unfound
pg 2.1b is active+clean+inconsistent+failed_repair, acting [6,5,3]
pg 2.1c is active+clean+inconsistent+failed_repair, acting [2,1,0]
pg 2.1d is active+clean+inconsistent+failed_repair, acting [3,6,5]
pg 2.1e is active+clean+inconsistent+failed_repair, acting [4,6,3]
pg 2.1f is active+clean+inconsistent+failed_repair, acting [4,1,2]
pg 11.6 is active+clean+inconsistent, acting [3,0,1]
pg 11.9 is active+clean+inconsistent, acting [4,1,7]
pg 11.c is active+clean+inconsistent, acting [7,4,1]
pg 11.14 is active+clean+inconsistent, acting [1,4,3]
pg 11.1b is active+clean+inconsistent, acting [1,2,0]
pg 11.1d is active+clean+inconsistent, acting [1,11,3]
[WRN] PG_DEGRADED: Degraded data redundancy: 3/1191 objects degraded (0.252%), 1 pg degraded
pg 2.1a is active+recovery_unfound+degraded, acting [5,6,4], 1 unfound
[WRN] PG_NOT_DEEP_SCRUBBED: 1 pgs not deep-scrubbed in time
pg 2.1a not deep-scrubbed since 2021-06-24T13:46:01.226873+0000
[WRN] PG_NOT_SCRUBBED: 1 pgs not scrubbed in time
pg 2.1a not scrubbed since 2021-06-30T19:52:31.104830+0000
[WRN] SLOW_OPS: 4 slow ops, oldest one blocked for 1626835 sec, daemons [osd.1,osd.2,osd.5] have slow ops.
OBJECT_UNFOUND: なpgに対しては、mark_unfound_lost で対応していきます。
# ceph pg 2.1a mark_unfound_lost delete
pg has 1 objects unfound and apparently lost marking
OSD_TOO_MANY_REPAIRS: に対しては、RedHatのドキュメントでは、強制的にメッセージを消去できそうな clear_shards_repaired が紹介されていますが、一般のcephでは提供されていないオプションのようです。
osd repair <who>
を試してみます。
# ceph osd repair all
instructed osd(s) 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 to repair
これで、いくらかエラーは減っていき、次のようになりました。
# ceph health detail
HEALTH_ERR 864 scrub errors; Too many repaired reads on 5 OSDs; Possible data damage: 6 pgs inconsistent; 3 sl
ow ops, oldest one blocked for 1627269 sec, daemons [osd.1,osd.2] have slow ops.
[ERR] OSD_SCRUB_ERRORS: 864 scrub errors
[WRN] OSD_TOO_MANY_REPAIRS: Too many repaired reads on 5 OSDs
osd.3 had 16 reads repaired
osd.1 had 18 reads repaired
osd.7 had 31 reads repaired
osd.2 had 32 reads repaired
osd.4 had 35 reads repaired
[ERR] PG_DAMAGED: Possible data damage: 6 pgs inconsistent
pg 11.6 is active+clean+inconsistent, acting [3,0,1]
pg 11.9 is active+clean+inconsistent, acting [4,1,7]
pg 11.c is active+clean+inconsistent, acting [7,4,1]
pg 11.14 is active+clean+inconsistent, acting [1,4,3]
pg 11.1b is active+clean+inconsistent, acting [1,2,0]
pg 11.1d is active+clean+inconsistent, acting [1,11,3]
[WRN] SLOW_OPS: 3 slow ops, oldest one blocked for 1627269 sec, daemons [osd.1,osd.2] have slow ops.
しばらくすると、PG_DAMAGEDは全て消えて、OSD_TOO_MANY_REPAIRSだけが残りました。
# ceph health detail
HEALTH_WARN Too many repaired reads on 5 OSDs; 3 slow ops, oldest one blocked for 1627335 sec, daemons [osd.1,
osd.2] have slow ops.
[WRN] OSD_TOO_MANY_REPAIRS: Too many repaired reads on 5 OSDs
osd.3 had 16 reads repaired
osd.1 had 18 reads repaired
osd.7 had 31 reads repaired
osd.2 had 32 reads repaired
osd.4 had 35 reads repaired
[WRN] SLOW_OPS: 3 slow ops, oldest one blocked for 1627335 sec, daemons [osd.1,osd.2] have slow ops.
# ceph status
cluster:
id: 454d7e30-a1f5-4369-b1e5-6b9b2700054c
health: HEALTH_WARN
Too many repaired reads on 5 OSDs
3 slow ops, oldest one blocked for 1627340 sec, daemons [osd.1,osd.2] have slow ops.
services:
mon: 3 daemons, quorum a,b,c (age 2w)
mgr: a(active, since 2w)
mds: myfs:1 {0=myfs-b=up:active} 1 up:standby-replay
osd: 16 osds: 16 up (since 2w), 16 in (since 2w)
rgw: 1 daemon active (my.store.a)
task status:
data:
pools: 11 pools, 177 pgs
objects: 343 objects, 184 MiB
usage: 18 GiB used, 29 TiB / 29 TiB avail
pgs: 177 active+clean
io:
client: 5.7 KiB/s rd, 426 B/s wr, 6 op/s rd, 2 op/s wr
ここから、osd purge <id|osd.id> [--force] [--yes-i-really-mean-it]
を試してみます。
# ceph osd down osd.1
marked down osd.1.
# ceph osd down osd.2
marked down osd.2.
# ceph status
cluster:
id: 454d7e30-a1f5-4369-b1e5-6b9b2700054c
health: HEALTH_WARN
Too many repaired reads on 4 OSDs
2 slow ops, oldest one blocked for 1627677 sec, osd.2 has slow ops
services:
mon: 3 daemons, quorum a,b,c (age 2w)
mgr: a(active, since 2w)
mds: myfs:1 {0=myfs-b=up:active} 1 up:standby-replay
osd: 16 osds: 16 up (since 76s), 16 in (since 2w)
rgw: 1 daemon active (my.store.a)
task status:
data:
pools: 11 pools, 177 pgs
objects: 343 objects, 184 MiB
usage: 18 GiB used, 29 TiB / 29 TiB avail
pgs: 177 active+clean
io:
client: 3.5 KiB/s rd, 511 B/s wr, 4 op/s rd, 3 op/s wr
Rook/Cephを導入したらosdが沢山作られた
新規に構築したk8sクラスターにRook/Cephを導入したところ、本来4台に一つずつのBlueStore(HDD)しかないはずなのに6つのOSDが作成されてしまいました。
原因はOS導入時に使用したAutoInstallを走らせるUSBメモリーが差し込まれたままになっていた事で、ISO9660イメージだからCD-ROM扱いされて無視されるかなと思っていたのですが、システムでは/dev/sdcとして認識されていて、OSDが起動したようです。
当然、USBメモリーは回収されるため、その後は/dev/sdcそのものが存在しないことで、OSDが起動できずにエラーとなっています。
$ sudo kubectl -n rook-ceph get pod -l osd
NAME READY STATUS RESTARTS AGE
rook-ceph-osd-0-5557b5c888-lj9x8 1/1 Running 2 (16h ago) 6d15h
rook-ceph-osd-1-66bcb89669-ch5bx 1/1 Running 2 (16h ago) 6d15h
rook-ceph-osd-2-9b8b5ff5b-44kbz 1/1 Running 2 (16h ago) 6d15h
rook-ceph-osd-3-59bcb68f97-g9nl9 0/1 Init:CrashLoopBackOff 177 (24s ago) 14h
rook-ceph-osd-4-6745cf4d86-7vnht 0/1 Init:CrashLoopBackOff 192 (3m4s ago) 6d15h
rook-ceph-osd-5-f6cc674f4-6sp5q 1/1 Running 2 (16h ago) 6d15h
rook-ceph-osd-6-f776bf965-xqbrg 0/1 Init:CrashLoopBackOff 175 (3m20s ago) 14h
環境
- Rook v1.9.10 (ceph 16.2.10)
- Kubernetes v1.23.7
作業手順
今回はBlueStoreの初期化などは不要で、そもそもPGsを構成していない不要なOSDだと分かっているので、影響を受けるPVがないという前提で作業を行ないます。
公式ガイド Ceph OSD Managementと公式ガイド Ceph Configurationに従って単純に不要なOSD (ID: 3,4,6) を削除していきます。
- Operatorの停止
- ToolBoxからceph osd downの実行
- ToolBoxからceph osd out/crush remove/auth del/rmの実行
- OSDに対応するDeploymentオブジェクトの削除 (removeOSDsIfOutAndSafeToRemove: trueが設定されていない場合)
- Operatorの復帰
Operatorの停止
$ sudo kubectl -n rook-ceph scale deployment rook-ceph-operator --replicas=0
ToolBoxからceph osd downの実行
$ sudo kubectl -n rook-ceph exec -it rook-ceph-tools-7d59b6df78-tlqrb -- bash
[rook@rook-ceph-tools-7d59b6df78-tlqrb /]$ ceph osd down osd.3
osd.3 is already down.
[rook@rook-ceph-tools-7d59b6df78-tlqrb /]$ ceph osd down osd.4
osd.4 is already down.
[rook@rook-ceph-tools-7d59b6df78-tlqrb /]$ ceph osd down osd.6
osd.6 is already down
ToolBoxからceph osd out/crush remove/auth del/rmの実行
[rook@rook-ceph-tools-7d59b6df78-tlqrb /]$ ceph osd out osd.6
marked out osd.6.
[rook@rook-ceph-tools-7d59b6df78-tlqrb /]$ ceph osd out osd.4
osd.4 is already out.
[rook@rook-ceph-tools-7d59b6df78-tlqrb /]$ ceph osd out osd.3
osd.3 is already out.
[rook@rook-ceph-tools-7d59b6df78-tlqrb /]$ ceph osd crush remove osd.3
removed item id 3 name 'osd.3' from crush map
[rook@rook-ceph-tools-7d59b6df78-tlqrb /]$ ceph osd crush remove osd.4
removed item id 4 name 'osd.4' from crush map
[rook@rook-ceph-tools-7d59b6df78-tlqrb /]$ ceph osd crush remove osd.6
removed item id 6 name 'osd.6' from crush map
[rook@rook-ceph-tools-7d59b6df78-tlqrb /]$ ceph auth del osd.3
updated
[rook@rook-ceph-tools-7d59b6df78-tlqrb /]$ ceph auth del osd.4
^Pupdated
[rook@rook-ceph-tools-7d59b6df78-tlqrb /]$ ceph auth del osd.6
updated
[rook@rook-ceph-tools-7d59b6df78-tlqrb /]$ ceph osd rm osd.3
removed osd.3
[rook@rook-ceph-tools-7d59b6df78-tlqrb /]$ ceph osd rm osd.4
removed osd.4
[rook@rook-ceph-tools-7d59b6df78-tlqrb /]$ ceph osd rm osd.6
removed osd.6
[rook@rook-ceph-tools-7d59b6df78-tlqrb /]$ exit
exit
$
対応するDeploymentオブジェクトの削除
$ sudo kubectl -n rook-ceph delete deploy rook-ceph-osd-3
deployment.apps "rook-ceph-osd-3" deleted
$ sudo kubectl -n rook-ceph delete deploy rook-ceph-osd-4
deployment.apps "rook-ceph-osd-4" deleted
$ sudo kubectl -n rook-ceph delete deploy rook-ceph-osd-6
deployment.apps "rook-ceph-osd-6" deleted
Operatorの復帰
$ sudo kubectl -n rook-ceph scale deployment rook-ceph-operator --replicas=1
deployment.apps/rook-ceph-operator scaled
結果の確認
またToolBoxに入って、ceph statusの確認を行います。
cluster:
id: 8c9c83ef-4694-42b9-8cc7-cbb4a529e384
health: HEALTH_OK
services:
mon: 3 daemons, quorum a,b,c (age 17h)
mgr: a(active, since 17h), standbys: b
osd: 4 osds: 4 up (since 17h), 4 in (since 41m); 2 remapped pgs
rgw: 1 daemon active (1 hosts, 1 zones)
data:
pools: 9 pools, 113 pgs
objects: 2.92k objects, 7.1 GiB
usage: 16 GiB used, 3.6 TiB / 3.6 TiB avail
pgs: 125/8769 objects misplaced (1.425%)
111 active+clean
1 active+remapped+backfilling
1 active+remapped+backfill_wait
io:
client: 7.5 KiB/s rd, 204 KiB/s wr, 1 op/s rd, 1 op/s wr
recovery: 6.5 MiB/s, 6 objects/s
ceph osd treeの出力は次のようになっています。
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-1 3.63879 root default
-5 0.90970 host s10rx61
1 hdd 0.90970 osd.1 up 1.00000 1.00000
-9 0.90970 host s10rx62
5 hdd 0.90970 osd.5 up 1.00000 1.00000
-7 0.90970 host s10rx63
2 hdd 0.90970 osd.2 up 1.00000 1.00000
-3 0.90970 host s10rx64
0 hdd 0.90970 osd.0 up 1.00000 1.00000