🔄

EC2起動時に自動でインスタンスストアをマウントする

2024/08/22に公開

はじめに

EC2のGPUインスタンスでローカルLLMを構築することになりました。
インスタンスストアはEC2の停止後に削除されます。
料金やI/Oのためインスタンスストアに環境構築していたのですが、このことをインスタンスの停止後に知りました笑

お金がかかるインスタンスではEC2は停止しておきたいですが、マウントからGitクローン・poetryの依存関係のインストールなど手動では時間がかかってしまうため、自動でスクリプトを実行することにしました。
(ユーザーデータでもできるそうですが、Amazon Linux2ではできないと見かけたためこの方法にしました)

手順

  1. 自動マウントスクリプトの作成
  2. スクリプトを実行するサービスの作成
  3. サービスの登録

1.自動マウントスクリプトの作成

以下のスクリプトを作成して、/home/ec2-userに配置しました。

mount_instance_store.sh
#!/bin/bash

# 変数の定義(書き換えてください)
DEVICE_NAME="/dev/nvme1n1"
MOUNT_POINT="/data"
USER_NAME="ec2-user"
SSH_KEY_PATH="~/.ssh/key-name"
OWN_NAME="github-owner-name"
REPO_NAME="github-repository-name"

# 既にファイルシステムが存在するか確認
if sudo file -s $DEVICE_NAME | grep -q 'filesystem'; then
    echo "ファイルシステムは既に存在します。スクリプトを終了します。"
    exit 0
fi

# 既にマウントされているか確認
if mountpoint -q $MOUNT_POINT; then
    echo "デバイスは既に $MOUNT_POINT にマウントされています。スクリプトを終了します。"
    exit 0
fi

# ファイルシステムの作成とマウント
sudo mkfs -t xfs $DEVICE_NAME
sudo mkdir -p $MOUNT_POINT
sudo mount $DEVICE_NAME $MOUNT_POINT
sudo chown -R $USER_NAME:$USER_NAME $MOUNT_POINT

# リポジトリのクローンと依存パッケージのインストール
eval "$(ssh-agent -s)"
ssh-add $SSH_KEY_PATH
git clone git@github.com:$ORG_NAME/$REPO_NAME.git $MOUNT_POINT/$REPO_NAME
poetry install --directory $MOUNT_POINT/$REPO_NAME

echo "スクリプトが正常に完了しました。"

ファイルシステムの作成とマウント

以下の流れとなっています。

  • ファイルシステムの作成
  • マウント先のディレクトリの作成
  • 作成したディレクトリにファイルシステムをマウント
  • 所有権の変更

AWSのユーザーガイドを参考にしました。
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/add-instance-store-volumes.html

リポジトリのクローンと依存パッケージのインストール

クローンのためのSSHキーはEC2上で作成してGitHubに登録しているものとします。
https://docs.github.com/ja/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account

また、gitやpoetryはEC2のルートデバイスにインストールしているものとします。

2.スクリプトを実行するサービスの作成

サービスとは、システムが直接起動するプロセスです。
つまり、これを書いておけば先ほどのスクリプトを自動で実行してくれます。
以下のサービスを作成して、/etc/systemd/system/に配置しました。

mount-instance-store.service
[Unit]
Description=Mount Instance Store
After=network.target

[Service]
User=ec2-user
Type=oneshot
ExecStart=/home/ec2-user/mount_instance_store.sh
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

簡単な説明です。

  • Description: サービスの説明文(任意)
  • After: このサービスが起動するタイミング
    • network.target: ネットワークサービスが起動した後に実行
  • User: 実行ユーザー
  • Type
    • oneshot: 1度だけの実行
  • ExecStart: 実行するコマンド
  • RemainAfterExit: すべてのプロセスが終了した場合でも、サービスをアクティブと見なすかどうか
  • WantedBy: どの起動プロファイルで有効になるか
    • multi-user.target: 通常のマルチユーザーモード

3.サービスの登録

サービスを有効化するコマンドを実行します。

sudo systemctl enable mount-instance-store.service

また確認のため、以下のコマンドも使用できます。

  • sudo systemctl list-unit-files --type=service: サービス一覧の確認
  • sudo systemctl start mount-instance-store.service: サービスの実行(テスト)
  • sudo systemctl status mount-instance-store.service: サービスのステータスを確認

さいごに

間違っている点やもっといい方法があると思うので、よければコメントで教えてください!

Discussion