hidemium's blog

日々学んだことをアウトプットする。

Dockerのインストールと動作確認

VMwareVirtualBoxなどのハイパーバイザ型とは異なり、起動が早く軽い仮想サーバが使えるコンテナ型の仮想化ソフトウェアのDockerについてインストールしてみました。

構成

Ubuntu 12.04 : Docker をインストール
※上記のサーバはVMware ESXi 5.1上で動作しています。

インストール

公式サイトにある手順を参考にDockerをインストールします。

まずは依存関係のあるパッケージをインストールし、サーバを再起動します。
他のサイトも参考にパッケージは追加しています。

$ sudo apt-get update
$ sudo apt-get dist-upgrade
$ sudo apt-get install ssh git build-essential libssl-dev
$ sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring
$ sudo reboot

Dockerをインストールします。

$ curl -s https://get.docker.io/ubuntu/ | sudo sh

※warningが出た場合はlxc-dockerをインストールしてくれと書いてありましたが、上記でlxc-dockerも合わせてインストールされるようです。

動作確認

まず、dockerでコンテナ(仮想サーバ)を起動してログインしてみます。
以下の場合、イメージ名がubuntuのコンテナを起動後、bashを実行し、ログインしています。

  • iオプションはインタラクティブモードでの起動を示しています。
  • tオプションは仮想端末ttyの割り当てを示しています。
$ sudo docker run -i -t ubuntu /bin/bash
$ root@11ab5172a0ec:/# uname -a
Linux 11ab5172a0ec 3.11.0-15-generic #25~precise1-Ubuntu SMP Thu Jan 30 17:39:31 UTC 2014 
$ root@11ab5172a0ec:/# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04 LTS"
$ exit

コンテナにログイン後、サーバのバージョンを確認してみましたが、Ubuntu14.04が起動していることが分かります。

次に、コンテナの一覧を確認します。
先ほど起動したコンテナが表示されていることが分かります。

$ sudo docker ps -a
CONTAINER ID        IMAGE                COMMAND                CREATED             STATUS                      PORTS                                          NAMES
11ab5172a0ec        ubuntu:14.04         /bin/bash              58 minutes ago      Exited (0) 56 minutes ago                                                  condescending_thompson

上記のコンテナからログオフし、再度コンテナを起動すると、別のコンテナとして表示されます。
コンテナの変更を保存するため、以下のコマンドを実行します。

$ sudo docker commit <コンテナID> <イメージ名> #コンテナIDはdocker psで表示された11ab5172a0ecが対応します。

Gitと似ていますが、上記のコマンドを実行することで、コンテナをイメージに変換することができます。

よく使うコマンド

dockerでよく使うコマンドについてまとめてみました。

$ sudo docker ps -a #コンテナの一覧を表示
$ sudo docker rm <コンテナID> #コンテナの削除
$ sudo docker images #イメージの一覧を表示
$ sudo docker rmi <イメージID> #イメージを削除

SSH接続

コンテナにSSH接続するには、コンテナにsshdをインストールします。
今回は、イメージにUbuntu12.04を指定しました。

$ sudo docker run -i -t ubuntu:12.04 /bin/bash
root@b9da36681214:/# apt-get update
root@b9da36681214:/# apt-get install openssh-server
root@b9da36681214:/# mkdir /var/run/sshd
root@b9da36681214:/# /usr/sbin/sshd
root@b9da36681214:/# passwd root
root@b9da36681214:/# exit

上記で作成したコンテナをcommitし、イメージにします。

$ sudo docker ps -a #コンテナIDを確認します。
$ sudo docker commit <コンテナID> ubuntu-sshd

次に、以下のようにubuntu-sshd コンテナを使って /usr/sbin/sshdで実行します。

  • pオプションはポートフォワードに使うポート番号を指定しています。

SSHでは22番ポートを使用しているため、22番ポートをフォワードします。
このオプションは複数指定することが可能で、22番ポートと80番ポートを使いたい場合は、-p 20 -p 80と指定します。

$ sudo docker run -d -p 22 ubuntu-sshd /usr/sbin/sshd -D

以下のコマンドで、PORTSの列に「0.0.0.0:[ポート番号]」が表示されますが、これが22番ポートにマッピングされたローカルのポートになります。

