インフラのコード化にちょこっと触れてみる


さっそくサーバ/インフラ徹底攻略(技術評論社)を参考にインフラのコード化に触れてみたいと思います。

VirtualBOXのインストール

https://www.virtualbox.org/wiki/Linux_Downloads
公式サイトにマニュアルもあります。

まずは/etc/apt/source.listを編集します。

$ cat /etc/apt/source.list
deb http://download.virtualbox.org/virtualbox/debian trusty contrib

公開鍵をコピペしてきて取り込みます。

takeken@ubuntu:~$ vim oracle_vbox.asc
takeken@ubuntu:~$ sudo apt-key add oracle_vbox.asc
OK

aptをupdateして、インストールします。

takeken@ubuntu:~$ sudo apt-get update
takeken@ubuntu:~$ sudo apt-get install virtualbox
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下の特別パッケージがインストールされます:
  dkms fakeroot libaudio2 libcaca0 libfakeroot libgsoap4 libmysqlclient18
  libqt4-declarative libqt4-network libqt4-opengl libqt4-script libqt4-sql
  libqt4-sql-mysql libqt4-xml libqt4-xmlpatterns libqtcore4 libqtdbus4
  libqtgui4 libsdl1.2debian libvncserver0 mysql-common qtcore4-l10n
  virtualbox-dkms virtualbox-qt
提案パッケージ:
  dpkg-dev debhelper nas libqt4-declarative-folderlistmodel
  libqt4-declarative-gestures libqt4-declarative-particles
  libqt4-declarative-shaders qt4-qmlviewer libqt4-dev libicu48 qt4-qtconfig
  libvncserver0-dbg virtualbox-guest-additions-iso vde2
以下のパッケージが新たにインストールされます:
  dkms fakeroot libaudio2 libcaca0 libfakeroot libgsoap4 libmysqlclient18
  libqt4-declarative libqt4-network libqt4-opengl libqt4-script libqt4-sql
  libqt4-sql-mysql libqt4-xml libqt4-xmlpatterns libqtcore4 libqtdbus4
  libqtgui4 libsdl1.2debian libvncserver0 mysql-common qtcore4-l10n virtualbox
  virtualbox-dkms virtualbox-qt
アップグレード: 0 個、新規インストール: 25 個、削除: 0 個、保留: 0 個。
32.9 MB のアーカイブを取得する必要があります。
この操作後に追加で 132 MB のディスク容量が消費されます。
続行しますか? [Y/n]
DKMS: install completed.
 * Stopping VirtualBox kernel modules                                                        [ OK ]
 * Starting VirtualBox kernel modules                                                        [ OK ]
libqtgui4:amd64 (4:4.8.5+git192-g085f851+dfsg-2ubuntu4) を設定しています ...
libqt4-declarative:amd64 (4:4.8.5+git192-g085f851+dfsg-2ubuntu4) を設定しています ...
libqt4-opengl:amd64 (4:4.8.5+git192-g085f851+dfsg-2ubuntu4) を設定しています ...
virtualbox-qt (4.3.10-dfsg-1) を設定しています ...
Processing triggers for libc-bin (2.19-0ubuntu6.3) ...

最初のパッケージのDLいらなくね?って気がするんだけれど、まぁいいか。


 

続いてVagrantのインストール

aptだと1.4.3だったので、公式からDLしたものをインストール。

takeken@ubuntu:~$ wget https://dl.bintray.com/mitchellh/vagrant/vagrant_1.6.5_x86_64.deb
takeken@ubuntu:~$ sudo  dpkg -i vagrant_1.6.5_x86_64.deb
(データベースを読み込んでいます ... 現在 105734 個のファイルとディレクトリがインストールされています。)
Preparing to unpack vagrant_1.6.5_x86_64.deb ...
Unpacking vagrant (1:1.6.5) over (1.4.3-1) ...
vagrant (1:1.6.5) を設定しています ...
Processing triggers for man-db (2.6.7.1-1ubuntu1) ...
takeken@ubuntu:~$ vagrant -v
Vagrant 1.6.5

本書に従って初回の仮想イメージを取得してみます。

takeken@ubuntu:~$ vagrant box add centos http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5_chef-provisionerless.box
==> box: Adding box 'centos' (v0) for provider:
    box: Downloading: http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-6.5_chef-provisionerless.box
==> box: Successfully added box 'centos' (v0) for 'virtualbox'!

