2014年5月31日土曜日

[Chef]Berkshelfを利用したJenkinsクックブックを作成してserverspec+Kitchenでテストした話

このエントリーをはてなブックマークに追加 はてなブックマーク - [Chef]Berkshelfを利用したJenkinsクックブックを作成してserverspec+Kitchenでテストした話

最近、Chefの本も色々出てきたのでしっかり勉強しようと思い、クックブックを作成し、テストまでするようにしてみたのでその時のメモです。

作ったもの

  • Jenkinsをインストールするクックブック
  • 最新版をインストールする為にaptやyumリポジトリの追加もする
  • Javaのインストールもする

作成したものはGithubに登録してあります。 後述の通り、CentOS6.4とUbuntu12.04でテストしております。 利用はご自由にどうぞ。

toshihirock/jenkins

また、タイトルにも記載の通り、テストはserverspecとVagrantドライバを利用したkitchenで実施するようにしました。

環境

ChefやBerkshelfはインストール済みの状態で確認しました。

$gem list --local |grep -e chef -e knife -e berkshelf 
berkshelf (3.1.2)
berkshelf-api-client (1.2.0)
chef (11.12.4)
chef-zero (2.1.4)
knife-solo (0.4.1)

ホストマシンはMacでVagrantもインストール済みです。

インストールがまだの場合、ChefDKでのインストールが楽でおすすめです。

環境の話は以前詳しいものを書いたので良ければ参照下さい。

Berkshelf version3+Knife soloでnginx環境をVagrantに作ってみた話

準備する

以下のコマンドでクックブックのひながたを作成します。

$kinife cookbook create jenkins -o .

Berkshelfの為のファイルを作成します。

$cd jenkins
$berks init .
      create  Berksfile
      create  Thorfile
      create  chefignore
      create  .gitignore
         run  git init from "."
      create  Gemfile
      create  .kitchen.yml
      append  Thorfile
      create  test/integration/default
      append  .gitignore
      append  .gitignore
      append  Gemfile
      append  Gemfile