$ sudo docker ps -a
CONTAINER ID        IMAGE                COMMAND                CREATED             STATUS                         PORTS                 NAMES
6e61ccbe71df        ubuntu-sshd:latest   /bin/sh -c '/usr/sbi   2 days ago          Up 25 hours                    0.0.0.0:[ポート番号]->22/tcp                         loving_almeida

上記で確認したポート番号を指定して、コンテナにSSH接続します。

$ ssh root@127.0.0.1 -p [ポート番号]

今回の構成は、VMware ESXi 5.1上のUbuntu12.04のサーバに、Ubuntu12.04のコンテナを起動しましたが、評判通りコンテナの起動は早く、サーバの負荷は小さいものでした。Chefやserverspecの環境として、使用できる見通しが取れたかと思います。

Chef + serverspec + Jenkins でサーバ構築からテストまでを自動化してみた

Chefとserverspecでサーバ構築とテストをプログラマブルにできるようになったため、Jenkinsによりサーバ構築からテストまでを自動化してみました。

やりたいこと

以下のように、Chefのリポジトリの更新をトリガーに、サーバ構築からテストまでをJenkinsにて自動化します。

  1. Chefのレシピをリモートリポジトリへgit pushすると、Jenkinsが通知を検知
  2. JenkinsからChefを実行し、サーバを構築
  3. サーバの構築が正常終了すれば、Jenkinsからserverspecを実行し、サーバの状態をテスト

構成

CentOS 6.5 : Chef、serverspec、Jenkins、Gitをインストール
Ubuntu 12.04 : サーバ構築、テスト対象
※上記2台のサーバはVMware ESXi 5.1上で動作しています。

インストール

以下のソフトウェアをインストールします。
※過去の記事のリンクになります。

設定

各ソフトウェアの設定について説明していきます。
SSH認証の設定は完了しているものとします。

Chef

まず、Chefのリポジトリを作成します。

$ knife solo init chef-repo

サーバ構築用のcookbookを作成します。
今回は、apache2をインストールするレシピを用意します。

$ cd chef-repo/
$ knife cookbook create apache2 -o site-cookbooks
$ vi site-cookbooks/apache2/recipes/default.rb
# Apacheをインストール
# sudo apt-get -y install apache2
package "apache2" do
    action :apache2
end

JSONファイルが作成されるため、実行するapache2のcookbookを指定します。

$ vi nodes/<サーバのIPアドレス>.json
{
  "run_list":[
    "recipe[apache2]"
  ]
}

serverspec

Chefのrootディレクトリに移動し、serverspecの初期設定を行います。

$ cd chef-repo/
$ serverspec-init
Select OS type:

  1) UN*X
  2) Windows

Select number: 1  #UN*Xを選択

Select a backend type:

  1) SSH
  2) Exec (local)

Select number: 1 #SSHを選択

Vagrant instance y/n: n #nを選択
Input target host name: 192.168.xxx.xxx #テスト対象サーバのIPアドレスを指定
 + spec/
 + spec/192.168.xxx.xxx/
 + spec/192.168.xxx.xxx/httpd_spec.rb
 + spec/spec_helper.rb
 + Rakefile

apache2がインストールされているか確認するテストコードを書きます。

$ mv spec/192.168.xxx.xxx/httpd_spec.rb spec/192.168.xxx.xxx/apache2_spec.rb
$ vi spec/192.168.xxx.xxx/apache2_spec.rb
require 'spec_helper'

describe package('apache2') do
  it { should be_installed }
end

Git

Chef・serverspec用のリモートリポジトリを作成します。

$ mkdir /var/lib/git
$ mkdir /var/lib/git/chef-cookbooks.git
$ cd /var/lib/git/chef-cookbooks.git
$ git --bare init

Chef・serverspec用のローカルリポジトリを作成します。
chef-repoのディレクトリに移動し、リポジトリの初期化を行い、ローカルリポジトリを作成します。
リモートリポジトリには何も入っていないため、ローカルリポジトリの内容を追加します

$ cd chef-repo/
$ git init
$ git add .
$ git commit -m "first commit"
$ git remote add origin /var/lib/git/chef-cookbooks.git
$ git push origin master

Jenkins

Jenkinsでのジョブは、jenkinsユーザにより実行されるため、パスワードなしでsudoを実行する設定を入れておきます。

$ visudo
jenkins ALL=(ALL) NOPASSWD: ALL # ←最終行に追加

