Oracle Cloud Free TierでSSHが繋がらなくなった時、最短で復旧する方法

技術

はじめに

OCIのFree Tierで動かしていたWEBサービスが、ある日突然ダウンした。
監視アラートが鳴り、サービスが応答していないことに気づく。

まずは落ち着いてSSH接続。
この時点ではまだ普通にログインできた。
プロセスを確認すると、確かにWEBサービスが落ちている。
原因は特定できないが、再起動すれば一旦は復旧しそうな状態だった。

実際、サービスを再起動すると問題なく立ち上がり、外部からのアクセスも戻った。
「まあ一時的なものだろう」
この時点では、正直そこまで深刻には考えていなかった。


二度目のダウン、そして分岐点

しかし、しばらくして再びWEBサービスが停止する。
今度は少し嫌な予感がした。

再度SSHで確認しようとしたが、挙動がやや不安定に感じたため、
念のためOCIの管理コンソールからインスタンス自体を再起動することにした。

OCI上ではインスタンスは問題なく再起動したように見える。
ステータスも「RUNNING」。

だが、ここから状況が一変する。

SSH接続ができない。
正確には「拒否」ではなく、タイムアウト
つまり、どこかで通信が止められている。


「動いているように見える死体」

Security List や NSG を確認する。
22番ポートは開いている。
Public IP も変わっていない。
ローカル環境の問題でもない。

それでもSSHは繋がらない。

OCIでは、この状態が一番厄介だ。
管理画面上はすべて正常に見えるのに、実態は壊れている。


GRUBにも入れない

次に考えたのは、GRUB経由での確認だった。
だが、OCI環境では再起動時にGRUBメニューを確実に捕まえるのが難しい。
ローカルや他のクラウドの感覚でいると、ここで一度つまずく。

結局、GRUBには入れなかった。


シリアルコンソールという「理論上の救済策」

OCIにはシリアルコンソールがある。
Instance Console Connection を使えば、OSレベルでの操作が可能……
のはずだった。

しかしここで、完全に想定外だった事実に直面する。

SSH鍵前提で運用していたため、
ログインユーザにパスワードを設定していなかった。

つまり、シリアルコンソールに入れてもログインできない。

この瞬間、
「あ、これは長期戦になるな」
と腹を括ることになった。


レスキューインスタンスという最終手段

仕方なく、レスキュー用のインスタンスを新規に立ち上げる。
問題のインスタンスからBOOTボリュームをデタッチし、
レスキュー用インスタンスにアタッチ。

BOOTボリュームをマウントし、chroot で環境に入る。
そこでユーザにパスワードを設定し、
再びBOOTボリュームを元のインスタンスに戻す。

手順としては、教科書どおりだ。


内部から見ると「問題なし」

インスタンスを起動し直し、
シリアルコンソールからログインすることに成功。

sshd は起動している。
設定ファイルもおかしくない。
firewall も問題なし。

内部から見れば、完全に正常。

だが、外部からのSSHは相変わらずタイムアウトする。

ここで、完全に詰んだ。


原因究明をやめる決断

正直、この時点でやれることはほぼ出尽くしていた。
ネットワーク設定も、OS設定も、確認できる範囲ではすべて問題ない。

そしてOCIでは、
「なぜ外部SSHだけが死ぬのか」を確実に突き止める手段がない。

ここでようやく、判断を切り替えた。


インスタンス再作成という現実解

新しいインスタンスを作成し、
問題のBOOTボリュームを再利用して起動。

結果はあっけない。

即、復旧。


結論

OCI Free Tierにおいては、
SSHトラブルの原因を徹底的に追うことが、
必ずしも最適解ではない。

内部から正常に見えても、
外部通信だけが壊れるケースが存在する。
そして、それをユーザ側で完全に可視化する手段は用意されていない。

OCIは無料だが、
SSHが死んだ時の復旧コストは、決して無料ではない。


教訓

  • SSHが死ぬ前提で設計する
  • インスタンスは捨てられるものとして扱う
  • BOOTボリューム再利用を前提にする
  • データと構成は必ず分離する
  • 直すより、作り直す勇気を持つ

コメント

タイトルとURLをコピーしました