はじめに
以下の記事を以前作成しました。
これで作成したうえで、実際のISUCONのようにEC2上に3台のサーバを使ってISUCONの練習をする際、またはISUCON本番時に、デプロイを複数台同時に可能にするスクリプトを作成しました。この記事でのスクリプトはGo言語のみを対象にしています。
環境
- AWS EC2
- Ubuntu 18.04.5 LTS
サンプルのGitHubレポジトリ
前提
サーバにいるisuconユーザーはsshで他サーバへアクセスすることができる。
EC2上のisuconユーザー用の鍵ペアを作成しauthorized_keys
ファイルを持つことでパスワードなしで互いのサーバへisuconユーザーでSSHアクセスできるようにします。
手動で作成することも可能ですが、筆者は公式のAnsibleとPackerを修正しAMIへビルドする改修をしました。本記事の最後に「公式AnsibleとPackerを書き換える」の項目で記載しています。
/etc/hosts
を修正しisu2, isu3の名前を作成する。
スクリプト内でisu2
,isu3
というホスト名にしており環境ごとに1台目サーバの/etc/hosts
ファイルへ設定する必要があります。
こちらもAnsibleかTerraformでの構築時に自動化されることが理想ですが現状(2021年7月4日)では筆者の方ではできていません。
他サーバ2台のプライベートIPを指定します。
127.0.0.1 localhost
+ 10.1.0.158 isu2
+ 10.1.0.181 isu3
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
デプロイスクリプト
以下はISUCON10予選のisuumoアプリケーションを対象にしており、isuumo
の部分を練習する過去問に合わせて変更する必要があります。
本来のISUCONではデプロイスクリプトではNginxやMySQLの設定ファイルも同時にデプロイしたり、ログをローテーションさせたりするチームが多いですが、この記事ではGoのアプリケーションのデプロイにフォーカスします。そのような処理もするようにデプロイスクリプトを各々がカスタマイズすることになると思います。
ディレクトリ構成
├── deploy-with-remote.sh
├── deploy.sh
└── webapp
├── go
├── ruby
....
はじめに1台目のサーバへデプロイスクリプトを含むレポジトリをcloneさせます。
sudo su isucon
cd ~
git clone https://github.com/momotaro98/isucon10-q.git # 自身のISUCONレポジトリを指定すること
直接実行するスクリプトが以下です。
他サーバへはsshコマンドを利用することで同様にdeploy.shスクリプトを流すようにしています。
#!/bin/bash -eu
# 【変更する必要のある箇所】
repo=https://github.com/momotaro98/isucon10-q.git # 自身のISUCONレポジトリ
repo_path=/home/isucon/isucon10-q # Gitレポジトリへのパス
# 自身のサーバへデプロイ
echo 'running deploy to this server'
git -C ${repo_path} pull origin master
${repo_path}/deploy.sh
# 他2台のサーバへデプロイ
echo 'running deploy to other servers, isu2 and isu3'
echo ''
echo '[NOTE] Before expecting this process to work well, you need to prepare /etc/hosts for alias isu2, isu3'
echo ''
for srv in "isu2" "isu3"
do
echo 'starting for '${srv}
ssh isucon@${srv} git -C ${repo_path} pull origin master || ssh isucon@${srv} git clone ${repo}
ssh isucon@${srv} ${repo_path}/deploy.sh
echo 'finished for '${srv}
done
deploy-with-remote.sh
のスクリプト内で実行しているビルド→デプロイ用のスクリプトが以下になります。
#!/bin/bash
# スクリプトファイル置き場を起点する
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
echo 'Restarting Go...'
cd $DIR/webapp/go/
# Goをビルド
/home/isucon/local/go/bin/go build -o isuumo # Goコマンドがあるバスを指定する必要がある
# Webアプリのサービスを再起動する
sudo systemctl stop isuumo.go.service
cp isuumo /home/isucon/isuumo/webapp/go/
cd $DIR
sudo systemctl restart isuumo.go.service
echo 'Restarted!'
実行したときの様子
1台目のサーバにログインし実行します。
$ ./deploy-with-remote.sh
running deploy to this server
From https://github.com/momotaro98/isucon10-q
* branch master -> FETCH_HEAD
Already up to date.
Restarting Go...
Restarted!
running deploy to other servers, isu2 and isu3
[NOTE] Before expecting this process to work well, you need to prepare /etc/hosts for alias isu2, isu3
starting for isu2
From https://github.com/momotaro98/isucon10-q
* branch master -> FETCH_HEAD
Already up to date.
Restarting Go...
Restarted!
finished for isu2
starting for isu3
From https://github.com/momotaro98/isucon10-q
* branch master -> FETCH_HEAD
Already up to date.
Restarting Go...
Restarted!
finished for isu3
それぞれのサーバでソースコードがビルドされサービスが再開できることが確認できました。
公式AnsibleとPackerを書き換える
isuconユーザーに鍵ペアを生成させるため、ISUCON公式Ansibleファイルを改修し、matsuuさんが作成されたPackerでAMIをビルドするスクリプト郡のレポジトリをフォークし修正することで対応しました。
以下は変更分のコミットのURLです。
Ansible変更分
Packer変更分