Jenkinsにログイン後、[新規ジョブの作成]をクリックし、ジョブ名とビルドを設定します。

以下のように設定を入れ、[OK]をクリックします。

  • ジョブ名: chef-cookbooks
  • フリースタイル・プロジェクトのビルド オン

上記で作成したリポジトリと連携するため、[ソースコード管理]を以下のように設定します。

  • ソースコード管理
    • Git オン
    • Repositories
      • Repository URL: /var/lib/git/chef-cookbooks.git
      • Credentials: なし
    • Branches to build
      • Branch Specifier (blank for 'any'): */master

リポジトリのgit pushを検知するために、[ビルド・トリガ]を以下のように設定します。

  • ビルド・トリガ
    • SCMをポーリング チェック
      • スケジュール 下記に記載
      • post-commitフックを無視 チェックオフ

スケジュールはcronのように設定できます。
今回は、15分毎にチェックが走るように、以下のように設定します。

H/15 * * * *

Chefとserverspecのコマンドを実行するために、[ビルド手順を追加]>[シェルの実行]をクリックし、[シェルの実行]を以下のように設定します。

sudo /root/.rbenv/shims/knife solo bootstrap <ユーザ名>@192.168.xxx.xxx
sudo /root/.rbenv/shims/rake spec

※bootstrapはprepareとcookを同時に実行するオプションです。

上記の設定ができたら、[保存]をクリックします。

実行

以下のように、Chefのファイルを修正後、commitし、git pushを実行します。

$ cd chef-repo/
$ vi site-cookbooks/apache2/recipes/default.rb
$ git add .
$ git commit -m "first commit"
$ git push origin master

スケジュールのタイミングによりgit pushの通知が検知されます。
通知を検知すると、JenkinsのワークスペースにChefのリポジトリがコピーされます。

ジョブが実行されたら、[ジョブ名]>[ビルド履歴]>[ビルド番号]へ移動し、[コンソール出力]をクリックします。ジョブが正常終了すれば、コンソール出力の末尾に「Finished: SUCCESS」と表示されます。

以下は、Chefとserverspecの実行が正常終了していることを示しています。

SCMのポーリングが実行
ビルドします。 ワークスペース: /var/lib/jenkins/workspace/chef-cookbooks
Fetching changes from the remote Git repository
Fetching upstream changes from /var/lib/git/chef-cookbooks.git
Checking out Revision 187f8b995de5ddc053a18a3d114f1aa5018f1979 (origin/master)
[chef-cookbooks] $ /bin/sh -xe /tmp/hudson7478251361203469042.sh
+ sudo /root/.rbenv/shims/knife solo bootstrap <ユーザ名>@192.168.xxx.xxx
Running Chef on 192.168.xxx.xxx...
Checking Chef version...
:
Running handlers complete
[0m
Chef Client finished, 1/1 resources updated in 8.041423413 seconds[0m
+ sudo /root/.rbenv/shims/rake spec
/root/.rbenv/versions/2.0.0-p451/bin/ruby -S rspec spec/192.168.xxx.xxx/httpd_spec.rb
.

Finished in 0.10092 seconds
1 example, 0 failures
Finished: SUCCESS

実行が失敗した場合は、以下のようにエラーが表示され、そこでJenkinsのジョブは停止します。

Build step 'シェルの実行' marked build as failure
Finished: FAILURE

Chefの実行で失敗した場合は、serverspecは実行されないため、正常終了すればサーバ構築からテストまですべて終了したことになります。

おわりに

今回構築した環境は、共同でChefのレシピやserverspecのテストコードを書くフローを想定していました。各メンバーは、PCでChefやserverspecのコードを作成後、VirtualBoxでテストし、問題がなければリモートリポジトリへgit pushします。リモートリポジトリへgit pushすれば、後はJenkinsがサーバ構築からテストまでを自動で行い、正常終了すれば本番環境へ適用するといった流れです。ただし、今回の環境ではテスト環境をクリアすることは含まれていないため、スナップショットを手動で戻してやる手間が残ってしまいました。
次回は、このあたりの問題を解決していきたいと考えてます。

serverspecで構築したサーバの状態をテストする

Chefでプログラマブルなサーバ構築ができるようになったため、構築後のサーバの状態をプログラマブルにテストするために、serverspecをインストールしてみました。

構成

  • CentOS 6.5 : serverspecをインストール
  • Ubuntu 12.04 : テスト対象

インストール

公式サイトにある手順を参考にserverspecをインストールします。
Rubyはすでにインストールされているものとします。

gemからserverspecをインストールします。

$ gem install serverspec

初期設定

セッティング

serverspecのセッティングを行います。
任意のディレクトリに移動し、以下のserverspec-initコマンドを実行します。
※Chefのrootディレクトリ(chef-repo)でもよいかもしれません。
対話形式で聞いてくるので、以下のように設定します。

$ mkdir serverspec
$ cd serverspec
$ serverspec-init
Select OS type:

  1) UN*X
  2) Windows

