さっそくサーバ/インフラ徹底攻略(技術評論社)を参考にインフラのコード化に触れてみたいと思います。
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 AVagrantfile
has been placed in this directory. You are now ready tovagrant up
your first virtual environment! Please read the comments in the Vagrantfile as well as documentation onvagrantup.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! Usebundle 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 runninggem 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なんかで差分管理もできるということだ。
う~む。
では今回は終了~。