はじめに
前回の記事では、学生が利用する共用Linuxサーバーで、ディスク容量が不足した問題について紹介しました。
VS Code Remote SSHを利用すると、接続先のLinuxにもVS Code Serverが配置されます。
学生約28人が利用する共用サーバーでは、それぞれのホームディレクトリにファイルが蓄積し、無視できない容量になっていました。
そこで、AWSのEBSボリュームを拡張し、パーティションとファイルシステムを調整して、まずは利用可能な容量を確保しました。
その後、不要なファイルの調査や整理を進めていたのですが、さらに大きな問題が発生しました。
EC2インスタンスそのものが、終了(Terminate)状態になってしまったのです。
今回は、その後の復旧作業と、GitHubに残していたものがどのように役立ったのかを記録します。
インスタンスタイプを変更しようとしたら
ディスク容量の問題とは別に、サーバーの動作が重いことも気になっていました。
複数の学生が同時に接続しているため、CPUやメモリなどのリソースにも余裕が必要です。
そこで、EC2のインスタンスタイプを変更し、サーバーの性能を上げようと考えました。
AWSマネジメントコンソールから変更を試みたところ、エラーが発生しました。
そして、その後にEC2の状態を確認すると、インスタンスが終了(Terminate)状態になっていました。
正直なところ、自分では終了操作を行った認識がありません。
インスタンスタイプを変更しようとしていたのであって、インスタンスを削除するつもりはありませんでした。
ただし、実際に何が起きたのかは、まだ確認できていません。
通常、インスタンスタイプの変更が失敗しただけで、EC2インスタンスが自動的に終了するわけではありません。
操作を誤ったのか、別の要因があったのか。現時点では断定できないため、ここでは確認できた事実だけを書いておきます。
インスタンスタイプの変更を試みた後、授業で使っていたEC2インスタンスが終了状態になっていた。
原因が何であれ、サーバーを失ったことに変わりはありません。
EC2の「停止」と「終了」は違う
AWSのEC2には、「停止(Stop)」と「終了(Terminate)」という操作があります。
停止は、インスタンスの実行を止める操作です。通常は、停止後に再び起動できます。
一方、終了はインスタンスを廃止する操作です。終了したインスタンスを、そのまま再起動することはできません。
また、EBSボリュームには、インスタンス終了時に削除するかどうかを指定する設定があります。
そのため、インスタンスを終了したからといって、すべてのEBSボリュームが必ず削除されるわけではありません。
ただし、終了時に削除される設定だったボリュームについては、別途バックアップなどがなければ復旧が難しくなります。
今回、少なくとも授業で利用していたEC2インスタンスは、そのまま再利用できない状態になりました。
そこで、新しいインスタンスを用意して、環境を再構築することにしました。
学生の成果物はどこにあるのか
サーバーが利用できなくなったとき、まず気になったのは学生が作成したプログラムです。
今回の授業では、Linux上でPythonのプログラムを作成し、実行しています。
もし成果物がEC2のホームディレクトリにしか保存されていなければ、サーバーとともに失われていた可能性があります。
しかし、授業では以前からGitHubを利用していました。
学生にはそれぞれGitHubのリポジトリを用意させ、作業内容をこまめにコミットし、プッシュするように指導していました。
そのため、GitHubに反映されていたプログラムは、EC2インスタンスとは別の場所に残っていました。
新しい環境を用意すれば、GitHubから再び取得できます。
git clone <リポジトリのURL>
このコマンドで、GitHubに保存されたリポジトリを新しい環境へ複製できます。
もちろん、GitHubにプッシュしていない変更まで戻せるわけではありません。
それでも、授業で積み重ねてきた成果物の多くを失わずに済んだことは、大きな救いでした。
学生アカウントも作り直す必要があった
ところが、サーバーの復旧はプログラムを戻すだけでは終わりません。
共用Linuxサーバーでは、学生それぞれにユーザーアカウントを作成していました。
新しいEC2インスタンスには、以前の学生アカウントは存在しません。
ユーザー名やホームディレクトリ、SSHで接続するための環境などを、もう一度用意する必要があります。
約28人分のアカウントを手作業で作り直すのは、なかなか大変です。
しかし、ここでもGitHubが役立ちました。
アカウント作成用のシェルスクリプトが残っていた
学生アカウントの作成には、以前からシェルスクリプトを利用していました。
そして、そのスクリプト群も、自分のGitHubリポジトリに保存していました。
つまり、EC2インスタンスは失われても、アカウントを作成するためのプログラムは残っていたのです。
新しいサーバーで必要な設定を行い、保存していたスクリプトを利用して学生アカウントを再作成しました。
今回、GitHubには二種類の重要なものが残っていました。
- 学生のGitHubリポジトリ:授業で作成したプログラムなどの成果物
- 教員のGitHubリポジトリ:学生アカウントを作成するためのシェルスクリプト群
前者は学習成果を守り、後者は学習環境の再構築を助けてくれました。
GitHubを使っていたのは、単にファイルを保存するためだけではありません。
プログラムをどのマシンでも利用できるようにすること。作業の履歴を残すこと。環境を変えても開発を続けられること。
そうした目的で取り入れていた仕組みが、今回のトラブルで役立ちました。
GitHubはバックアップなのか
今回の経験から「GitHubに保存しておけば安心」と言いたくなります。
しかし、少し注意が必要です。
GitHubに保存されるのは、基本的にGitで管理し、リモートリポジトリへプッシュした内容です。
Linuxのユーザーアカウントそのものや、OSの設定、インストールしたパッケージ、SSHの設定などが自動的に保存されるわけではありません。
また、コミットしただけでプッシュしていなかった変更も、失われたサーバーにしか存在しなければ復元できません。
今回は、必要な成果物とスクリプトがGitHubに残っていたから、環境を再構築できました。
これは、サーバー全体をバックアップしていたこととは違います。
本格的に復旧性を高めるなら、EBSスナップショットやAMI、設定のコード化なども考える必要があります。
環境をコードで再現するという考え方
今回、学生アカウントを作成するスクリプトが残っていたことには、もう一つ意味があると思います。
それは、環境構築の手順をコードとして残していたということです。
もし学生アカウントをすべて手作業で作成していたら、同じ作業をもう一度繰り返す必要がありました。
しかし、シェルスクリプトがあれば、処理を再実行できます。
これは、Infrastructure as Code(IaC)にも通じる考え方です。
もちろん、今回のEC2環境全体をIaCで管理していたわけではありません。
ネットワークやEC2インスタンス、ストレージの構成まで自動的に再現できたわけではないからです。
それでも、環境構築の一部をコード化しておいたことで、復旧の負担を減らすことができました。
一度行った作業を、もう一度実行できる形で残しておく。
これは、日頃の授業でも大切にしたい考え方です。
学生にGitHubを使わせる理由
授業では、学生にGitHubへのコミットとプッシュを習慣づけるようにしています。
学生にとっては、少し面倒な作業かもしれません。
手元のファイルが保存できていれば、わざわざGitHubにプッシュする必要はないようにも感じるでしょう。
しかし、今回のように作業環境そのものが失われることがあります。
PCが故障するかもしれませんし、サーバーが使えなくなるかもしれません。
そのとき、成果物が別の場所に残っていれば、作業を再開できます。
また、GitHubには変更履歴が残ります。
完成したプログラムだけでなく、どのように修正してきたのかも確認できます。
私が学生にGitHubを使わせたい理由は、提出物を管理するためだけではありません。
自分の成果物を自分で管理し、どの環境でも開発を続けられるようになってほしいからです。
今回、その必要性を教員自身が改めて実感することになりました。
障害を防ぐことと、障害から復旧すること
今回の経験を振り返ると、二つの課題が見えてきます。
一つは、障害を起こさないための管理です。
ディスク容量を定期的に確認すること。不要なファイルを整理すること。AWSの操作を慎重に行うこと。
もう一つは、障害が発生した場合の復旧です。
成果物を別の場所に保存しておくこと。環境構築の手順を残しておくこと。必要なら新しい環境を作り直せるようにすること。
どちらも大切ですが、意味は異なります。
障害を完全になくすことは難しいものです。
だからこそ、障害が発生したときに、どこまで元の状態に戻せるのかを考えておく必要があります。
今回、EC2インスタンスは失いました。
しかし、学生の成果物と環境構築用のスクリプトが残っていたことで、授業を継続するための環境を再構築できました。
まとめ ― サーバーは失っても、学びは残せる
今回のトラブルは、VS Code Remote SSHによるディスク容量不足から始まりました。
EBSの容量を拡張し、不要ファイルを調査しているうちに、今度はEC2インスタンスそのものを失うことになりました。
何が原因で終了状態になったのかは、まだ確認できていません。
ただ、そこから得た学びはあります。
学生の成果物をGitHubに保存していたこと。
学生アカウントを作成するシェルスクリプトをGitHubに残していたこと。
これらが、環境の再構築に役立ちました。
今回の経験を「GitHubを使っていたから大丈夫だった」という成功談だけで終わらせるつもりはありません。
失われた環境を完全に再現できたわけではありませんし、まだ改善できる部分もあります。
それでも、普段から作業の履歴や再実行可能な手順を残しておくことの価値を、身をもって経験しました。
サーバーは失われることがある。しかし、そこで積み重ねた成果や、再び始めるための手順まで失う必要はない。
これもまた、AITRetry Labに残しておきたい一つのRetryです。


コメント