You must run `bundle install' to fetch any new gems.
      create  Vagrantfile
Successfully initialized

今回のテストで利用するserverspecについてもインストールするようにGemfileを変更します。

source 'https://rubygems.org'

gem 'berkshelf'
gem 'serverspec'
gem 'test-kitchen', '~>1.2.0'
gem 'kitchen-vagrant', :group => :integration

Gemfileに記載したものをインストールします。

$bunle install

Berkshlefの利用

今回Jenkinsをインストールに当たり、以下のサードパーティのCookbookを使います。

上記を使う事をmetadata.rbに記載します。

name             'jenkins'
maintainer       'YOUR_COMPANY_NAME'
maintainer_email 'YOUR_EMAIL'
license          'All rights reserved'
description      'Installs/Configures jenkins'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version          '0.1.0'

depends "java"
depends "apt"
depends "yum"

上記記載後、予め対象のクックブックをインストールします。

$berks install

上記によって、~/.berkshelf/cookbooks/配下にcookbookが格納されます。

今回はmetadata.rbに利用するクックブックを記載しましたが、Berksfileへの追記でも指定が可能です。こちらでは指定したGitのURLからダウンロードする事もでき、Opscodeなどに登録されていないサードパーティのクックブックの利用も可能です。

レシピを書く

以下のようなレシピをrecipes/default.rbに記載しました。

# install java
case node['platform']
when 'ubuntu'
  execute "apt-get update" do
    command "apt-get update"
  end
end
include_recipe 'java'

# add package control
case node['platform']
when 'ubuntu'
  apt_repository 'jenkins' do
    uri node['jenkins']['apt_uri']
    key node['jenkins']['apt_key']
    action :add
  end
when 'centos'
  yum_repository 'jenkins.repo' do
    baseurl node['jenkins']['yum_baseurl']
    description 'jenkins'
    gpgkey node['jenkins']['yum_gpgkey']
    action :create
  end
end

# install jenkins
package 'jenkins'

# start jenkins
service 'jenkins' do
  action [ :enable, :start ]
end

# move to jennkins setting file
cookbook_file 'jenkins' do
  case node['platform']
  when 'ubuntu'
    path node['jenkins']['ubuntu_setting_path']
  else
    path node['jenkins']['centos_setting_path']
  end
  action :create
  notifies :reload, 'service[jenkins]'
end

上記レシピでは以下を実施しています。

  • Javaをインストール
  • apt,yumのリポジトリにJenkinsを追加
  • Jenkinsのインストール
  • Jenkinsの起動
  • Jenkinsの設定ファイルの変更(Gitの文字化けをしないように文字コードをUTF–8にする設定ファイルに変更)
  • 設定ファイル変更後、Jenkinsの再起動

次に設定値をattributeに記載します。 attributesフォルダ配下にdefault.rbを作成し、記述します。

$vi attributes/default.rb

編集します。

# java
default['java']['jdk_version'] = '7'

# jenkins
default['jenkins']['apt_uri'] = 'http://pkg.jenkins-ci.org/debian binary/'
default['jenkins']['apt_key'] = 'http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key'
default['jenkins']['yum_baseurl'] = 'http://pkg.jenkins-ci.org/redhat'
default['jenkins']['yum_gpgkey'] = 'http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key'
default['jenkins']['ubuntu_setting_path'] = '/etc/default/jenkins'
default['jenkins']['centos'] = '/etc/sysconfig/jenkins'

Jenkinsの設定ファイルの上書きを行う為に、予め利用したい設定ファイルを配置します。 確認した所、centosとubuntuでは利用する設定ファイルが違うみたいなので、filesフォルダ配下にそれぞれのプラットフォーム名のフォルダを作成し、利用したいファイルを配置します。 利用するJenkinsの設定ファイルは各プラットフォームにJenkinsをインストールし、設定ファイルをコピーしておき、編集して配置しました。

$mkdir files/centos
$mkdir files/ubuntu
$cp foo/bar/jenkins files/centos/
$cp hoge/fuga/jenkins files/ubuntu/

なお、filesフォルダの詳細は以下を確認ください。

About Files

テストを書く

レシピの準備はできたのでテストを書きます。 以下のコマンドで必要なファイルを作成します。

$bundle exec kitchen init

.kitchen.ymlが作成されるので中身を確認します。

---
driver:
  name: vagrant

provisioner:
  name: chef_solo

platforms:
  - name: ubuntu-12.04
  - name: centos-6.4

suites:
  - name: default
    run_list:
      - recipe[jenkins::default]
    attributes:

今回、テスト環境としてVagrantを利用し、テスト対象のOSもUbuntuとCentOSのため、このままとしますが、テスト対象などを変更する場合にはこのファイルを編集する必要があります。

今回のテストはserverspecを利用する為、そのフォルダを作成します。

$mkdir -p test/integration/default/serverspec/localhost/

次にテストファイルを作成し、編集します。

$vi test/integration/default/serverspec/localhost/default_spec.rb

編集します。

require 'serverspec'
include Serverspec::Helper::Exec
include Serverspec::Helper::DetectOS

describe command('java -version') do
  it { should return_stdout /.*1.7/}
end

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

describe service('jenkins') do
  it { should be_enabled }
  it { should be_running }
end

以下を確認するテストとしました。

  • インストールされたJavaのバージョンは1.7であること
  • Jenkinsがインストールされていること
  • Jenkinsのサービスが起動しており、かつOS起動時にサービスが起動する設定となっていること

準備ができたのでテストを実行します。

$bundle exec kitchen test

実行するとVagrantを利用してテストが実行されます。 なお、 テスト環境となるOSのイメージが存在しない場合(今回の場合にはCentOS6.4とUbuntu12.04)にはそのダウンロードが必要となり、かなり時間が掛かります。

テストやクックブックの適用に失敗するとエラー内容が出力されます。 その場合、再度bundle exec kitchen testとするとOSの再起動から始まるため、単純に適用だけの操作は以下で可能となります。

$bundle exec kitchen verify default-ubuntu-1204

2014年5月23日金曜日

外部のbareリポジトリとオレオレGitlabを連携させてみる

このエントリーをはてなブックマークに追加 はてなブックマーク - 外部のbareリポジトリとオレオレGitlabを連携させてみる

オレオレGitlabを構築して、外部のbareリポジトリと連携してみたのでその時のメモ。 (メール機能については除外)

状況

  • 外部サーバーにGitのbareリポジトリがある
  • 外部サーバーにGitlab立てたいけど色々あって却下された
  • じゃあ社内ネットワークにGitlab立ててHookさせれば良いんじゃね?
  • VagrantでVM立ててそこにGitlab立てよう

完成イメージ

環境

  • ホストマシン:Mac OSX 10.9.3
  • VM:Ubuntu12.04(64bit)
  • Vagrant1.6.2
  • Gitlab 6.8.2

UbuntuのVMを起動する

Gitlabが簡単にインストール出来るOmnibusが利用出来るUbuntu12.04(64bit)のVMを立てます。

まずはVagrantfileを用意。大切な箇所だけ抜粋。

# ubuntu12.04 64bitのBOXを予めインストール
config.vm.box = "precise64"

# 80ポートへのフォワード設定
config.vm.network "forwarded_port", guest: 80, host: 1234

起動させます。

$vagrant up

GitLabのインストール

まずはsshアクセスします。

$vagrant ssh

GitlabをVMにインストールします。 取得するGitLabのOmnibusの最新版は こちらで確認し、各自変更してください。

$wget https://downloads-packages.s3.amazonaws.com/ubuntu-12.04/gitlab_6.8.2-omnibus-1_amd64.deb
$sudo dpkg -i gitlab_6.8.2-omnibus-1_amd64.deb
$sudo gitlab-ctl reconfigure

インストールが終わったか、確認します。

$wget http://localhost:8080/

外部からのアクセスする際のURLを設定します。

$sudo vi /etc/gitlab/gitlab.rb
external_url "http://localhost"
$sudo chmod 600 /etc/gitlab/gitlab.rb

再度設定をします。

$sudo gitlab-ctl reconfigure

本例の場合、ブラウザからhttp://localhost:1234/でアクセスします。 実際に会社などで利用する場合には自身のマシンに設定されているIPアドレスでも接続出来るはずです。なお、その場合、gitlab.rbのexternal_urlもマシンに降られているIPアドレスを記述する必要があります。

最初のログインはID「root」、パスワード「5iveL!fe」と入力します。

bareリポジトリをGitLabにも追加する

本例では確認他の為にGithubを利用します。 まず、Githubに適当なプロジェクトを作成します。

その後、該当のプロジェクトのgit cloneする時のURLをメモします。

GitlabのNew ProjectImport existing repository?を選択し、先ほどコピーしたURLにユーザー名とパスワードを設定して指定します。(https://username:password@gitlab.com/company/project.git. など)

上記によってGitLabにbareリポジトリを作成されます。

bareリポジトリは/var/opt/gitlab/git-data/repositories/{namespace}/配下に配置されています。

git configコマンドで確認すると以下のようになっており、originはGithubとなっている事が確認出来ます。

$cd /var/opt/gitlab/git-data/repositories/root/helloworld.git
$git config -l
core.repositoryformatversion=0
core.filemode=true
core.bare=true
remote.origin.url=https://username:password@github.com/toshihirock/Hello-World.git

Gitabへのpush時に取得元のリポジトリにもpushするようにする

Gitlabへのpushタイミングで取得元にもpushする為にHookスクリプトを利用します。

こちらは以下のサイトを参考にさせてもらいました。

git hooks を利用したデプロイを導入しました

gitでbareリポジトリを同期する方法

まず、直接取得元へpushするユーザーが居る事もあると思うので、push時に取得元とGitLabとの間で同期を取るようにします。 この方法を実現する為に、pushの取り込み前に実行されるpre-receiveスクリプトを利用します。

$su git
$cd hooks
$touch pre-receive
$chmod +x pre-receive
$vi pre-receive

編集します。

#!/bin/bash
echo "start pre-receive"
git fetch origin 'refs/heads/*:refs/heads/*'
echo "end pre-receive"

これで取得元の差分があれば取り込む事が出来ます。

また、post-updateスクリプトを利用してGitlabへのpushが完了したタイミングで、取得元にもpushするようにします。 post-receiveスクリプトといのもあるのですが、こちらは複数のブランチへのpushの際にも一度しか呼ばれないので、今回の用途ではブランチ毎に呼び出されるpost-updateスクリプトを利用します。

$touch post-update
$chmod +x post-update
$vi post-update

編集します。

#!/bin/bash
echo "start post-update"
BRANCH=$(git rev-parse --symbolic --abbrev-ref $1)
git push origin ${BRANCH}
echo "end post-update"

上記のようにすると変数BRANCHにpushしたブランチ名が入るので、対象のブランチを取得元にpushすることができます。 先ほどgit configで見たようにGitlabに作成されたbareリポジトリのoriginは取得元(本例だとGithub)となっているので上記のようにすることで取得元へのpushが出来ます。

Gitlabからのクローンを確認

Gitlabからクローン出来るか確認してみます。 ユーザー名、パスワードは置き換えて下さい。

$git clone http://username:password@localhost:1234/root/helloworld.git

Githubからのクローンとpush先の変更

Githubから対象のリポジトリをcloneします。

$git clone http://username:password@github.com/hogefuga.git

git remoteコマンドを利用してoriginの向き先をGitlabに変更します。

$git clone Github url
$git remote set-url origin http://username:password@localhost:1234/root/helloworld.git

originの向き先がGitlabとなっている事を確認します。

$git config remote.origin.url 

pushしてみる

ではcloneしてきたリポジトリを編集してGitlabにpushし、その後、Githubに反映されているか確認します。

$vi README
$git add .
$git commit -m "Github"
$git push origin master
Hello-World [master] git push origin master
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 262 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: start pre-receive
remote: end pre-receive
remote: start post-update
remote: To https://username:password8@github.com/toshihirock/Hello-World.git
remote:    e9c6f5f..35d1433  master -> master
remote: end post-update
To http://username:password@localhost:1234/root/helloworld.git
   e9c6f5f..35d1433  master -> master

上記のようにHookスクリプトで標準出力される内容ははpush時に確認出来ます。(ユーザー名、パスワードは変更しています)

上記実施後、Githubでもpushしたコメントが反映されている事を確認できました。

また、上記の場合には取得元のパスワードがバレバレになるのでその場合にはpost-updateを以下に変更すれば出力がされないようになります。

git push origin ${BRANCH} >/dev/null 2>&1

本例ではhttpプロトコルで確認しましたが、sshプロトコルでも可能です。

2014年5月12日月曜日

Vagrant1.6のDockerの機能使ってコンテナにSSH接続してWebサーバー立ててみたよ

このエントリーをはてなブックマークに追加 はてなブックマーク - Vagrant1.6のDockerの機能使ってコンテナにSSH接続してWebサーバー立ててみたよ

Vagrant1.6からDockerを利用できるという事で色々使ってみたのでそのメモ。

Feature Preview: Docker-Based Development Environments

  • Imageを指定してコンテナを起動
  • Dockerfileを利用してコンテナの起動
  • コンテナにSSH接続してみる
  • SSH接続してWebサーバー立ててみる

確認環境

  • MaxOSX 10.9.2
  • Vagrant 1.6.1

そもそもMacやWindowsだとDockerって動かないのでは?

DockerはMacWindowsのOSでは利用出来ません。 そのため、VagrantではDockerを動かす為に専用LinuxVM(boot2docker)を起動して、その上でDockerを動作させます。

コンテナを起動する

Vagrantでコンテナを起動する方法として以下の2つがあります。

  1. Imageを指定する
  2. Dockerfileを利用してコンテナを起動する

1.Imageを指定する

以下のようにVagrantfileを作成します。

VAGRANTFILE_API_VERSION = "2" 

Vagrant.configure("2") do |config|
    config.vm.provider "docker" do |d| 
        d.image = "paintedfox/postgresql"
    end 
end

上記の例では以下を設定しています。

  • 利用するProviderはdockerを指定
  • 利用するイメージはpaintedfox/postgresqlを指定

次に以下のコマンドでコンテナを起動させます。

$vagrant up --provider=docker

上記によって以下が順番に実行されます。

  1. VM(boot2docker)が起動する
  2. VM(boot2docker)で指定したイメージをpullする
  3. VM(boot2docker)上でdockerを実行し、指定したコンテナをrunする

初回実行時にはイメージのダウンロードを行うため、通信環境によっては多少時間が掛かりますが、辛抱強く待ちます。あまりにも遅いとVagrantのboot_wait時間を超えて起動に失敗してしまいますので、通信環境の良い所で実行するのをおすすめします。(一度pullが終われば、以降はダウンロードする処理は実行されません)

終わった後にVagrantの状態を1.6の新機能global-statusを利用して確認してみます。

$vagrant global-status
id       name    provider   state     directory                                      
-------------------------------------------------------------------------------------
2a00b3b  default virtualbox running   /Users/toshihirock/.vagrant.d/data/docker-host 
3b48b7b  default docker     preparing /Users/toshihirock/vagrant/docker              

providerがvirtualboxとなっているのが、コンテナを動かす為に起動されたVMで、dockerとなっているのが先ほどrunしたコンテナになります。

boot2dockerのVMにも接続する事ができるので、こちらからもコンテナの状態を確認してみます。 ログインする際にはglobal-statusで確認したidを指定します。

$vagrant ssh 2a00b3b 
                        ##        .
                  ## ## ##       ==
               ## ## ## ##      ===
           /""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
           \______ o          __/
             \    \        __/
              \____\______/
 _                 _   ____     _            _
| |__   ___   ___ | |_|___ \ __| | ___   ___| | _____ _ __
| '_ \ / _ \ / _ \| __| __) / _` |/ _ \ / __| |/ / _ \ '__|
| |_) | (_) | (_) | |_ / __/ (_| | (_) | (__|   <  __/ |
|_.__/ \___/ \___/ \__|_____\__,_|\___/ \___|_|\_\___|_|
boot2docker: 0.8.0
$docker ps -a
CONTAINER ID        IMAGE                          COMMAND                CREATED             STATUS                     PORTS               NAMES
2dc46197e3be        paintedfox/postgresql:latest   /scripts/start.sh /s   7 minutes ago       Exited (1) 2 minutes ago                       docker_default_1399814767  
$exit

既に処理を実行し、終了している事が確認できました。

Vagrantで経由でDockerの操作を行った際に何か困った事があれば、上記VMにSSHログインして調査すれば問題が解決しやすいかと思います。

コンテナの削除はvagrant destoryでvagrant global-statusで確認したidを指定すればOKです。 idは全て入力する必要はなく、一意に指定できれば良いので以下のようにしても動作が可能です。

$vagrant destroy 3

2.Dockerfileを指定する

以下のようにVagrantfileを作成します。

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure("2") do |config|
    v.vm.provider "docker" do |d|
        d.build_dir = "."
    end
end

上記の例では以下を設定しています。

  • 利用するProviderはdockerを指定
  • 利用するDockerifleはVagrantfileと同じディレクトリに配置

Dockerfileは先ほどと同じイメージを利用するようにしました。

FROM aintedfox/postgresql

これで先ほど同様にvagrant upすればOKです。

$vagrant up --provider=docker

1.Imageを指定するの手順を実行した後、上記を実行するとかなり早くコンテナの起動が出来るかと思います。

VM(boot2docker)の起動処理の時間とイメージをpullしてくる時間が省略された為です。

なお、VM(boot2docker)を削除すると、イメージを再度pullしてくる必要があるので必要です。

終わった後はコンテナを削除します。

$vagrant destroy 3

コンテナにSSH接続してみる

sshdのサービスを起動させるイメージを利用する事でVMと同じようにコンテナにもSSH接続が可能なようで試してみます。

以下のようなVagrantfileを用意します。

VAGRANTFILE_API_VERSION = "2" 

Vagrant.configure("2") do |config|
    config.vm.define "phusion" do |v| 
        v.vm.provider "docker" do |d| 
            d.cmd = ["/sbin/my_init", "--enable-insecure-key"]
            d.image = "phusion/baseimage:latest"
            d.has_ssh = true
        end 
        v.ssh.username = "root"
        v.ssh.private_key_path= "insecure_key"
        v.vm.provision "shell", inline: "echo hello"
    end 
end

上記の例では以下を設定しています。

  • 利用するProviderはdockerを指定
  • 利用するイメージはphusion/baseimageの最新(latest)
  • /sbin/my_initというコマンドを引数–enable-insecure-keyを指定して実行。
  • VagrantでSSHを利用する事を指定
  • SSHでログインするユーザーはroot
  • SSHでログインする際に利用する鍵はinsecure_key(詳細は後述)
  • コンテナの処理が完了したらhelloと出力する。

詳細は公式ドキュメントをご確認頂きたいのですが、本例では指定してるイメージがphusion/baseimageである事が大切です。

このイメージのドキュメントに詳細が書いてありますが、恐らく初期化処理の中でssdhのサービスを起動させる処理があり、これによってコンテナにも関わらず、SSH接続を可能にしているようです。

つまり全てのイメージでSSH接続が出来るという訳ではないのです

また、上記コンテナへのSSH接続は必ず指定された鍵を利用して認証を行う必要があります。そのため、以下のコマンドでVagrantfileと同じディレクトリに予めSSHで利用する鍵を配置しておく必要があります。

$curl -o insecure_key -fSL https://github.com/phusion/baseimage-docker/raw/master/image/insecure_key
$chmod 600 insecure_key

上記準備ができたら今まで同様に起動させます。

$vagrant up --provider=docker
・・・・
==> phusion: hello

正しく処理が完了した場合には、helloという出力がされる事も確認出来るかと思います。 ではコンテナにSSH接続してみます。

$vagrant ssh
==> phusion: SSH will be proxied through the Docker virtual machine since we're
==> phusion: not running Docker natively. This is just a notice, and not an error.
Warning: Permanently added '172.17.0.2' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 12.04.4 LTS (GNU/Linux 3.8.0-35-generic x86_64)

 * Documentation:  https://help.ubuntu.com/
 root@cb4eb5281f86:~#

イメージのベースはUbuntu12.04であり、そのコンテナにVagrantを利用して簡単にSSH接続する事が出来ました!

確認後、コンテナは削除します。

$vagrant destroy 3

SSH接続してWebサーバー立ててみる

単純にSSH接続出来ただけだと意味が無いので、実際にローカルマシン(vagrantを動かしているマシン)からアクセス出来るようにしてみます。

上記については既にブログに記載している方がいらっしゃり、とても分かりやすく説明されています。

Vagrant1.6のDocker Provider

が、一応こちらでも記載します。(上記ブログの方の方が分かりやすいです!)

ローカルマシンからのアクセスを実現する為には、ローカルマシン→VM(boot2docker)→コンテナと接続しなければいけません。 つまり、ポートフォワードを2カ所(ローカルマシン→VM。VM→コンテナ。) で設定する必要があります。

VM→コンテナについては今まで編集してきたVagrantfileにポートフォワードの設定を記載すればOKです。

ローカルマシン→VM間のポートフォワードを指定する場合には、新しくVagrantfileを作成する必要があります。VM→コンテナ間のVagrantfileに以下のように追記を行います。

d.vagrant_vagrantfile = "host-vm/Vagrantfile"

指定した場所にVagrantfileを配置する必要があるのですが、デフォルトでVM(boot2docker)に適用されるVagrantfileがあるのでそれに追記を行います。

$mkdir host-vm && cd host-vm
$wget https://raw.githubusercontent.com/mitchellh/vagrant/master/plugins/providers/docker/hostmachine/Vagrantfile

配置したファイルにポートフォワードに関する追記を行うと以下のようになります。

Vagrant.configure("2") do |config|
  config.vm.box = "mitchellh/boot2docker"

  config.vm.provider "virtualbox" do |v|
    # On VirtualBox, we don't have guest additions or a functional vboxsf
    # in TinyCore Linux, so tell Vagrant that so it can be smarter.
    v.check_guest_additions = false
    v.functional_vboxsf     = false
  end

  ["vmware_fusion", "vmware_workstation"].each do |vmware|
    config.vm.provider vmware do |v|
      if v.respond_to?(:functional_hgfs=)
        v.functional_hgfs = false
      end
    end
  end

  # b2d doesn't support NFS
  config.nfs.functional = false
  config.vm.network :forwarded_port, guest: 8080, host: 8080
end

同じようにVM→コンテナ間のVagrantfileにもポートフォワードに関する追記を行います。最終的には以下のようになります。

VAGRANTFILE_API_VERSION = "2" 

Vagrant.configure("2") do |config|
    config.vm.define "phusion" do |v| 
        v.vm.provider "docker" do |d| 
           d.vagrant_vagrantfile = "host-vm/Vagrantfile"
                d.cmd = ["/sbin/my_init", "--enable-insecure-key"]
                d.image = "phusion/baseimage:latest"
                d.has_ssh = true
        end 
        v.ssh.username = "root"
        v.ssh.private_key_path= "insecure_key"
        v.vm.provision "shell", inline: "echo hello"
        v.vm.network :forwarded_port, guest: 80, host: 8080
    end 
end

準備ができたので、順番に操作をしていきます。

まず、VM(boot2docker)を一度停止します。 Vagrantfileを明示的に指定すると別のVM(boot2docker)が起動するのですが、その際に既に起動しているものとポートがバッティングしてエラーとなる為です。恐らく回避方法もありそうな気がしますが。。。

$vagrant halt {vm_id}

次にVM(boot2docker)とコンテナを起動します。

$vagrant up --provider=docker

次にコンテナにSSH接続してnginxをインストールし、サービスを起動します。

$vagrant ssh
$apt-get update
$apt-get install -y nginx
$service nginx start
$exit

これで準備完了です。

ローカルマシンからブラウザでhttp://localhost:8080/にアクセスしてみます。

コンテナのnginxのWebページを表示する事が出来ました。

最後に

実際に動いているのはコンテナでもVagrantを利用する事でさもVMを利用しているかのように操作を出来るこの機能はとても素晴らしいと思います。

Dockerにも任意のprovisonが適応できるようなので、Chefとか流したりもきっと出来そうな。今度時間があればやってみたい。。。

2014年5月10日土曜日

Vagrant1.6のGlobalStatus and Controlが地味に便利だった話

このエントリーをはてなブックマークに追加 はてなブックマーク - Vagrant1.6のGlobalStatus and Controlが地味に便利だった話

Vagrant1.6の大きな変更の一つ、GlobalStaus and Controlが地味に便利だったのでメモ。

この機能を使うと

  • Vagnratで管理しているVMの一覧とその状態などが確認出来る
  • いちいちVagrantfileのあるディレクトリに移動しなくてもVMの操作が可能。(起動、中断、SSH接続など)

という事が出来ます。

なお、公式のドキュメントは こちら参照のこと。

準備

Vagrant1.6をまだインストールしていない人はインストール(アップグレード)しましょう。

$vagrant -v
Vagrant 1.6.1

なお、アップグレードの場合のみだと思われますが、私の環境ではvagrant global-statusコマンドを初回実行時に以下のような事を言われました。

Vagrant is upgrading some internal state for the latest version. Please do not quit Vagrant at this time. While upgrading, Vagrant will need to copy all your boxes, so it will use a considerable amount of disk space. After it is done upgrading, the temporary disk space will be freed.

Press ctrl-c now to exit if you want to remove some boxes or free up some disk space.

Press any other key to continue.

vagrantのアップグレードで一時的にBoxのコピーが必要だからその間Vagrantを止めないでね、もし、ディスクスペースが少ない場合にはctrl-cで中断してBox削除してね、問題なければそれ以外のコマンド押してね、という感じっぽいです。(適当)

よっぽどディスクが逼迫していなければEnterキー押してしまって良い思います。

コマンド実行してみる

早速使ってみます。最初に書いたように実行はどこのディレクトリでもOKです。

$vagrant globa-status
id       name    provider   state    directory                              
----------------------------------------------------------------------------
4d3ea23  default virtualbox poweroff /Users/toshihirock/vagrant/ubuntu12_32 
96c9db6  default virtualbox running  /Users/toshihirock/vagrant/ubuntu14_64 

The above shows information about all known Vagrant environments
on this machine. This data is cached and may not be completely
up-to-date. To interact with any of the machines, you can go to
that directory and run Vagrant, or you can use the ID directly
with Vagrant commands from any directory. For example:
"vagrant destroy 1a2b3c4d"

上記のようにVagrantで管理しているVMの一覧とその状態及びVagrantfileの位置などが分かります。

個人的にあれVagrantfileどこだっけ??という事がたまにあるのでVagrantfileの配置されたディレクトリが分かるのが嬉しいです。

今まで無かった情報としてVMごとに一意に決められたIDについても表示がされています。 これを使う事でVagrantfileのある場所に移動しなくても指定VMへの操作が出来ます。

例えばIDが96c9db6となっているVMにSSH接続したい場合には以下のようにします。

$vagrant ssh 96c9db6

公式ドキュメントを見る限り、SSHは勿論、updestorysuspendなど基本的な操作も可能なようです。

また、こちらは公式には書いてませんでしたが、全てのIDを入力しなくても一意にIDできるまでの入力のみでもコマンド実行が可能なようです。

$vagrant ssh 9

これも覚えておくと地味に便利ですね。

2014年5月1日木曜日

Chefのレシピ管理ツールBerkshelfのversion3のドキュメントを和訳してみた

このエントリーをはてなブックマークに追加 はてなブックマーク - Chefのレシピ管理ツールBerkshelfのversion3のドキュメントを和訳してみた

Chefの管理ツールであるBerkshlefのversion3がやっとでリリースされ、しかもChef-DK(Chef Deploymant Kit)とかいうのSDKにも内包されるようになったようで、せっかくなのでversion3のドキュメントを非公式に和訳してみました。

今回、GithubのREADME.mdに書いてみました。

Github-TranslateBerkshelf

色々良い訳。

  • 本ページはBerkshelf version3のドキュメント非公式に和訳したものです。
  • 2014年5月1日時点のものを参照したため、今後変更となる箇所がある可能性もあります。
  • 意訳した箇所もあります。
  • 動作確認を行えなかった箇所も多い為、その点はご了承ください。
  • 英語が得意!という訳でもないので、すいません、その点もご了承ください。
  • 記述誤りなどは @toshihirockまでご連絡頂くか、pull requestして頂くなどして頂ければ幸いです。

なお、vagrant berkshelfプラグインですが、私の環境では正しく動きませんでした。。。

vagrant-berkshelfは非推奨になるとのこと

上記記事からも非推奨となるようで、Vagrantと組み合わせて使う場合でも 以前ブログに書いたように使った方が良さそうな気がしました。