54
56

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Auto Scaling運用時のサーバ自動設定について

Last updated at Posted at 2013-12-08

Auto Scalingを実運用していく上で苦労した(している)部分の話であり, 手探りで設定していくうち個人的にハマった部分を共有したい(あわよくばもっとうまくやっている人の話も聞きたい)という動機で書かれた記事です.

そもそもAuto Scalingを設定するためには,

  • Launch ConfigやAuto Scaling Groupなど複数の新しい概念を学習しつつ, それらを組み合わせなくてはならない
  • まだブラウザのManagement Consoleから設定できない

等のハードルがあり, 他のAWSサービスと比べると, 初めて設定する時はけっこう手間取りました.
とはいえ情報が無くはないので, なんとかAuto Scalingが動き始めたというところから話を始めます.

運用時に解決する必要のある課題

標準的なAuto Scalingを設定したあと, 実際に動かすまでには以下の3点に対応する必要があります.

    1. インスタンス起動時にソースコードを最新にする
    • AMIから起動されるサーバは, AMI作成時点のソースコードを持ち続けている. そのまま公開されると古いコードがユーザの目に触れてしまうので, インスタンス起動時にGitレポジトリから最新のmasterブランチを取得して更新して欲しい.
    1. インスタンス起動時にミドルウェアの設定を稼働中サーバと揃える
    • 「アプリ稼働に必要なライブラリが追加された」「nginxの設定を変更した」等, 稼働中のサーバで更新された設定は, 自動的に起動するインスタンスにも反映したい.
    1. 上記のセットアップが完了するまでELBからアクセスを振らない
    • Auto Scalingは起動したインスタンスをAuto Scaling Groupで定義したELBに接続する. ネットワーク不調等で上記1,2の実行に時間がかかってしまうと, 不完全な状態でサーバがユーザに公開されてしまうという可能性がある. ので, これをHealthCheckで回避する.

なお今回の話は, LinuxのアプリケーションサーバをAuto Scalingで増やす, 以下の様な構成を想定しています(紫丸が上記1,2,3に対応).

as.png

大方針としては,

これら1,2,3への対応をすべてChefレシピ中に含めて, AMIからのインスタンス起動時にchef-soloを走らせます.

現在のところこの「インスタンス起動時」のトリガーとして,

Linuxのinitシステム

を使っています(正確に何と呼べばいいのか...). 他の案として「Launch Configのuser_dataとしてスクリプトを流し込む」「CloudInitを使う」等の方法も考え試していたのですが, 一番手に馴染んで信頼性のある(?)方法に落ち着きました.

init

使用サーバはUbuntuなので, 以下の様なUpstart用のinitファイルを/etc/init/setup-auto-scaling.confに置いています. Fedoraを使っていた時は/etc/init.d/以下でした.

/etc/init/setup-auto-scaling.conf
# setup-auto-scaling - run chef-solo
#
# This task run chef-solo for app server.

description     "Run chef-solo for app server"

start on runlevel [2345] and local-filesystems and net-device-up IFACE!=lo

task

env HOME=/root
env LC_ALL="en_US.UTF-8"
chdir /tmp
post-start script
    git clone git@github.com:myaccount/chef-repo.git /tmp/chef-repo \
        >> /tmp/run-chef.log 2>&1
    cd /tmp/chef-repo && /usr/local/rvm/bin/bootup_berks install \
        >> /tmp/run-chef.log 2>&1
    rolebysg=`curl http://169.254.169.254/latest/meta-data/security-groups`
    chef-solo -c /tmp/chef-repo/solo.rb -j /tmp/chef-repo/roles/$rolebysg.json \
        >> /tmp/run-chef.log 2>&1
end script

前提としてサーバのrootがchefを実行可能な状態でAMI化しておく必要があります. 上記スクリプトでやっていることは以下の通り.

  • GitHubから最新のchefレポジトリをclone
  • 依存cookbookを取得するためBerkshelfを実行
  • AWSのHTTP apiを使ってSecurityGroupを取得
  • 予めSecurityGroup名で配置しておいたroleファイルを指定しchef-solo実行

Security Groupの違い = 役割の違い, とみなして困るケースはほぼ無いので, こうしています.

chef

自前で管理している最新のcookbookを使ってchefを実行するということは, 前述の課題1,2,3のうち1と2はほぼ片付きます. 例えば「(1): インスタンス起動時にソースコードを最新にする」に対応する箇所をrecipeから抜き出すと, こんな感じになると思います.

sync-code.rb
git "app-repository" do
  repository "git@github.com:myaccount/app.git"
  reference 'master'
  destination "/path/to/nginx/root/#{repo}/current"
  action :sync
end

1年半前にAuto Scalingを設定した時はchefを使っていなかったため, nginxの設定を変更するとAMIも作りなおすという悲しい運用だったのですが, 今はchef任せです. チームで「サーバ設定を変更するときはchefレポジトリにcommitすること」というルールを共有しておけばサーバ間の設定漏れがなくなるため実にありがたく, chef様様です.

health check

最後に「(3): 上記のセットアップが完了するまでELBからアクセスを振らない」に関して, 採用している解決策は

「ELBがチェックするHealth CheckファイルをGitレポジトリからignoreしておき, chef-solo実行完了時にHealth Checkファイルをtouchする」

というものです. こうしておけば, chefの実行が終わる前あるいは「GitHubがたまたま落ちてた」などでchefの実行が途中でコケた時に不完全な状態のサーバがELBからアクセスを受ける心配はなくなります.

まずはAWSのELB設定で(例えば)/ping.htmlをチェックするように設定して,

2013-12-09 at 2.37 AM.png

アプリケーションのGitレポジトリからping.htmlをignoreしておきます.

.gitignore
+ ping.html

これで, Gitレポジトリから最新ソースコードを落としてきた段階ではping.htmlが存在しないのでELBからのHealthCheckに失敗し, アクセスが割り振られることはありません.
(ping.htmlを削除した上でAMIを作成する必要があるので注意)

その上でchef recipeの一番最後に,

cookbooks/hoge/recipes/touch-healthcheck.rb
template 'ping.html' do
  path '/path/to/nginx/root/ping.html'
  source 'ping.html'
  mode 0775
end

このようなtemplateブロックを書いておけば, chef-soloの実行が完了した後にのみELBからのアクセスを受けさせることができます.

いじょ

最適解である自信はないのですが, 以上のようにしてAuto Scalingを運用しています. 何かの助けになれば幸いです. また, もっと良い方法をご存じの方は教えてください.

54
56
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
54
56

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?