chefやansibleを使ってサーバの環境構築が主流になってきていて、業務や個人で使っている人も多いと思います。
サーバ構築した後に、そのサーバの状態が正しく設定されているかを確認するとき、
手動でサーバにはいってプロセスの状態を見たりする事もできますが、 管理するサーバ数が多い場合 その作業が非常に大変になっていきます。
その問題を解決するために、サーバの状態を容易にテストできるRspecやServerspecというツールが出現してきて、サーバの状態テストが非常に用意になりました。
今回は、Serverspecというツールをつかってサーバの状態テストをする手順を解説していきます。
Serverspecとは
serverspec.org
テスト対象のサーバの状態(特定のサービスが起動しているか、ポートが開いているか)など、サーバのあるべき状態を記述し、対象サーバの状態をテストする事ができます。
テストの記述はrubyで記述し、rubyを知っていればテストコードの追加と設定ファイルの記述を容易に行えます。
webサーバの状態をテストしてみる
前提 対象サーバへはSSH接続を行い、~/.ssh/config ファイルに以下の設定を記述している Host wap HostName ${SERVER_IP_ADDRESS} User test_user StrictHostKeyChecking no PasswordAuthentication no IdentityFile "~/.ssh/id_rsa" IdentitiesOnly yes LogLevel FATAL 対象サーバでtest_userというアカウントを作成し、sudoコマンドを実行できる状態
上記の前提条件の上で、ここでは特定のサーバに対して以下の状態になっているかを簡単にテストしてみます。
- httpdがインストールされている - httpd serviceが有効になっている - httpd プロセスが起動されている - 80番portが開いている
実際にこの4つの状態は、最初にserverspecを初期化した状態でサンプルとして書かれているので、それを使ってみます。
Serverspecのインストール
ローカル環境(mac OS)において、Serverspecをインストールしていきます。
手順としては非常に簡単でServerspec本家のサイトにInstallationとしてまとまっているので、そのとおりに行えば大丈夫です。
serverspec.org
# gemでserverspecインストール $ gem install serverspec # serverspec-initコマンドが使えるようになっているのを確認 $ which serverspec-init /Users/USERNAME/.rbenv/shims/serverspec-init
gemでserverspecをインストールすると、serverspec-initコマンドが使えるようになります。
serverspec-initコマンドを実行すると、テストしたいサーバの状態(OS, 接続方法, host名)を入力して自動でServerspecの設定ファイルを生成してくれます。
ここでは、外部で作成したcentOSサーバに対してsshでアクセスする際の設定を入力していきます
$ serverspec-init Select OS type: 1) UN*X 2) Windows Select number: 1 # UN*X環境を設定 Select a backend type: 1) SSH 2) Exec (local) Select number: 1 # SSH接続なので、1 Vagrant instance y/n: n #Vagrant instanceでないため、 n Input target host name: wap # ~/.ssh/config ファイルに設定したhost名: wap を入力 + spec/ + spec/wap/ + spec/wap/sample_spec.rb + spec/spec_helper.rb + Rakefile + .rspec
これを実行すると、実行したカレントディレクトリ配下にServerspec用のディレクトリ・ファイルが生成されます。
. ├── Rakefile └── spec ├── wap │ └── sample_spec.rb # wap サーバのテストを記述 └── spec_helper.rb # Serverspec実行時の設定ファイル
Serverspec でのテストを実行する際には、 rakeコマンドを使ってサーバのテストファイルを呼び出し、テストを行います。
rake実行時の処理はRakefileにかかれており、デフォルトで ./spec配下のディレクトリをチェックし、*_spec.rb のrubyファイルを呼び出して
テストを実行するようになっています。
先程作られた自動生成ファイルは sample_spec.rbとなっていますが、 わかりやすく wap_spec.rbと変更しても動く様になっています。
Rakefile
require 'rake' require 'rspec/core/rake_task' task :spec => 'spec:all' task :default => :spec namespace :spec do targets = [] Dir.glob('./spec/*').each do |dir| next unless File.directory?(dir) target = File.basename(dir) target = "_#{target}" if target == "default" targets << target end task :all => targets task :default => :all targets.each do |target| original_target = target == "_default" ? target[1..-1] : target desc "Run serverspec tests to #{original_target}" RSpec::Core::RakeTask.new(target.to_sym) do |t| ENV['TARGET_HOST'] = original_target t.pattern = "spec/#{original_target}/*_spec.rb" end end end
そして、Serverspecでのテスト実行時のサーバ接続情報は下記のように設定してみます。
Serverspecでのテスト時に、サービスの起動確認など、内容によっては接続先サーバでのsudoコマンドを使ってテストを行うため、
対象ユーザのパスワードなどを入力させる処理を記述します。
初期生成時にある程度書かれていますが、ここでは微妙に変えています
spec_helper.rb
require 'serverspec' require 'net/ssh' set :backend, :ssh # 対象サーバ内でのsudo passwordの設定処理 # 実行時に 環境変数に ASK_SUDO_PASSWORDが設定されている場合 # コマンドライン上でパスワードを入力させる if ENV['ASK_SUDO_PASSWORD'] begin require 'highline/import' rescue LoadError fail "highline is not available. Try installing it." end # コマンドライン上でパスワードを入力させる set :sudo_password, ask("Enter sudo password: ") { |q| q.echo = false } else # ASK_SUDO_PASSWORD設定がオフの場合はここに設定したパスワードを利用する set :sudo_password, 'SERVER_USER_PASSWORD' end host = ENV['TARGET_HOST'] options = Net::SSH::Config.for(host) # 接続先サーバのユーザ名 options[:user] ||= 'test_user' set :host, options[:host_name] || host set :ssh_options, options set :family, 'redhat'
これでサーバ接続時の設定を記述できました。 今回は1つのサーバに対してテストを行いますが、複数のサーバに対してテストを行う場合、設定に合わせてspec_helper.rbファイルの修正も必要になるかと思います。
続いて、対象サーバの状態テストを記述していきます。
./spec/wap/sample_spec.rb にテスト内容を記述していきます。
前述したように、対象サーバのhttpdに対して以下の状態になっていることをテストするための処理を記述します。
- httpdがインストールされている - httpd serviceが有効になっている - httpd プロセスが起動されている - 80番portが開いている
sample_spec.rb
require 'spec_helper' # httpdがインストールされている describe package('httpd') do it { should be_installed } end # httpdのserviceの状態を記述する describe service('httpd') do it { should be_enabled } # serviceが有効になっている it { should be_running } # serviceが起動されている end # 80番ポートが開いているかテストする describe port(80) do it { should be_listening } end
テスト実行
ここで、テストするサーバへの接続設定と、テスト内容の記述ができたので、実際にテストを実行してみます。
テスト実行は、rakeコマンドを実行することで可能です。
$ rake spec
rake実行時にカレントディレクトリのRakefileの内容を呼び出してテストを行っていきます。
まずは、対象サーバのhttpdがインストールされているが、サービスが無効・起動していない状態でテストを実行してみます。
$ rake spec # 最初にsudo用のパスワードを入力する Enter sudo password: # httpdがインストールされている テスト○ Package "httpd" should be installed # 以下のテストが失敗している Service "httpd" should be enabled (FAILED - 1) should be running (FAILED - 2) Port "80" should be listening (FAILED - 3) Failures: 1) Service "httpd" should be enabled On host `wap' Failure/Error: it { should be_enabled } expected Service "httpd" to be enabled sudo -p 'Password: ' /bin/sh -c chkconfig\ --list\ httpd\ \|\ grep\ 3:on # ./spec/wap/sample_spec.rb:8:in `block (2 levels) in <top (required)>' 2) Service "httpd" should be running On host `wap' Failure/Error: it { should be_running } expected Service "httpd" to be running sudo -p 'Password: ' /bin/sh -c service\ httpd\ status httpd is stopped # ./spec/wap/sample_spec.rb:9:in `block (2 levels) in <top (required)>' 3) Port "80" should be listening On host `wap' Failure/Error: it { should be_listening } expected Port "80" to be listening sudo -p 'Password: ' /bin/sh -c netstat\ -tunl\ \|\ grep\ --\ :80\\\ # ./spec/wap/sample_spec.rb:13:in `block (2 levels) in <top (required)>' Finished in 0.85183 seconds (files took 13.41 seconds to load) 4 examples, 3 failures Failed examples: rspec ./spec/wap/sample_spec.rb:8 # Service "httpd" should be enabled rspec ./spec/wap/sample_spec.rb:9 # Service "httpd" should be running rspec ./spec/wap/sample_spec.rb:13 # Port "80" should be listening
テストを実行してみると httpdのパッケージはインストールされているが、httpdのserviceのテストと80番ポートのテストが失敗していることがわかります。
失敗時のログをみるとわかりますが、 サービスが有効かどうかのチェックは 実際にはchkconfigコマンドをつかっていて、 起動の確認はserviceコマンドを実行していることがわかります。
ポートの確認にはnetstatを実行していることがわかります。
ここで、対象サーバのhttpdをchkconfigコマンドを使って有効にし、httpdを起動してみます。
#テスト対象サーバでtest_userとしてログインする # httpdを有効にする $ sudo chkconfig httpd on # httpdを起動する $ sudo service httpd start Starting httpd: [ OK ]
httpdを有効にし、起動した上で再度テストを実行するとすべて成功していることが確認できます。
$ rake spec # 最初にsudo用のパスワードを入力する Enter sudo password: Package "httpd" should be installed Service "httpd" should be enabled should be running Port "80" should be listening Finished in 0.85282 seconds (files took 3.13 seconds to load) 4 examples, 0 failures
参考
Serverspecでサーバの構成をテストする 導入と個人的知見 - Qiita
https://www.ossnews.jp/oss_info/Serverspec
「Serverspec」を使ってサーバー環境を自動テストしよう - さくらのナレッジ
Serverspecでよく使うテストの書き方まとめ - Qiita
Infrastructure as Code ―クラウドにおけるサーバ管理の原則とプラクティス
- 作者: Kief Morris,宮下剛輔,長尾高弘
- 出版社/メーカー: オライリージャパン
- 発売日: 2017/03/18
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る