takeken@ubuntu:~$ vagrant init centos
A Vagrantfile has been placed in this directory. You are now
ready to vagrant up your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
vagrantup.com for more information on using Vagrant.

upは権限的にsudoが必要らしい。NATの設定から何からなにまで
全部やってくれるようだ。

takeken@ubuntu:~$ sudo vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'centos'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: takeken_default_1415349675419_50777
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
    default: 22 => 2222 (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection timeout. Retrying...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Mounting shared folders...
    default: /vagrant => /home/takeken

sshもsudoが必要だった。いつのことだったかDockerを初めて試した時に

「ありのままに起こった事を話すぜ。CentOSを使っていたと思ったらいつの間にかubuntuだった。」
みたいなネタの話をしていたけれど、今まさにその逆だな。


コンテナじゃねーけど。

takeken@ubuntu:~$ sudo vagrant ssh
Last login: Fri Mar  7 16:57:20 2014 from 10.0.2.2

[vagrant@localhost ~]$ uname -a
Linux localhost.localdomain 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

[vagrant@localhost ~]$ cat /etc/redhat-release
CentOS release 6.5 (Final)

Chefを入れまする

ところでChefもPuppetと同じくServerとスタンドアロンの2つがあります。
PuppetではいきなりServer&Clientでいきましたが、ここは本をなぞっているので
Chef Soloでいきます。

[vagrant@localhost ~]$ sudo bash -c "curl -L https://www.opscode.com/chef/install.sh | bash"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 16472  100 16472    0     0  10456      0  0:00:01  0:00:01 --:--:-- 30674
Downloading Chef  for el...
downloading https://www.opscode.com/chef/metadata?v=&prerelease=false&nightlies=false&p=el&pv=6&m=x86_64
  to file /tmp/install.sh.1518/metadata.txt
trying wget...
url     https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chef-11.16.4-1.el6.x86_64.rpm
md5     2355a7a93bc4cc353bee6de9e3bcb7ba
sha256  278599ff185b680703e7a779db8674eeba843e9fe42a0ae06e01a9dfa9ac4d0e
downloaded metadata file looks valid...
downloading https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chef-11.16.4-1.el6.x86_64.rpm
  to file /tmp/install.sh.1518/chef-11.16.4-1.el6.x86_64.rpm
trying wget...
Comparing checksum with sha256sum...
Installing Chef
installing with rpm...
警告: /tmp/install.sh.1518/chef-11.16.4-1.el6.x86_64.rpm: ヘッダ V4 DSA/SHA1 Signature, key ID 83ef826a: NOKEY
準備中...                ########################################### [100%]
   1:chef                   ########################################### [100%]
Thank you for installing Chef!

これでVagrant+VirtualBOX+Chef+Ubuntuな環境が出来上がりました。

では全く同じ事をするんもいいけれど、少し変えてみて自分でも
考える部分を作ろうと思います。という訳でnginxを入れてみることに。

[vagrant@localhost ~]$ sudo knife cookbook create nginx
WARNING: No knife configuration file found
** Creating cookbook nginx
** Creating README for cookbook: nginx
** Creating CHANGELOG for cookbook: nginx
** Creating metadata for cookbook: nginx

どうやら失敗したようです。
(´・ω・`)

[vagrant@localhost ~]$ rpm -qa | grep nginx
[vagrant@localhost ~]$

ではhttpdに変えてみてレシピを見てみます。

[vagrant@localhost ~]$ sudo knife cookbook create httpd
WARNING: No knife configuration file found
** Creating cookbook httpd
** Creating README for cookbook: httpd
** Creating CHANGELOG for cookbook: httpd
** Creating metadata for cookbook: httpd

httpdでは上手くいきました。

Recipe: httpd::default
  * package[httpd] action install
    - install version 2.2.15-39.el6.centos of package httpd
Running handlers:
Running handlers complete
Chef Client finished, 1/1 resources updated in 5.155466175 seconds

レシピを見ると同じなんですけどね。

[vagrant@localhost ~]$ cat /var/chef/cookbooks/httpd/recipes/default.rb
#
# Cookbook Name:: httpd
# Recipe:: default
#
# Copyright 2014, YOUR_COMPANY_NAME
#
# All rights reserved - Do Not Redistribute
#
package "httpd" do
  action :install
end
[vagrant@localhost ~]$ cat /var/chef/cookbooks/nginx/recipes/default.rb
#
# Cookbook Name:: nginx
# Recipe:: default
#
# Copyright 2014, YOUR_COMPANY_NAME
#
# All rights reserved - Do Not Redistribute
#
package "nginx" do
  action :install
end

nginxが無理な理由は後で追いかけるとして
追いかけて雪国な感じで、本書の通り進めていきます。
knife-soloを入れます。

takeken@ubuntu:~$ cat Gemfile
source 'https://rubygems.org'

gem 'knife-solo'

bundlerのインストール

takeken@ubuntu:~$ gem install bundler
Fetching: bundler-1.7.4.gem (100%)
ERROR:  While executing gem ... (Errno::EACCES)
    Permission denied - /var/lib/gems
takeken@ubuntu:~$ sudo gem install bundler
[sudo] password for takeken:
Fetching: bundler-1.7.4.gem (100%)
Successfully installed bundler-1.7.4
1 gem installed
Installing ri documentation for bundler-1.7.4...
Installing RDoc documentation for bundler-1.7.4...

うまくいかねー!この黄色と赤の画面見るとレンサバにRailsを入れていた時のことを思い出すよ。

takeken@ubuntu:~$ bundle
Fetching gem metadata from https://rubygems.org/..........

Building native extensions.  This could take a while...
ERROR:  Error installing knife-solo:
        ERROR: Failed to build gem native extension.

原因はdevパッケージがないからというのを見つけたのでdevをインストール。

参考サイト
Laboratory of Scarlet

RubyGemsでinstallコマンドをたたくとエラーが出る→rbenvの問題だった

takeken@ubuntu:~$ sudo apt-get install ruby1.9.1-dev
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了

うまくいきました。

takeken@ubuntu:~$ bundle
Fetching gem metadata from https://rubygems.org/..........
Resolving dependencies...
Installing ffi 1.9.6
Installing libyajl2 1.1.0
Installing ffi-yajl 1.2.0
Installing hashie 2.1.2
Using mixlib-log 1.6.0
Installing rack 1.5.2
Installing chef-zero 2.2.1
Installing diff-lcs 1.2.5
Installing erubis 2.7.0
Installing highline 1.6.21
Using mime-types 1.25.1
Using mixlib-authentication 1.3.0
Using mixlib-cli 1.5.0
Using mixlib-config 2.1.0
Using mixlib-shellout 1.6.0
Installing net-ssh 2.9.1
Installing net-ssh-gateway 1.2.0
Installing net-ssh-multi 1.2.0
Installing ipaddress 0.8.0
Using systemu 2.6.4
Installing wmi-lite 1.0.0
Installing ohai 7.4.0
Installing plist 3.1.0
Installing coderay 1.1.0
Installing method_source 0.8.2
Installing slop 3.6.0
Installing pry 0.10.1
Installing rest-client 1.6.7
Installing chef 11.16.4
Installing knife-solo 0.4.2
Using bundler 1.7.4
Your bundle is complete!
Use bundle show [gemname] to see where a bundled gem is installed.
Post-install message from knife-solo:
Thanks for installing knife-solo!

If you run into any issues please let us know at:
  https://github.com/matschaffer/knife-solo/issues

If you are upgrading knife-solo please uninstall any old versions by
running gem clean knife-solo to avoid any errors.

See http://bit.ly/CHEF-3255 for more information on the knife bug
that causes this.

takeken@ubuntu:~$ bundle exec knife solo init .
WARNING: No knife configuration file found
Creating kitchen...
Creating knife.rb in kitchen...
Creating cupboards...

ホストからノードにChef Soloを入れてみます。
sshの設定からですがうまくいったようです。

takeken@ubuntu:~$ sudo vagrant ssh-config --host takedb >> ~/.ssh/config
takeken@ubuntu:~$ cat ~/.ssh/config
Host takedb
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /home/takeken/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

takeken@ubuntu:~$ bundle exec knife solo prepare takedb
Bootstrapping Chef...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 16472  100 16472    0     0  13850      0  0:00:01  0:00:01 --:--:-- 31315
Downloading Chef 11.16.4 for el...
downloading https://www.opscode.com/chef/metadata?v=11.16.4&prerelease=false&nightlies=false&p=el&pv=6&m=x86_64
  to file /tmp/install.sh.2212/metadata.txt
trying wget...
url     https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chef-11.16.4-1.el6.x86_64.rpm
md5     2355a7a93bc4cc353bee6de9e3bcb7ba
sha256  278599ff185b680703e7a779db8674eeba843e9fe42a0ae06e01a9dfa9ac4d0e
downloaded metadata file looks valid...
downloading https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chef-11.16.4-1.el6.x86_64.rpm
  to file /tmp/install.sh.2212/chef-11.16.4-1.el6.x86_64.rpm
trying wget...
Comparing checksum with sha256sum...
Installing Chef 11.16.4
installing with rpm...
警告: /tmp/install.sh.2212/chef-11.16.4-1.el6.x86_64.rpm: ヘッダ V4 DSA/SHA1 Signature, key ID 83ef826a: NOKEY
準備中...                ########################################### [100%]
   1:chef                   ########################################### [100%]
Thank you for installing Chef!
Generating node config 'nodes/takedb.json'...

ホストからゲストに向かってChefからhttpをインストール。

takeken@ubuntu:~$ bundle exec knife cookbook create httpd -o site-cookbooks
** Creating cookbook httpd
** Creating README for cookbook: httpd
** Creating CHANGELOG for cookbook: httpd
** Creating metadata for cookbook: httpd
takeken@ubuntu:~$ vim site-cookbooks/httpd/recipes/default.rb
takeken@ubuntu:~$ bundle exec knife solo cook takedb -o httpd

    ~~省略~~

Recipe: httpd::default
  * package[httpd] action install (up to date)

Running handlers:
Running handlers complete
Chef Client finished, 0/1 resources updated in 2.351531206 seconds

じゃあ、Puppetに応用しようかと考えたのだが、Puppetにknife-solo
みたいなものはないらしい。

Slideshare
http://www.slideshare.net/winebarrel/2013-0720-chefpuppet

見本の通りにBase_packagesを作ってノードに入れてみた。

Recipe: base_packages::default
  * package[gcc] action install
    - install version 4.4.7-11.el6 of package gcc
  * package[make] action install (up to date)
  * package[git] action install
    - install version 1.7.1-3.el6_4.1 of package git
  * package[readline] action install (up to date)
  * package[readline-devel] action install
    - install version 6.0-4.el6 of package readline-devel

Running handlers:
Running handlers complete
Chef Client finished, 3/5 resources updated in 43.575401101 seconds

良かったらしい。

後はChefでのコード化の話になってくる。ここまでやってきて、Vagrantに対してはいまいちやりきってない感じがするのでChefはいったん切り上げてVagrantについて~と思って本をぺらぺらめくっていたら、Puppet、Vagrant、VirtualBOXという特集があったじゃないか。

ちょっと飛んでそっちにいきたいと思います。

ちょこっと小話ですが、CentOSなどのRH系はYum、Deb系ならAptというコマンドがありますが、PuppetやChefはその辺は明示せずにインストールするという宣言をすることになります。

他は開発関係の用語は聞きなれないので、単体テストとか結合テストとか、テスト駆動とか・・・言葉そのものにパッとしないので書いている事もよく分からない事になるかもしれませんがご容赦くだしあ。ま、意味がよく分からんのはいつものことですけどね。

 

Serverspecをインストール

takeken@ubuntu:~$ sudo gem install serverspec --pre --no-ri --no-rdoc

続いて本を参考に管理用ディレクトリの作成と、管理用ディレクトリに roles/app/manifests/init.pp と provision.sh Vagrantfileを作成しよう。

今回のVagrantfileは上の方で手動でおこなった、イメージを取ってきてインストールという部分とPuppetのインストールと、Puppetに記述されている作業をVagranfileに記述して自動でやってくれるものだ。

おおお、サーバーはこれで出来上がり。
2回目という事でなんとなくVagrantのイメージも出来てきた。

起動もなんなくクリアできた。

takeken@ubuntu:~/test-driven-infra$ sudo vagrant up
  略
==> app: Complete!
  略

ではServerspecの作業にうつります。

テストコードのひな形を作成。テストも自動でできるというのがまだパッとしないけれど、構築部分がコード化(自動化)されているから出来ることなのだろうな。

 

テスト駆動をやってみよう

serverspecの用意もできたので、続いて必要なファイルを作成したり、Puppetの記述をしたりと本に沿って進めていこう。

takeken@ubuntu:~/test-driven-infra$ sudo serverspec-init
Select OS type:

  1) UN*X
  2) Windows

Select number: 1

Select a backend type:

  1) SSH
  2) Exec (local)

Select number: 1

Vagrant instance y/n: y
Auto-configure Vagrant from Vagrantfile? y/n: y
 + spec/
 + spec/app/
 + spec/app/sample_spec.rb
 + spec/spec_helper.rb
 + Rakefile
 + .rspec

ServerspecのテストはLakeコマンドでやるみたいで、ここでもRubyみたいだ。
何だかRubyばっかりだのう。

テストの内容はntpが入っているか?というものなので、同じように進めているので当然のごとくエラーが出る。とりあえずテストはうまくできたので第1段階完了だ。

 takeken@ubuntu:~/test-driven-infra$ sudo rake spec
/usr/bin/ruby1.9.1 -I/var/lib/gems/1.9.1/gems/rspec-support-3.0.4/lib:/var/lib/gems/1.9.1/gems/rspec-core-3.0.4/lib -S /var/lib/gems/1.9.1/gems/rspec-core-3.0.4/exe/rspec spec/app/ntp_spec.rb

Package "ntp"
  should be installed (FAILED - 1)

Failures:

  1) Package "ntp" should be installed
     On host `app'
     Failure/Error: it { should be_installed }
       expected Package "ntp" to be installed
       sudo -p 'Password: ' /bin/sh -c rpm\ -q\ ntp
       package ntp is not installed

     # ./spec/app/ntp_spec.rb:4:in `block (2 levels) in <top (required)>'

Finished in 1.02 seconds (files took 1 minute 55.32 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/app/ntp_spec.rb:4 # Package "ntp" should be installed
/usr/bin/ruby1.9.1 -I/var/lib/gems/1.9.1/gems/rspec-support-3.0.4/lib:/var/lib/gems/1.9.1/gems/rspec-core-3.0.4/lib -S /var/lib/gems/1.9.1/gems/rspec-core-3.0.4/exe/rspec spec/app/ntp_spec.rb failed

では、さっきのテストを通過させるためにntpモジュールを作成し、Puppetマニフェストを適用します。
ここで Puppet aplly するわけではなくて、Vagrant provisionを実行するということに注意。

この2個のファイルを作成して実行します。

takeken@ubuntu:~/test-driven-infra$ vim modules/ntp/manifests/init.pp
takeken@ubuntu:~/test-driven-infra$ vim roles/app/manifests/init.pp
takeken@ubuntu:~/test-driven-infra$ sudo vagrant provision
==> app: Running provisioner: shell..
~~略~~
==> app: Notice: /Stage[main]/Ntp/Package[ntp]/ensure: created
==> app: Notice: Finished catalog run in 13.67 second

再テストしてみます。

問題なく終わりました!

takeken@ubuntu:~/test-driven-infra$ sudo rake spec

Finished in 0.80765 seconds (files took 5.21 seconds to load)
1 example, 0 failures

続いて本のように、マニフェストに追記して、再テストしてみます。

マニフェストを修正。

takeken@ubuntu:~/test-driven-infra$ vim modules/ntp/manifests/init.pp

Vagrant provisionで適用。

takeken@ubuntu:~/test-driven-infra$ sudo vagrant provision

テスト駆動

takeken@ubuntu:~/test-driven-infra$ sudo rake spec
/usr/bin/ruby1.9.1 -I/var/lib/gems/1.9.1/gems/rspec-support-3.0.4/lib:/var/lib/gems/1.9.1/gems/rspec-core-3.0.4/lib -S /var/lib/gems/1.9.1/gems/rspec-core-3.0.4/exe/rspec spec/app/ntp_spec.rb

Package "ntp"
  should be installed

Service "ntpd"
  should be enabled
  should be running

Finished in 0.87954 seconds (files took 4.63 seconds to load)
3 examples, 0 failures

問題なしでした。

本当にさわりの部分しかやってないと思いますが、コード化、自動化ってこんな感じなのだなぁというのはちょっとばかり体験できました。
まじにコードで全部やりきっている。
テスト駆動インフラっていうのがこうして積み重ねてコードを育てていく手法という事らしい。

今までやってきたサーバー構築とは全く違っていると感じるのだけど、サーバーで行われていることは同じなのだね。ただ何から何までをすべてをコードでやっているって違いがあるだけ。
それだとまだまだ自分なんかは本当にダイジョブかな??って逆に感じてしまうのですが。っていうか書いた通りになっているはずなので確実なのだよ。
手動で手順通りに確認するという作業の問題点が改善される気もするし。
Gitなんかで差分管理もできるということだ。

う~む。
では今回は終了~。

 

Similar Posts:


Leave a Reply

Your email address will not be published. Required fields are marked *