Select number: 1  #UN*Xを選択

Select a backend type:

  1) SSH
  2) Exec (local)

Select number: 1 #SSHを選択

Vagrant instance y/n: n #nを選択
Input target host name: 192.168.xxx.xxx #テスト対象サーバのIPアドレスを指定
 + spec/
 + spec/192.168.xxx.xxx/
 + spec/192.168.xxx.xxx/httpd_spec.rb
 + spec/spec_helper.rb
 + Rakefile

SSH認証

SSH接続によりテストを行うため、サーバにパスワードなしで接続できるように、公開鍵認証の設定を行います。
ssh-keygenコマンドで認証用の鍵を作成し、対象サーバへ転送します。

$ ssh-keygen
$ scp ~/.ssh/id_rsa.pub <ユーザ名>@<テスト対象サーバのIPアドレス>:
$ ssh <ユーザ名>@<テスト対象サーバのIPアドレス> # テスト対象サーバへログイン
$ mkdir ~/.ssh
$ mv id_rsa.pub ~/.ssh/authorized_keys

パスワードなしでsudoを実行する設定を行います。

$ sudo visudo
<ユーザ名> ALL=(ALL) NOPASSWD: ALL # ←最終行に追加
$ exit

serverspecは、SSH接続でテスト対象にアクセスしますが、テスト対象にログインするための情報は~/.ssh/configから取得しています。
serverspecが利用できるように、~/.ssh/configを修正します。

$ vi ~/.ssh/config
Host 192.168.xxx.xxx
  HostName 192.168.xxx.xxx #テスト対象サーバのIPアドレスを指定
  User <ユーザ名> #SSH接続でログインするユーザを指定
  Port 22
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile "/root/.ssh/id_rsa" #秘密鍵のパスを指定
  IdentitiesOnly yes
  LogLevel FATAL

テスト

テストコード

serverspec-init後に、テストコードのサンプルとしてspec/192.168.xxx.xxx/httpd_spec.rbが作成されます。httpd_spec.rbを参考に、以下のようにテストコードを書きます。

$ mv spec/192.168.xxx.xxx/httpd_spec.rb spec/192.168.xxx.xxx/apache2_spec.rb
$ vi spec/192.168.xxx.xxx/apache2_spec.rb
require 'spec_helper'

describe package('apache2') do
  it { should be_installed }
end

※require 'spec_helper'でspec/spec_helper.rbが実行され、~/.ssh/configからSSH接続の情報を取得しています。

テスト実行

以下のコマンドを実行し、テストを実行します。
exampleはテストの件数、failuresは失敗したテストの件数を示しています。
以下の場合は、全てのテストが成功したことを示しています。

$ rake spec
/root/.rbenv/versions/2.0.0-p451/bin/ruby -S rspec spec/192.168.xxx.xxx/apache2_spec.rb
.

Finished in 0.10092 seconds
1 example, 0 failures

後は、spec/192.168.xxx.xxx/配下にテスト対象ごとに*_spec.rbファイルを作成し、テストコードを書いていきます。

Gitのインストールと初期設定

バージョン管理を行うため、CentOS6.5にGitをインストールしてみました。

インストール

公式サイトにある手順を参考にGitをインストールします。
最新版のGitを使用する場合は、ソースからのインストールしますが、今回はyumからインストールしました。

$ yum -y install git

初期設定

ユーザの登録

まずは、Gitのユーザ名とメールアドレスを登録します。
「--global」オプションを付けることで、「~/.gitconfig」に情報が格納されます。

$ git config --global user.name <ユーザ名>
$ git config --global user.email <メールアドレス>
$ git config --list

リモートリポジトリの作成

