前回はETCDの破損によるクラスター障害でサイトダウンしましたが、今回はなんとディスク故障によりWebサイトがサービスダウンしてしまいました。
コンテンツ
サービス障害検知からディスク故障
ファイルを読み込めない状況になって、ストレージとしての機能が停止していました。サイトが応答していない状況から、ディスク故障という原因判明までは直ぐにたどり着いたのですが、予備ディスクがなく近隣にパーツショップも無いため、楽天のツクモで注文したところ、注文後も発送連絡が全く来ない状況が続き、復旧まで何日もかかってしまいました。
ディスク故障ですが、今回のケースの場合、ディスク4個でRAID5を組んでいるうちの1個が故障という事で、データ自体は理論上失われていない状況です。
ストレージ環境の再検討
復旧作業が進めない状況に陥ってしまったため、改善しないといけないと考えていたストレージ環境について、いい機会と捉え対応する事にしました。
Kubernetesで使用している永続ストレージは、ストレージプロビジョナーとしてnfs-subdir-external-provisionerを介してNFSを利用しています。nfs-subdir-external-provisionerを採用したのは、構築当時、nfs-subdir-external-provisionerを利用したWeb文献が多く見られたためでした。
しかし英文のサイトを読んでいくと、nfs-subdir-external-provisionerは数年前からプロジェクトが停止状態の様で、バグ修正などが行われないため別のストレージプロビジョナーを利用すべきとの意見が多くあったため、今回のディスク障害を機にcsi-driver-nfsに乗り換える事にします。
また、応答速度の向上と、ディスク障害に対応すべく、NFSストレージをNVMeに変更し、それをrsyncで定期的に磁気ディスクにバックアップを取る運用に変更します。
nfs-subdir-external-provisionerからcsi-driver-nfsへの移行作業
今回は、このうちのnfs-subdir-external-provisionerからcsi-driver-nfsへのデフォルトストレージクラス設定の変更作業を以下に記載します。
1.旧ストレージクラス(nfs-subdir-external-provisioner)のデフォルトアノテーション解除
まず、nfs-subdir-external-provisioner からデフォルト指定を解除します。
kubectl patch storageclass nfs-subdir-external-provisioner \
-p '{"metadata": {"annotations": {"storageclass.kubernetes.io/is-default-class": "false"}}}'
※ストレージクラス名を別名称で指定している場合は、書き換えてください
2.新ストレージクラス(csi-driver-nfs)の作成
以下のHelmコマンドは、csi-driver-nfs でNFSサーバー 192.168.1.1 を参照するように設定し、デフォルトストレージクラスとします。
helm repo add csi-driver-nfs https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/charts
CSIVERSION=$(curl -sL https://api.github.com/repos/kubernetes-csi/csi-driver-nfs/releases | jq -r ".[0].tag_name")
helm install csi-driver-nfs csi-driver-nfs/csi-driver-nfs -n kube-system --version ${CSIVERSION} --set storageClass.create=true --set storageClass.name=storage-csi --set storageClass.parameters.server=192.168.1.1 --set storageClass.parameters.share=/export --set storageClass.mountOptions[0]="nfsvers=4.1" --set storageClass.defaultClass=true
※パラメータ(例:name、share や mountOptions)等は、実環境に合わせて適宜修正してください。
デプロイ済みのストレージは変更されません
上記はデフォルト設定を変更していますが、作業後にデプロイされるものが参照する設定です。注意しなければいけない点は、デプロイ済みのものに関しては、ストレージ設定は変更されません。
デプロイし直せば、新しい設定で作り直されますが、一旦削除できないサービスなどは、ごにょごにょPVCなどの設定をいじる必要があります。
csi-driver-nfsを使ってみての感想
実際にcsi-driver-nfsを使い始めて思った困った事は、自動生成されるフォルダ名がランダム変数のみで、リリース名などが入らない事。
nfs-subdir-external-provisionerでは、ネームスペース名+リリース名+チャート名+変数といった形のフォルダ名が自動生成されていて、見た目で判断ができるフォルダ名が採用されていたのですが、csi-driver-nfsにはその様な機能は盛り込まれてないとの事でした。
完全切替は先送り
完全切り替えを前提で作業したのですが、上記理由で、暫く共存させて利用してみる事にしました。
もう一つのディスク関連の課題
もうひとつ、今回の調査で判明した改善点は、ファイルシステムについて。
構築当時は、IBMが開発した形式というブランド名に惹かれてJFS(ジャーナル・ファイルシステム)をいうファイルシステムを採用しました。
JFSの技術的な特徴
JFS は多数の機能をサポートする近代的なファイルシステムです。以下はその一部です:
- 完全に64ビット。
- i-node の動的な容量割り当て。小さなファイルが多数存在してもファイルシステムの i-node が不足することはありません。
- 速度と効率性にふったディレクトリ構造:
- JFS は巨大なファイルのブロック割り当てにエクステントを利用します。
- 標準的な Unix のパーミッションに加えて拡張属性をサポート。
- 内部・外部ログをサポート。
- きわめてスケーラブル。最小ファイル容量から4ペタバイトまでパフォーマンスが変わらない。
- 巨大なシステムで高い性能を発揮するように設計されたアルゴリズム。
- GNU/Linux 向けにチューンされたパフォーマンス。
- トランザクション/ログを提供するように根底から設計 (アドオンではない)。
- システム喪失からの再起動は1秒以下。
- 実績のあるジャーナリングファイルシステムテクノロジ (AIX で10年以上にわたって使用)。
- 元の設計目標: パフォーマンス, 堅牢性, SMP。
- オリジナルの AIX の JFS のチームメンバーが開発・設計したファイルシステム。
- SMP ハードウェアで動作するように作られ、最低でも4コアの SMP マシンを想定してコードを最適化済み。
- (カーネル 3.7 から) TRIM をサポート。
i-nodeが枯渇する事はないという売り文句は、私には非常に魅力的です。
i-node枯渇は、以前レンタルサーバーを利用している際に経験があります。固定ページのサイトにWordPressも同居させたところ、ファイル数が超過して、i-node不足に陥り、メールすら受信できない状況になってしまいました。
世の方向性はBTRFS
しかし、世の方向性は、大企業もBTRFSというファイルシステムに向いている様で、そのうちこれに変えるべきとの認識です。
しかしファイルシステムの変更は、全てのデータを退避してから再フォーマットしなければならないというハードルがあります。このため、これは将来的に物理的にNASを作り替える時の課題にしたいと思います。