読者です 読者をやめる 読者になる 読者になる

GeekFactory

int128.hatenablog.com

今日から始めるサーバ構築の省力化

インフラ ruby

SSHクライアントたくさん並べてペーストしまくるのが許されるのは小学生までだよね

と言ってみたかっただけです。こんにちは。

Capistranoでサーバ構築を省力化する方法を紹介します。サーバ構築の自動化といえばChefやPuppetが有名ですが、CapistranoはサーバにSSH接続さえできれば利用できるメリットがあります。データセンタに持ち込むノートPCにCapistranoを仕込んでおけば便利なツールになるし、短期間に検証用のサーバを構築する場合も有用なツールになるでしょう。Capistranoはデプロイツールとして使われることが多いですが、サーバ構築にも有用です。

CapistranoRubyで書かれたツールで、複数のサーバにSSH接続してコマンドを実行できます。同様のツールとしてexpectがありますが、CapistranoスクリプトRubyの内部DSLなので書きやすく拡張性があります。標準ではRailsのデプロイタスクが用意されており、自分でタスク(レシピ)を簡単に追加できます。

Capistranoのインストール

LinuxMac OS XCapistranoを使う方が何かと便利ですが、Windowsでも使えます。ロクな環境がなくても大丈夫です。

必要なもの。

RailsInstallerをインストールしたらスタートメニューからRuby and Railsコマンドプロンプトを開き、以下を実行します。

rem プロキシがある場合のみ↓
set http_proxy=http://localhost:9090/
gem install capistrano

これで完了です。

管理対象サーバの準備

CapistranoSSH接続するユーザを作成します。

sudo useradd -r -m -g users -G users,wheel capistrano
echo 'capistrano:xxxxxxxx' | sudo chpasswd

もしくは、普段利用している一般ユーザでも構いません。

  • sudoが使えるようにしておきましょう。wheelに入れるなど。
  • パスワード認証の場合はCapistranoのレシピに平文パスワードを書くことになります。
  • Windows上のCapistranoで公開鍵認証が使えるかどうか分かりません。
  • 変なレシピを書いて失敗した時に被害を最小限に留められるよう、一般ユーザをおすすめします。
  • サーバ間でパスフレーズ無し公開鍵認証できるようにしておくと、scpが使えるようになって便利です。

ユーザができたら簡単なレシピを実行してみます。以下の内容をCapfileという名前で保存します。

role :server, '172.20.10.1', '172.20.10.2', '172.20.10.3', '172.20.10.4', '172.20.10.5'
set :user, 'capistrano'
set :password, 'xxxxxxxx'

task :show_uname, :roles => :server do
  run "uname -a"
end

基本的にはrunの後にコマンドを書くだけで各サーバで実行してくれます。

コマンドプロンプトで以下を実行してみましょう。各サーバのカーネルバージョンが表示されたら成功です。

cap show_uname

最近使ったレシピ

# sshの実行時にTTYが見つからないエラーを回避する
default_run_options[:pty] = true

role :server, '172.20.10.1', '172.20.10.2', '172.20.10.3', '172.20.10.4', '172.20.10.5'

set :user, 'capistrano'
set :password, 'xxxxxxxx'

# ユーザを作成して初期パスワードを設定する
task :create_initial_users, :roles => :server do
  run "sudo useradd -m -g users -G users,wheel hoge"
  run "sudo useradd -m -g users -G users,wheel hage"
  run 'echo -e "hoge:hoge\n
hage:hage" | sudo chpasswd'
end

# 公開鍵認証を有効にする
task :mkdir_root_ssh, :roles => :server do
  run 'sudo chmod 700 /root/.ssh'
  run 'sudo sh -c "cd /root/.ssh && ln -s id_rsa.pub authorized_keys"'
end

# ローカルディスクにコピーしたyumリポジトリを使う
# (インターネットに接続できない環境とか)
task :fix_yum_repos, :roles => :server do
  run 'sudo scp -p 172.20.10.1:/etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/'
  run 'sudo scp -p 172.20.10.1:/etc/yum.repos.d/CentOS-LocalMedia.repo /etc/yum.repos.d/'
  run 'sudo yum update'
end

# SELinuxを無効化する
task :disable_selinux, :roles => :server do
  run 'sudo scp -p 172.20.10.1:/etc/sysconfig/selinux /etc/sysconfig/'
  run 'sudo setenforce 0'
  run 'sudo getenforce'
end

# iptablesを無効化する
task :disable_iptables, :roles => :server do
  run 'sudo chkconfig iptables off'
  run 'sudo chkconfig ip6tables off'
end

上記では設定ファイルをばらまく時にscpを使っていますが、本当はSCMで管理する方が望ましいでしょう。まあ数ヶ月しか使わないサーバ*1なら前者で十分ですし、環境整備にどこまで時間を投資できるかに依存する話ですね。

現場には不毛な作業が溢れているかもしれません。単純作業はなるべく自動化して、空いた時間でブクマ三昧な日々を送りましょう勉強しましょう。単純作業のために人件費を使うよりはいいと思います。

*1:短期間に多くのサーバが必要になるならEC2を使うべきと思うけど、そうはいかないんだよね。不思議。