リモートリポジトリを作成します。
リモートリポジトリへのアクセスは、一旦Localプロトコルで行います。
他サーバから接続する場合は、SSHプロトコルやGitプロトコルが使えます。SSHプロトコルを使う場合は、SSH認証の設定が必要となります。

$ mkdir /var/lib/git
$ mkdir /var/lib/git/project.git
$ cd /var/lib/git/project.git
$ git --bare init

ローカルリポジトリの作成

管理対象のディレクトリに移動し、リポジトリの初期化を行い、ローカルリポジトリを作成します。

$ mkdir local
$ cd local
$ git init
$ echo test > test #テスト用のファイルです
$ git add .
$ git commit -m "first commit"

リモートリポジトリには何も入っていないため、ローカルリポジトリの内容を追加します。※Localプロトコルでアクセスしています。

$ git remote add origin /var/lib/git/project.git
$ git push origin master

初期設定は以上となります。

Gitの簡単な使い方として、ファイルの編集→add→commit→pushを繰り返し行っていくことになります。
Gitの使い方については、まだ分からない点があり、整理ができたところで記事にしたいと思っています。

GitWebのインストール

インストール

Gitはコマンドベースのツールのため、リポジトリがどのような状態になっているか分かりにくいときがあります。
そこで、Gitのリモートリポジトリをブラウザで見れるように、GitWebをインストールします。
apacheも必要であるため、合わせてインストールします。

$ yum -y install httpd
$ yum -y install gitweb

/etc/gitweb.confファイルにリモートリポジトリのパスを指定します。

$ vi /etc/gitweb.conf
#our $projectroot = "/var/lib/git";
our $projectroot = "/var/lib/git"; ←コメントアウトを外して、リモートリポジトリのパスを指定

apache自動起動の設定とサービスを起動します。

$ chkconfig httpd on
$ service httpd start

apacheのデフォルトポートは80なので、ファイアウォールの設定によりポート80が使えるように開放します。

$ vi /etc/sysconfig/iptables
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT ←追加します
$ service iptables restart

また、SELinuxが動作していると、「404 - No projects found 」と表示されGitの情報が見れない場合があります。以下のファイルを修正し、SELinuxを無効化します。

$ vi/etc/sysconfig/selinux
#SELINUX=enforcing
SELINUX=disabled

サーバを再起動すると設定が反映されます。

デザインの変更

GitWebのデザインをGitHub風に変更するテーマが公開されてるので適用します。
(見た目は大事です)

