夏頃にDockerコンテナというベータ版がリリースされたはずですが
それとは違い、Chef-soloをキックする方法です。
そんな素晴らしい手法を紹介していた参考サイト。
Dockerイメージをchef-soloでプロビジョニングする | Developers.IO:
こういう事が発見&実行できる人がうらやましいですぞ。
まず最初の目的はSinatraの環境をさくっと作っちゃう事です。前回は手作業で作って途中でDockerコンテナをコミットしておけばいつでもそこから出来る!っとか言ってましたが、出来上がってから考えると、めんどくさいっちゅうの&管理が大変だっちゅうの。
Chefで管理した方がいいでしょう。というのも最近コード化をちょこっとやった影響もあるのでしょう。
コンテナをコミットしていくのもいつでも使いたい時に鬼速で起動できるというメリットはあるにはありますが、中の構成はハッキリ言うて時間の経過とともに分かりませんになっていく。
てなわけで、いわゆるコード化をやるっちゅうの。
RedmineのDockerfileを過去に作っているのですが
redmineのDockerfileがやっとできた
Dockerfileで進めてもいいんですが、まぁ過去の事は置いといてここ数日の流れからせっかくだしRubyで行こうぜと。楽しいし。と言うことです。
まずは原理を知るために使用するレシピは単にApacheをインストールするだけのものです。
Chefを触るのはちょっと久し振りなのでリハビリも兼ねてです。
ホストサーバーはruby gem chef knife-soloが使える環境って事で最初は省略するなり。
ツリーはこんな感じになりました。
$ tree
.
├── Dockerfile
└── chef-repo
├── cookbooks
│ └── apache
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── attributes
│ ├── definitions
│ ├── files
│ │ └── default
│ ├── libraries
│ ├── metadata.rb
│ ├── providers
│ ├── recipes
│ │ └── default.rb
│ ├── resources
│ └── templates
│ └── default
├── data_bags
├── environments
├── nodes
│ └── docker.json
├── roles
├── site-cookbooks
└── solo.rb
手抜きではなくて、こっちの方が自分でもいいと思ったので、一気にコマンドオンリー(ほぼ)でいきます。
$ mkdir chef-sinatra
$ cd chef-sinatra
$ rbenv global 2.1.5
$ ruby -v
ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-linux]
$ rbenv rehash
$ gem -v
2.2.2
$ gem install chef --no-ri --no-rdoc
$ knife configure
$ gem install knife-solo --no-ri --no-rdoc
クックブックを作成しよう。
$ cd chef-repo
リポジトリ作成
$ knife cookbook create apache
$ vi cookbooks/apache/recipes/default.rb
$ cat chef-repo/cookbooks/apache/recipes/default.rb
#
# Cookbook Name:: apache
# Recipe:: default
#
# Copyright 2014, YOUR_COMPANY_NAME
#
# All rights reserved - Do Not Redistribute
#
package "httpd" do
action :install
end
service "httpd" do
action [ :enable, :start ]
end
続いてはDockerfile作成
chef-solo -o レシピ名 だと上手くいかなかったのね。
結局のとこsolo.rbがないよ?と聞かれるので、参考サイトとほぼ同じ感じになりました。
$ cat Dockerfile
FROM centos:centos6
MAINTAINER takekentw
ENV HOME /chef-repo
ADD chef-repo /chef-repo
RUN curl -L http://www.opscode.com/chef/install.sh | bash
RUN cd ${HOME} && chef-solo -c ${HOME}/solo.rb -j ${HOME}/nodes/docker.json
では、コンテナを作ります。
$ sudo docker build -t centos:build .
Sending build context to Docker daemon 24.58 kB
Sending build context to Docker daemon
Step 0 : FROM centos:centos6
---> 25c5298b1a36
~~ 中略 ~~
Thank you for installing Chef!
---> ebd58aa8e77d
Removing intermediate container bd030c4e2254
Step 5 : RUN cd ${HOME} && chef-solo -c ${HOME}/solo.rb -j ${HOME}/nodes/docker.json
---> Running in 76e096bf5c8b
[2014-12-06T00:43:52+00:00] INFO: Forking chef instance to converge...
[2014-12-06T00:43:52+00:00] INFO: *** Chef 12.0.0 ***
[2014-12-06T00:44:06+00:00] INFO: service[httpd] enabled
~~ 中略 ~~
Removing intermediate container 76e096bf5c8b
Successfully built 396e4e905e33
出来上がりました。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos build 396e4e905e33 About a minute ago 418.9 MB
起動してみます。
$ sudo docker run -it -p 80 --name chef_01 centos:build /bin/bash
bash-4.1#
bash-4.1# whoami
root
bash-4.1# service httpd status
httpd dead but pid file exists
bash-4.1# service httpd start
Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.14 for ServerName
[ OK ]
ここでコンテナからデタッチしました。[ Ctrl+p q ]
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ad3082574949 centos:build "/bin/bash" 32 seconds ago Up 31 seconds 0.0.0.0:49154->80/tcp chef_01
接続テスト。
$ curl http://localhost:49154
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<head>
<title>Apache HTTP Server Test Page powered by CentOS</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
うむうむ。
では問題なさそなので、昔に作ったbaseも試してみよう。ちなみにbaseレシピとはtakekenというユーザーの作成と基本的なパッケージをインストールするものです。
やってみると結構忘れているのでリハビリはまだ続けるのです。
ほぼ忘れてましたが、外部のCookbooksを使うのでberkshelfを入れてインストールしてcookbooksを生成しときます。
$ gem install berkshelf
ひな形を作成します。
$ knife solo init .
んでこれも忘れがちになる。
過去に試した時とberksでcookbooksを取りに行く取得先も変わったようだ。
$ berks install
中身はこんな感じです。
過去に作った使いまわしなのですけどね。
$ tree
.
├── Dockerfile
└── chef-repo
├── Berksfile
├── Berksfile.lock
├── cookbooks
│ ├── selinux
│ │ ├── CHANGELOG.md
│ │ ├── README.md
│ │ ├── attributes
│ │ │ └── default.rb
│ │ ├── libraries
│ │ │ └── selinux_service_helpers.rb
│ │ ├── metadata.json
│ │ ├── providers
│ │ │ └── state.rb
│ │ ├── recipes
│ │ │ ├── _common.rb
│ │ │ ├── default.rb
│ │ │ ├── disabled.rb
│ │ │ ├── enforcing.rb
│ │ │ └── permissive.rb
│ │ ├── resources
│ │ │ └── state.rb
│ │ └── templates
│ │ └── default
│ │ └── sysconfig
│ │ └── selinux.erb
│ └── yum
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── attributes
│ │ └── main.rb
│ ├── libraries
│ │ └── matchers.rb
│ ├── metadata.json
│ ├── providers
│ │ ├── globalconfig.rb
│ │ └── repository.rb
│ ├── recipes
│ │ └── default.rb
│ ├── resources
│ │ ├── globalconfig.rb
│ │ └── repository.rb
│ └── templates
│ └── default
│ ├── main.erb
│ └── repo.erb
├── data_bags
├── environments
├── nodes
│ └── docker.json
├── roles
├── site-cookbooks
│ └── base
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── attributes
│ ├── definitions
│ ├── files
│ │ └── default
│ ├── libraries
│ ├── metadata.rb
│ ├── providers
│ ├── recipes
│ │ └── default.rb
│ ├── resources
│ └── templates
│ └── default
│ └── sudoers.erb
└── solo.rb
site-cookbooks/base/templates/default/sudoers.erbはsuduersファイルほぼそのままでwheelを有効にした程度です。
$ cat site-cookbooks/base/recipes/default.rb
#
# Cookbook Name:: base
# Recipe:: default
#
# Copyright 2014, YOUR_COMPANY_NAME
#
# All rights reserved - Do Not Redistribute
#
# 外部cookbookを利用してepelをインストール
yum_repository 'epel' do
description 'Extra Packages for Enterprise Linux'
# url 'http://ftp.riken.jp/Linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm'
# gpgkey 'http://ftp.riken.jp/Linux/fedora/epel/RPM-GPG-KEY-EPEL-6'
mirrorlist 'http://mirrors.fedoraproject.org/mirrorlist?repo=epel-6&arch=$basearch'
gpgkey 'http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6'
action :create
end
# 基本的なパッケージをインストール
%w{ gcc make openssh-server kernel-devel zlib-devel openssl-devel readline-devel perl wget curl bind-utils git ntp openssh-clients rsync sysstat vim sudo }.each do |p|
package p do
action :install
end
end
# 外部cookbookを利用してselinuxを無効
selinux_state "SELinux Disabled" do
action :disabled
end
# 作業ユーザー作成
user "takeken" do
comment "takeken"
home "/home/takeken"
shell "/bin/bash"
password "$1$Sdk6GWI3$8wCs/GirgmAfyjEd3K8rp/"
supports :manage_home => true, :non_unique => false
action [:create, :manage]
end
#
group "wheel" do
action :modify
members [ 'takeken' ]
append true
end
#
template "sudoers" do
owner "root"
group "root"
path "/etc/sudoers"
mode "0440"
source "sudoers.erb"
end
$ cat Berksfile
source "https://supermarket.getchef.com"
cookbook 'yum'
cookbook 'selinux'
$ cat nodes/docker.json
{
"run_list" : [
"yum",
"recipe[selinux::disabled]",
"recipe[base]"
]
}
$ cat solo.rb
file_cache_path "/tmp/chef-solo"
cookbook_path [
"/chef-repo/site-cookbooks",
"/chef-repo/cookbooks"
]
このくらいかしらね。
ではbuildします。
$ sudo docker build -t base:base_03 . Sending build context to Docker daemon 130 kB Sending build context to Docker daemon ---> Running in 9013228dd96c [2014-12-06T11:05:33+00:00] INFO: Forking chef instance to converge... [2014-12-06T11:07:07+00:00] INFO: Report handlers complete ---> 916d8c4850fc Removing intermediate container 9013228dd96c Successfully built 916d8c4850fc だいぶ端折っていますが、だいたい2分くらいですな。 ドッカー\(^o^) [bash] $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE base base_03 cfc1865ce4c6 About a minute ago 797.9 MB [root@aeb9ed08e4d3 ~]# id uid=0(root) gid=0(root) groups=0(root) [root@aeb9ed08e4d3 ~]# ls -l /home total 4 drwx------. 2 takeken takeken 4096 Dec 6 11:07 takeken
出来上がりました~。sshdってコンテナじゃあいらないのでほんとにただのリハビリになりました。もしsshを使うとして注意すべきところはPassword許可と、PAMをNoにすることでした。
作ってみた感想は欲しい環境によってVirtualBoxなりKVMなりDockerなりを使い分けた方が最終的なコストはベストな選択をするのが最もよさげです。
ではこの辺で。
次回にSinatra環境ができるかどうかは分かりません。なんとなくRubyだけで何か作ろうとしてみたりしていると思いますが、何をやるか分かりません。