2024年4月18日(木)22:15(JST)より、sksat の運用する Kubernetes クラスタのひとつ(以後 “Kubernetes クラスタ”)に障害が発生しました。
これにより、パソコニスタンの主要サービスのひとつである pasokey が 140分間利用できませんでした。
影響を受けたもの #
sksat が運用するいくつかのサービスは、今回障害が発生した Kuberenetes クラスタ上で運用されています。
パソコニスタンに関係のあるものとしては、以下のサービスに影響がありました。
- pasokey
- misskey.sksat.run: パソコニスタンとは直接の関連はありませんが、pasokey の staging 環境として運用されています
タイムライン #
参照されるタイムスタンプはすべて日本標準時(JST)です。
時間 | 説明 |
---|---|
2024-04-18 22:36 JST | インシデントを認知 |
2024-04-18 22:38 JST | スマホのブラウザで開き、Cloudflare Tunnel の接続断ではない未知のインシデントであることを確認 |
2024-04-18 23:10 JST | 油淋鶏定食を食べ終わる |
2024-04-18 23:12 JST | 調査・復旧の優先順位を決める |
2024-04-18 23:15 JST | pasokey だけでなく staging 環境でも同様のインシデントが発生していることを確認 |
2024-04-18 23:16 JST | 不自由な計算機しか手元になく、VPN 経由での ArgoCD へのアクセスができないことに悪態を付く |
2024-04-18 23:18 JST | Misskey CLI が一応開けたのでテスト投稿を試みる |
2024-04-18 23:21 JST | スマホからでも Kubernetes Node に SSH できる可能性に思い至るが、適切な秘密鍵が手元に無いことに気付く |
2024-04-18 23:25 JST | 自宅マシンへの任意コード実行によるエスカレーションを考えるが、インシデントの規模と帰宅時間から割に合わないなと思い直す |
2024-04-18 23:36 JST | 帰宅 |
2024-04-18 23:38 JST | 本格的なインシデント調査開始 |
2024-04-18 23:39 JST | ArgoCD にアクセスできないことを確認 |
2024-04-18 23:41 JST | Kubernetes コントロールプレーンノードの IP アドレスが変化していることに気付く |
2024-04-18 23:44 JST | kubectl で pasokey の Misskey プロセスのログにエラーを確認 |
2024-04-18 23:45 JST | kubectl で pasokey および staging 環境の cloudflred のログを確認 |
2024-04-18 23:52 JST | 念のため Cloudflare の Dashboard から Cloudflare Tunnel が healthy であることを確認 |
2024-04-18 23:54 JST | 念のため Cloudflare System Status が Operational であることを確認 |
2024-04-18 23:56 JST | 他の fediverse インスタンスから状況を確認 |
2024-04-18 23:58 JST | Kubernetes コントロールプレーンノードの IP アドレス再固定を試みるが、LAN への再接続に失敗し、SSH 不能になる |
2024-04-19 00:02 JST | キーボードとモニタを引っ張り出して Kubernetes コントロールプレーンに接続 |
2024-04-19 00:05 JST | Kubernetes コントロールプレーンにて Too many open files エラーを確認 |
2024-04-19 00:09 JST | ファイルディスクリプタ数上限を再設定し、Kubernetes コントロールプレーンノードを LAN に再接続 |
2024-04-19 00:10 JST | ArgoCD の復旧を確認 |
2024-04-19 00:13 JST | Kubernetes クラスタの一部プロセスがサービスに関わらず CrashLoopBackOff していることを確認 |
2024-04-19 00:16 JST | Kubernetes コントロールプレーンノードの再起動を試みる |
2024-04-19 00:18 JST | Kubernetes コントロールプレーンノードを強制再起動 |
2024-04-19 00:21 JST | FS-Cache Duplicate cookie detected エラーを確認 |
2024-04-19 00:21 JST | ArgoCD にアクセスできず、NFS の CSI Driver の pod が CrashLoopBackOff していることを確認 |
2024-04-19 00:25 JST | NFS ファイルサーバの応答が無いことを確認 |
2024-04-19 00:31 JST | また苦労して NFS ファイルサーバにモニタとキーボードを接続するが、まったく反応が無いことを確認し、強制再起動 |
2024-04-19 00:33 JST | ArgoCD の復旧を確認 |
2024-04-19 00:34 JST | pasokey の復旧を確認 |
分析 #
現在、各種ログを精査しています。
今のところ、NFS ファイルサーバに 2024-04-18 22:15:01 JST~2024-04-18 22:15:40 JST の間にハングを起こす事象があったことが明らかになっています。
教訓と改善策 #
今回のインシデントは、pasokey にとって運用開始から最大規模となる2時間以上の障害を発生させました。趣味で運用しているので SLA などは一切設定しておらず、意図的なメンテナンスで長期間のサービスダウンやデータロストが発生する可能性は常日頃からあるものの、意図しないタイミングでの障害は非常にムカつきます。可能な限りインシデントの発生を抑制し、発生したとしてもインシデントレスポンスを学ぶためのダシとして最大限活用しなければなりません。
直接の原因となった NFS ファイルサーバのハングと Kubernetes ノードのファイルディスクリプタ数上限については、より詳細な調査が必要です。しかし、今回のインシデントから学び、これからやるべきことは他にもたくさんあります。
pasokey が Misskey として動作していることまで含めた外形監視 #
現在、pasokey は README にもあるように、Better Stack と Uptime Robot による外形監視を行っています。これらは手軽な監視には非常に便利なツールであり、実際にこれまでの pasokey の障害としてよくある Cloudflare Tunnel の接続断の検知にはとても役立ってきました。しかし、今回の障害のように、Misskey がサーバとしては動作しており、Cloudflare Tunnel の接続も問題は無いものの内部的な問題が発生しているようなケースにおいては、必ずしも適切な監視たりえません。これにより、今回の障害を認知するまでに時間がかかりました。そこで、Misskey という実際のサービスのドメインまで含めた正常性確認を伴う外形監視を考えています。
NFS ファイルサーバの監視とアラート #
今回のインシデントにおいて、調査開始からサービス復旧までに時間がかかった最大の要因は、NFS ファイルサーバのハングという主要因の認識が遅れたことです。NFS ファイルサーバの監視が適切に行われ、アラートが上がっていれば、調査・復旧作業の優先順位をもっと適切に設定できたでしょう。
また、この監視系は Kubernetes クラスタ本体とは別個に構築する必要があることに注意が必要です。船が沈んでいることを水の中から喚いてもその声は届きません。このような問題に対処するため、物理的にも論理的にも別の場所で動作するプラットフォームが求められています。幸いにしてようやくこのためのプラットフォームはつい先日(1年以上に渡る地団太を踏んだ後)構築を順次開始しているため、まあなんとかなるでしょう。
各サーバへの物理的アクセス #
今回のインシデント対応では、各サーバに対するネットワークアクセスが失われるなど、ブラウザと SSH だけでは完結しない対応が必要になる場面がしばしば存在しました。しかし、これらのサーバは sksat の自宅のメタルラック内に乱雑かつ多数配置されており、適切なコンソールや画面出力への物理的アクセスは至難の技となっています。このような問題を解決するため、PiKVM の導入によるコンソール・画面出力のネットワーク化や、メタルラック内のサーバ・ケーブリングの再配置を検討しています。
ログ基盤 #
今回のインシデント対応および事後調査では、各サーバやプロセスのログを横断的に調査しました。これらの調査にあたって、そもそも適切な範囲のログを抜き出すためにスクリプトを書いたり、どこに適切なログファイルがあるかを調べ直したりする時間はよい経験にはなったもののあまり必要な時間であったとは言い難いです。そのため、あらゆるログを収集し検索可能にするログ基盤が求められています。また、このログ基盤についても、監視系と同様本体の Kubernetes クラスタとは別の場所で運用すべきでしょう。
まとめ #
このようなインシデントを起こしてしまったことに別に深くお詫びしたりはしないのですが、status monitor の緑色が減り、睡眠時間が減ったことを悔しく思っております。正直 pasokey の運用をそこまでちゃんとする理由があるわけではないのですが、趣味で運用するサービスのインフラストラクチャをオーバーエンジニアリングすることに非常に関心があり、耐障害性は中でも面白さのあるトピックです。
フォローアップすべきというわけでもないけれど結構したいことはたくさんあり、やるべきことの合間や特にそうでない時にちまちまと取り組んでいます。