$ cd /usr/local/src/
$ git clone https://github.com/kogakure/gitweb-theme.git
$ cd gitweb-theme/
$ \cp -rf ./* /var/www/git

※\cpはcp -iのエイリアスを無効にして、上書き確認を無効にしています。

Jenkinsのインストールと初期設定

継続的インテグレーション(CI:Continuous Integration)を行うため、CentOS6.5にJenkinsをインストールしてみました。

インストール

JenkinsはJavaで動作しているため、Javaをインストールします。

$ yum -y install java-1.7.0-openjdk

公式サイトにある手順を参考にJenkinsをインストールします。

$ wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
$ rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
$ yum -y install jenkins

Jenkinsの自動起動の設定とサービスを起動します。

$ chkconfig jenkins on
$ service jenkins start

Jenkinsのデフォルトポートは8080なので、ファイアウォールの設定によりポート8080が使えるように開放します。

$ vi /etc/sysconfig/iptables
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT ←追加します
$ service iptables restart

端末からブラウザで「http://localhost:8080」にアクセスできることを確認します。

初期設定

初回アクセス後、[Jenkinsの管理]をクリックすると、以下のメッセージが出力されます。
初期の状態では誰でもジョブの設定ができるため、セキュリティの設定を行います。

セキュリティを有効化しないと、ネットワーク上の誰にでもプロセスの起動を許可します。悪用を防ぐために、少なくとも認証を有効化することを検討してください。

[Jenkinsの管理]>[グローバルセキュリティの設定]へ移動します。
セキュリティを有効化のチェックボックスをオンにすると、設定画面が表示されます。
セキュリティを有効化のオプションを以下のように設定し、保存をクリックします。

  • Jenkinsのユーザーデータベース チェック
    • ユーザーにサインアップを許可 チェック
  • ログイン済みユーザーに許可  チェック

ログイン画面に遷移するので、[アカウント登録]をクリックし、[サインアップ]に行きます。
以下のアカウント情報を入力し、[サインアップ]クリックします。

  • ユーザ名
  • パスワード
  • パスワードの確認
  • フルネーム
  • メールアドレス

「ログインしました。トップに戻ります。」と表示されるので、[トップ]をクリックします。
トップ画面に遷移すると、上記のアカウントでログインしている状態となります。
「Jenkinsの管理」をクリックすると、上記の「セキュリティを有効化しないと~」のメッセージが消えていることが分かります。

[Jenkinsの管理]>[グローバルセキュリティの設定]へ移動します。
セキュリティを有効化のオプションを以下のように変更し、保存をクリックします。

  • Jenkinsのユーザーデータベース チェック
    • ユーザーにサインアップを許可 チェックオフ
  • 行列による権限設定 チェック
    • 作成したユーザ名を入力して追加をクリック
      • ユーザ名の行のチェックを全てオン

一旦ログオフし、ログインできるか確認します。
※[セキュリティを有効化]の設定で失敗すると、ログインできないため注意が必要です。(失敗した場合は、再インストールしたほうが早いかもしれません。)

プラグインのアップデート

[Jenkinsの管理]>[プラグインの管理]へ移動すると、[アップデート]タブに初期導入されていたプラグインのうちアップデートが可能なプラグインが表示されます。
すべてのプラグインにチェックを入れ、[ダウンロードして再起動後にインストール]をクリックします。
アップデート後、[Jenkinsの管理]>[プラグインの管理]へ移動すると、[アップデート]タブにプラグインが表示されていないことを確認します。

Gitの設定

初期ではGitのプラグインがインストールされていないため、JenkinsからGitを使いたい場合は、Gitのプラグインをインストールします。

[利用可能]タブへ移動し、「Git Plugin」にチェックを入れ、[ダウンロードして再起動後にインストール]をクリックします。

  • Git Plugin チェック

※チェックをしていなくても「Git Client Plugin」も合わせてインストールされます。

次に、[Jenkinsの管理]>[システムの設定]へ移動すると、Gitの項目が表示されています。
「Path to Git executable」にGitのパスを入力し、[保存]をクリックします。

  • Name: Default
  • Path to Git executable: /usr/bin/git


後は、[新規ジョブ作成]をクリックして、ジョブを作成していきます。

Chef SoloでRedmineの構築を自動化する

Chef SoloでRuby on Railsの環境構築ができたため、味を占めてRedmineの構築も自動化してみました。

Chefを動かすにはCentOS6にChef Soloをインストールするが必要なので、まず先にやっておきます。
Opscode CommunityRedmineのCookbookを探してみたところ、redmine2というCookbookがあったためこれを使うことにしました。

今回、Chefで作成する構成は以下のとおりです。

Redmine Redmine 2.4.3
OS Ubuntu 12.04
データベース MySQL 5.5.37
Webサーバ nginx 1.1.19
Ruby 1.9.3-p484


まず、chef-repo配下にBerksfileを作成し、README.mdに指定のあったCookbookを設定します。

$ cd chef-repo/
$ vi Berksfile
site :opscode

cookbook 'rbenv', git: 'https://github.com/fnichol/chef-rbenv'
cookbook 'redmine2', git: 'https://github.com/aminin/redmine2-cookbook'

berksコマンドを実行して依存関係のあるCookbookをダウンロードします。

$ berks install

サーバにChefをインストールします。

$ knife solo prepare <ユーザ名>@<サーバのIPアドレス>


redmine2のattribute/default.rbは以下のようになっており、デフォルトのDBはsqliteでしたが、MySQLも利用できる仕様だったため、DBにはMySQLを指定することにしました。*1

default_unless[:redmine]         = {}
default[:redmine][:user]         = 'redmine'
default[:redmine][:home]         = '/home/redmine'
default[:redmine][:host]         = 'redmine.example.com'
default[:redmine][:version]      = '2.4.3'
default[:redmine][:ruby_version] = '1.9.3-p484'
default[:redmine][:create_db]    = true
 
default_unless[:redmine][:db]     = {}
default[:redmine][:db][:type]     = 'sqlite'
default[:redmine][:db][:hostname] = 'localhost'
default[:redmine][:db][:dbname]   = 'redmine'
default[:redmine][:db][:username] = 'redmine'
default[:redmine][:db][:password] = 'redmine'

Redmineのデータベースとパスワード、MySQLのパスワードを指定するため、下記のようにJSONファイルを作成します。*2

$ vi nodes/<サーバのIPアドレス>.json
{
    "redmine": {
        "host": "redmine.dev",
        "db": {
            "type": "mysql",
            "password": "passw0rd"
        }
    },

    "mysql": {
        "password": "passw0rd"
    },

    "run_list": [
        "recipe[mysql::server]",
        "recipe[redmine2]"
    ]
}

サーバに対してchef-soloを実行します。

$ knife solo cook <ユーザ名>@<サーバのIPアドレス>

Redmineの構築ができたことを確認するため、「http://<サーバのIPアドレス>」にアクセスし、adminユーザでログインできることを確認します。


実は、当初以下のサイトを参考に、RedmineのCookbookを一から作成していましたが、passengerのインストールとrake db:migrateの処理で詰まってしまい途方にくれていました。今回Opscodeで先人の知恵を借りましたが、Redmineの構築がここまで簡単にできるのは衝撃的でした。ある意味、破壊的な技術だなという気がします。

*1:README.mdやmetadata.rbにはデフォルトのDBはPostgreSQLだよと書いてあり、どちらの値が優先されるのかは確認中です。

*2:Ubuntu 12.04で動作確認済み

Chef SoloでRailsの環境構築を自動化する

Ruby on Railsの環境構築は、RubyのインストールRails のバージョンを指定してインストールするが必要でしたが、これらの作業をChef Soloで自動化してみました。

Chefを動かすにはCentOS6にChef Soloをインストールするが必要なので、まず先にやっておきます。
次にCookbookを作りますが、Opscode Communityに多くのCookbookが公開されているため、Cookbookを全て自作しなくてもある程度の環境構築はできてしまします。*1


公開されているCookbookを使うには、依存関係のあるCookbookをまとめてダウンロードしてくれるBerkshelfを使用します。

Berkshelfをインストールします。

$ gem install berkshelf

chef-repo配下にBerksfileを作成し、以下のようにCookbookを指定します。
Ruby on Railsの環境構築のため、今回はrbenvというCoookbookを使用します。
Opscode Community以外のCookbookを使用する場合は、以下のようにgit:~のように指定します。

$ cd chef-repo/
$ vi Berksfile
site :opscode

cookbook 'rbenv', git: 'https://github.com/fnichol/chef-rbenv'

berksコマンドを実行してCookbookをダウンロードします。
berksコマンドを実行するとBerksfile.lockが作成され、依存関係のあるCookbookが一覧で表示されます。

$ berks install

サーバにChefをインストールします。

$ knife solo prepare <ユーザ名>@<サーバのIPアドレス>

RubyのバージョンとRailsのバージョンを指定してインストールするには、下記のようにJSONファイルを作成します。*2*3

run_listには、実行するCookbookである、ruby_buildとrbenvを指定しています。
また、rbenvオブジェクトでAttributeのデフォルト値を上書きします。
今回は、インストール先のユーザ、Rubyのバージョン、rbenvのglobal設定、Railsのバージョンを指定しました。

$ vi nodes/<サーバのIPアドレス>.json
{
    "rbenv": {
        "user_installs": [
            {
                "user": "<ユーザ名>",
                "rubies": ["1.9.3-p545","2.0.0-p353"],
                "global": "1.9.3-p545",
                "gems":  {
                    "1.9.3-p545": [
                        { "name": "bundler" },
                        { "name": "rails",
                          "version": "~>3.0"
                         }
                    ]
                }
            }
        ]
    },

  "run_list":[
    "recipe[ruby_build]",
    "recipe[rbenv::user]"
    ]
}

サーバに対してchef-soloを実行します。

$ knife solo cook <ユーザ名>@<サーバのIPアドレス>

Ruby on Railsの環境構築ができたことを確認するため、サーバにログインし、Railsで新規アプリケーションを作成するの手順を実行し、「http://<サーバのIPアドレス>:3000」にアクセスできることを確認します。

*1:ただし、公開されているCookbookを単純に使用しただけでは、必ずエラーが発生するかと思います。エラーが発生した場合、エラーの内容やCookbookの中身を理解する必要があり、LinuxRuby・Chef・インストール対象のソフトウェア等の知識が求められるため、正直学習コストは低くないのではと思っています。

*2:Ubuntu 12.04で動作確認済み

*3:README.mdには多くの対応プラットフォームか書かれておりCentOSもおそらく可