環境依存ってめんどくさい
昨日とあるchefの勉強会に参加しました。
そこではみんな直ちにchefりたいという気持ちとは裏腹に、環境まわり(特にWindowsユーザー)で詰まってなかなか進まないという問題がありました。rubyのバージョン、パス、sshなど等。。。
なのでまずはお勉強環境を統一するためにvagrantでホストの上にホストとなるゲストを作りましょう。
ホストでの作業
仮想環境の準備
まずはvagrantが動く環境を作ります。windowsの人もMacの人も、VirtualBoxとVagrantをインスコしましょう。これらは各OS毎にインストーラーが提供されているので、問題なく準備できるはずです。
vagrantでさっくりと
まずはvagrantの作業用ディレクトリを作ります。
mkdir vagrant cd vagrant mkdir share
んでもってVagrantfileを作ります。vagrantはこのファイルの中身に従って自動で仮想環境を作ってくれます。shareディレクトリは仮想マシンを起動した後で使用するので、追って説明します。
ip_address = "192.168.10.10"
Vagrant.configure("2") do |config|
config.vm.box = "CentOS-6.5"
config.vm.box_url = "http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.5-x86_64-v20140110.box"
config.vm.network :private_network, ip: ip_address
config.vm.synced_folder "share", "/home/vagrant/share"
config.vm.provision :shell, :path => "provision.sh"
end
ipアドレスなどは適当に編集してください。この設定では最低限の設定などを行っているだけで、実際のサーバー設定(プロビジョニング)はprovision.sh内で行っています。
#!/bin/sh
# dockerをインスコする
yum -y install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
yum -y install docker-io git jq
service docker start
chkconfig docker on
usermod -G docker vagrant
# chefをインスコする
curl -L https://www.opscode.com/chef/install.sh | sudo bash
# knife-soloをインスコする
/opt/chef/embedded/bin/gem install knife-solo -no-ri -no-rdoc
# dockerコンテナにSSHするための準備
cp /vagrant/share/id_rsa.docker /home/vagrant/.ssh/id_rsa
cp /vagrant/share/id_rsa.docker.pub /home/vagrant/.ssh/id_rsa.pub
chown -R vagrant:vagrant /home/vagrant/.ssh
chmod -R g-rwx,o-rwx /home/vagrant/.ssh
これは普通のシェルスクリプトです。vagrantを使わずに仮想マシンをセットアップした場合でいうところの、OSのインストール後rootでログインしてこのスクリプトを流すような感じです。vagrantはこれを自動でやってくれます。
provision.shの内容ですが、大きくわけて3つのことをやっています。
- dockerのインストール
- chefのインストール
- dockerへのアクセス準備
です。dockerはこれからchefる対象のゲスト環境を作るのに必要なです。
次にchefのインストールです。インストールにはchefが用意してくれてるomnibusインストーラを使います。
最後にchefが動く対象となるdockerコンテナへのアクセス用設定です。あらかじめshare以下でssh-keygen -t rsa
して鍵をつくっておきましょう。
これでvagrantの準備は完了したので、コマンドラインから
vagrant up
を実行してください。各種ソフトのインスコに時間がかかりますが、数分後には仮想マシンが立ち上がります。
また、初回に限りOSのイメージをDLするのでそれなりの時間はかかってしまいます。2回め以降はイメージを削除しない限り再利用するので、時間はかなり短縮されます。
vagrantへssh
お勉強の舞台である仮想環境は起動したので、さっそくsshでログインします。
Vagrantfileで指定したIPアドレスにvagrantユーザーでログインできます(パスワードもvagrant)。
ログインすると、ホームディレクトリにshareというディレクトリがあります(正確にはシンボリックリンク)。この中身が手順の最初で作ったホストのvagrant/shareディレクトリになっています。
実際は/vagrant/shareへのリンクになっていて、vagrantが勝手にホストのvagrantディレクトリを/vagrant以下にマウントしてくれています。そのディレクトリにリンクを張ったものです。
実際にshare以下に適当にファイルを作ると(date > share/hoge
)ホストにもhogeが作成されていることが確認できます。
ここで作業をすることで、仮想マシンを作り直しても成果物をホストに残すことができます。
あとついでにchef-soloやknifeコマンドが動くことも確認しておいてください。
docker
次にchefがcookする対象のサーバーを用意します。
share以下にDockerfileを作ります。
FROM ubuntu:14.04
RUN apt-get update && apt-get -y upgrade
RUN apt-get install -y openssh-server chef
RUN mkdir -p /var/run/sshd
RUN useradd -d /home/docker -m -s /bin/bash docker
RUN echo docker:docker | chpasswd
RUN echo 'docker ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
RUN sed -ri 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
RUN mkdir -p /var/run/sshd && chmod 755 /var/run/sshd
ADD id_rsa.docker.pub /home/docker/.ssh/authorized_keys
RUN chown -R docker /home/docker/.ssh
RUN chmod -R g-rwx,o-rwx /home/docker/.ssh
CMD /usr/sbin/sshd -D
内容はubunt:14.04をベースにapt-getでsshdをインストールし、鍵の設定をしているだけです。頭にRUNやCMDがついてますが、大体は普通のシェルスクリプトですが、apt-getでchefをインストールしておくのと、ADDコマンドでローカル(vagrant)の鍵をdockerコンテナに追加しているのがポイントです。
Dockerfileが準備できたらいよいよコンテナを起動させます。
と、その前に起動するコンテナのイメージを作ります。Dockerfileがあるディレクトリでdocker build test:01 .
を実行します。するとubuntu:14.04をベースにDockerfileで設定した内容にしたがって新たなコンテナイメージtest:01
を作ってくれます。作ったコンテナはdocker images
で確認ができます。
test:01ができていたらこれを起動しますdocker run -d test:01
。
buildに比べてrunはあっさり終わりましたが、これでコンテナが起動しました。
docker ps
でtest:01が起動中であることを確認できます。
コンテナへのssh
次に起動したtest:01へsshします。まずは対象のIPアドレスを調べます。
docker ps
でコンテナのIDがわかる(今回の例ではbd1c21e8ecc0
)ので、それに対してdocker inspect bd1c21e8ecc0
を実行します。するとコンテナの情報がjsonでずらずら出てくるので、この中からIPアドレスを調べます。
vagrantにはjqを入れてあるので、docker inspect bd1c21e8ecc0 | jq ".[0].NetworkSettings.IPAddress"
でipを調べ、.ssh/configにssh設定を行います。
host docker
hostname [コンテナのIP]
user docker
port 22
identityfile ~/.ssh/id_rsa
パミッションの設定も忘れずにchmod 700 ~/.ssh/config
しておきます。この状態でssh docker
でログインできることを確認します。
やっとchef
ここまでの作業でホスト環境に依存しないknifeの実行環境(vagrant)と、いつでも作り直せる調理対象(docker)が出来上がりました。
適当な作業ディレクトリを作りdockerに対してknifeを実行してみます。
mkdir knife cd knife knife solo init . knife solo bootstrap docker
knifeが無事に実行されましたか。
やりなおしたい
chefのテストなどで、一度まっさらな環境からやり直したい場合ときは、コンテナを作り直します。
まずは起動中のコンテナを破棄します。
docker rm -f bd1c21e8ecc0
するとdocker ps
がまっさらになるので、docker run -d test:01
からやり直せます。一度イメージを作った後なので、一瞬でやり直せます。なんどでもお手軽にやり直せるのがdockerのいいところです。
最後に
当方がまだchefの勉強お始めたばかりなので、chefの内容については空っぽです。しかし、chefを勉強するための環境は整えれたので、これから勉強を続けていくことができるようになりました。
また、ほかの人の環境でもvagrant up
するだけで同じ環境を構築できるので、ホストマシンに依存する問題がなくなり勉強だけに集中できるようになりました。
##成果物
ここで作ったものはgithubに上げてあるので、よかったらお使いください。