Home 技術解説-新着 kitchen CIを使ったテスト駆動によるChef開発 ~IT運用自動化の新しい方向性|第4回

kitchen CIを使ったテスト駆動によるChef開発 ~IT運用自動化の新しい方向性|第4回

by kusui
 ITインフラストラクチャの最適化、運用の効率化を実現するものとしてプライベートクラウドが広がりを見せる一方、その95%は失敗に終わっているとも言われている(*1)。その大きな原因は既存の運用を変えることに失敗した点にある、とガートナーの調査によって指摘されている。
 
・・・・・・・・
・・・・・・・・
 
 ITインフラを自動化しプライベートクラウドを実現するためのツールはさまざまある。しかし、手作業やシェルスクリプトを用いるような既存の運用方法との溝は大きく、実際に導入するにはいろいろな障害があるだろう。そのハードルをいかに下げるかが重要だ。
 
 本連載ではITインフラの自動化について取り上げ、前回(本誌No.14)は構成管理ツールChefの概念と構成について説明した。筆者は、OS設定や構成をすべてChefによって実施する案件に携わった経験をもつ。本稿ではその経験を踏まえ、「現場」でChefを使いこなすため、kitchen CIと呼ばれるツールを中心にChef開発のポイントについて紹介する。
 
 

Chef導入時にクリアすべき
3つの課題

 Chefは、サーバー設定をレシピと呼ばれるRubyで書かれたコードによってInfrastructure as Code(*2)を実現するツールである。まずChef導入のメリットについて振り返ろう。
 
・・・・・・・・
(*2)インフラストラクチャの構成管理を、スクリプトや外部ファイルに記述して自動化する仕組み
・・・・・・・・
 
 Chefの導入には、大きく3つのメリットがあると考えられる。1つ目は、Chefを使えばコードによってサーバーの設定を自動化できる点である。手作業でのサーバー設定に比べ、サーバー構築にかかる期間とコストを大幅に短縮することができる。2つ目は、Chefは「サーバーのあるべき状態」をコード化できる点である。これによって、何度実行しても同じ状態に収束させる特徴(冪等性)をもっている。一度だけの実行を前提としたシェルスクリプトと比べて、より高度な自動化を行うことが可能だ。そして3つ目のメリットが、Chefは横展開も容易な点である。コードとして書かれた成果物は、GitHubやChef Supermarketと呼ばれるChefコミュニティ上で公開できる。以上がChefによって得られる主なメリットである。
 
 しかし、こういったメリットを享受する前に、Chefの導入に挫折するケースが見られる。とくにChefを利用するうえで最初にぶつかる壁が、「どうやってレシピを開発をするか」である。たとえ、Chef Supermarketなどを利用したとしても、実際のコードの開発がまったく発生しないわけではない。Chefのレシピ開発になじみのない、シェルスクリプト中心にLinux/UNIX系サーバーの運用を担当しているエンジニアにとっては、大きなハードルになりうる。
 
 そこで開発を効率的に進める場合、いくつかの課題をクリアしなくてはならないと筆者は考える。それらを紹介しよう。
 
◆ 開発環境の用意
 ChefのコードはRubyでコーディングされるが、開発対象としてChefを実行できるインフラ環境が必要である。とくに開発の初期の段階では、失敗が許されるよう、サーバーの作成、削除が容易にできる環境が望ましい。たとえばあるパッケージをインストールするときに依存関係にあるライブラリも一緒にインストールされる。これをインストール前の状態に戻したいとき、依存関係にあるライブラリを取り除くべきか否かは、変更履歴をすべて管理していないと判断できない。こういったやり直しが利く環境を作るには、一般的には、インフラスキルをもった要員を確保しなくてはいけない。
 
◆ チーム開発
 Chef開発のプロジェクトには、さまざまなスキルレベル、あるいは異なるバックグラウンドのエンジニアが参加することが多いだろう。また、ベースの開発が終了したあとも、修正や機能の追加を行っていくことを考えれば、運用チームのメンバーも開発に参加するかもしれない。そのようななかで効率的にチーム開発を進めるにはどうすべきだろうか。
 
◆ レシピの品質
 複数人が開発に携わるため、レシピの品質が要員によってばらついてしまうことが予想される。これまで手作業やシェルスクリプトでインフラ構築を行っていた現場でChefを導入する場合、どのようにChefの実績を積み上げるのか、その開発物の品質をどう維持するかを新たに考えなくてはならない。
 
 これらの課題を解決しなければ、Chef開発に非常に時間がかかったり、運用自動化が十分になされないということになりかねない。実際に筆者もChefを導入しようとした際に同じ問題を経験した。そこで、これらの問題を解決する方法として、Chefだけでなく、Chefの開発を手助けしてくれるツールを調査し、また実際に使ってみた。その結果、有用と判断できたツールがkitchen CIであった。
 

 以降の章ではkitchen CIについて紹介する。

 

Chef開発を効率的に行える
kitchen CIツール

 筆者がChefの開発のポイントと感じたのは「テスト」である。ChefはRubyで開発する以上、そのコードの品質を保証する何らかのテストの仕組みが必要である。テストと聞くと、面倒な作業と捉えるエンジニアがいるかもしれない。しかし、開発が進んでから複数のレシピを同時に実行する結合テストの単位が大きくなるほど、バグを見つけ修正するのに時間がかかるようになる。
 
 コードを作成しながら小さい範囲でテストを繰り返し行うのが望ましい。つまり、きちんとテストを行うことが効率的な開発には不可欠だ。しかし、繰り返しテストを実施できる仕組みを作るのは困難かもしれない。これを解決するのがkitchen CIツール(以下、kitchen)である(図表1)。
 
 
 
 
 kitchenは、Chef社によって開発されている、ChefなどのInfrastructure as Codeのテスト駆動開発を実現するオープンソースのツールである。GitHubでも入手できる(*3)。
 
・・・・・・・・
・・・・・・・・
 
 kitchenはChef開発における初期状態の環境準備、Chefの実行、Chefを実行した環境のテストを行う機能をもつ。kitchenを使えば、前述したChef開発における3つの課題を以下のように解決することができる。
 
◆ 簡単に環境を作り直せる
 kitchenを使えば簡単にテスト環境を作り直すことができ、失敗を恐れずに開発を進められる。前述したとおり、テストを繰り返しながら開発を進めることが重要だ。しかしサーバーを初期状態に戻すには、変更履歴を管理したり手動で仮想マシンをもう一度立て直すなどの必要があるだろう。kitchenツールを使えば、コマンド1つでテスト用の環境を作れる。これによって開発者は環境を準備する煩わしさから解放され、本来の開発への注力が可能になる。
 
◆ チーム開発を実践できる
 kitchenを使えば、ほかのメンバーが実行したことを簡単に再現できる。するとそこから、さらに追加の開発を行うことが可能だ。kitchenでは、テスト環境の状態を定義するために1つの設定ファイルを使用する。このファイルを開発メンバーに配布することで、インフラの知識が浅いメンバーやプロジェクト途中から開発に参加するメンバーも含めて、自分の担当する開発に集中できる。
 
 たとえばAさんがネットワークの設定を行うレシピを作成する。これを用いることによってBさんはネットワークの構成の詳細について知らなくても、kitchenによって簡単にネットワークの設定がなされた環境を再現し、Webサーバーの設定を行うレシピの開発が可能だ。
 
 
◆ テスト駆動開発でChefの品質を維持できる
 kitchenを使った開発で、Chefの品質を維持することができる。ここまで説明してきた、テストを繰り返し行いながら開発を行う方法は、アプリケーション開発にも用いられるテスト駆動開発につながる。テスト駆動開発とは、最初にテストコードを実装しそのテストを成功させるコードを開発する、という開発手法である。この手法をChef開発に取り入れれば、「テストコードにパスするかどうか」というChef開発のルールを定めることができる。
 
 以上のようにkitchenを使うことで、開発のための初期環境を用意するコストやテストを行うコストの削減が可能である(図表2)。ここからはkitchenの詳細について説明する。
 
 
 

kitchenのコマンドと
ymlファイル

 kitchenで主に使うのは以下の4つのコマンドである。①テスト環境を作成し、②レシピを実行しサーバー設定を行い、③テストを行い、④不要になったテスト環境を削除する、という一連の流れが、kitchenツールによって実現できることがわかると思う。
 
・ kitchen create:テスト環境(仮想サーバー)作成
・ kitchen converge:レシピの実行
・ kitchen verify:テスト実行
・ kitchen destroy:テスト環境(仮想サーバー)削除
 
 これらのコマンドを実行したときの処理を定義するのが、.kitchen.ymlファイルである。このymlファイルは以下の5つのセクションに分かれている(図表3)。
 
 
(a) driverセクション
 テスト用の仮想環境を立ち上げるためのドライバを指定する。ここでは後述するAIX用のドライバであるkitchen-WPARを使用している。
 
(b) provisionerセクション
 プロビジョニングを行うツールを指定する。kitchen convergeコマンドによってレシピを実行するときに指定したツールを使用する。ここではChef実行を行うchef-soloを指定している。
 
(c) platformsセクション
 テスト環境のOSなど初期状態を指定する。
 
(d) suitesセクション
 実行するChefのコード(レシピ)を指定する。ほかにもレシピ内で使う変数(アトリビュート)の値を指定することができる。
 
(e) verifierセクション
 テストを行うツールを指定する。この例ではサーバー構成をテストするためのテストフレームワークであるserverspecを使用している。
 
 このなかでとくに、構築するテスト環境を定義するdriverセクションについて詳しく見ていこう。仮想のテスト環境を作成するためドライバは、デフォルトのVagrantのほかにさまざまなプラグインが公開されている。また容易にプラグインを作成できる仕組みがあるので、自分の欲しいプラグインを作成できる。作成したプラグインはGitHubなどのコミュニティを通じて公開され、誰でもダウンロードして使うことが可能だ。
 
 このDriverの強力さを理解してもらうのに本稿では、AIX用のドライバである、kitchen-WPAR(*4)とkitchen-PowerVC(*5)の2つを紹介する。これらは、筆者が経験したAIXの構築やパラメータ変更をすべてChefで行うプロジェクトで大いに役立った。なお、ここではAIXに絞った説明となるが、LinuxやWindowsの開発にも参考になるのでぜひ役立ててほしい。
 
・・・・・・・・
・・・・・・・・
 

kitchen-WPAR

 筆者が経験したプロジェクトでは、当初kitchen-WPARと呼ばれるドライバを使って開発を行った。WPARはAIXのOSレベルでの仮想化機能である。Linuxでたとえるなら、dockerコンテナ(*6)で作成するようなイメージである。kitchen-WPARを使うには仮想環境を作成するためのAIXサーバーが1台あればよい。後述のkitchen-PowerVCに比べて導入が容易だ。環境はkitchen createコマンドを実行して、わずか5分程度で作成できる(図表4)。
 
・・・・・・・・
・・・・・・・・
 
 
 
 
 
 実際に筆者はkitchen-WPARを使ってChef開発を始め、得られたメリットが以下であった。
 
・ すぐに始められるので、Chefおよびインフラ(AIX)の知識を身につけるのに役立った。
・ 5分程度で環境が作り直せるため、環境を壊しては作り直すという習慣が身についた。
 
 しかし、徐々に以下のような壁にぶつかるようになった。kitchen-WPARでは十分な開発が行えない理由が2つあった。
 
 まず、WPAR環境では一部のカーネルパラメータのチューニングができない(*7)。また、PowerHAと呼ばれるクラスタ・ソフトウェアの導入も自動化する必要があったが、これも共有ディスクの切り出しができないなどの制約によりkitchen-WPARでは行えなかった(*8)。そのため、より柔軟なインフラ構成を取れる仕組みが必要となり、そこで登場したのがPowerVCとkitchenドライバであった。
 
・・・・・・・・
・・・・・・・・
 

kitchen-PowerVC

 kitchen-WPARに比べ、より柔軟にChef開発を行うのに役立つのがkitchen-PowerVCである。AIXは、OpenStackをベースとした仮想化管理ツールとしてPowerVCを提供している(図表5*9))。kitchen-PowerVCを使えば、PowerVCを通してのWPARではなく、独立したLPARとして仮想サーバーのテスト環境を作成できる。よって前述したkitchen-WPARの制約に引っかかることなく、開発が行えた。
 
 
 
・・・・・・・・
・・・・・・・・
 
 実際に筆者は、クラスタ・ソフトウェアの導入自動化のために、図表6のような.kitchen.ymlを使用した。クラスタ構成には複数台のサーバーが必要だったが、これはplatformsセクションに -name以下の2つのブロックを記述することで実現できる。さらに、ディスクを指定するblock_device_mappingに同じuuidを指定することで、複数台のサーバーで共有ディスクを切り出すこともできた。なおuuidとは、図表6のようにPowerVCの画面から確認できるボリュームのIDである。
 
 
 
 このようにPowerVCを導入する必要があるなど 導入コストはkitchen-WPARに比べて高いが、より高度なインフラ設定を行うことが可能だ。kitchen-WPARを使って開発をはじめ、途中からkitchen-PowerVCに移行することでChef開発を完遂できた。
 
 ここまで説明したdriverによって仮想環境が構築できる。続いてその環境に対し、Chefの実行を行い、環境が設計どおりになっていたかのテストを行う。ここで実行するChefのレシピとテストコードを指定するのが、suitesとverifierセクションである。筆者はレシピごとの単体テストを実行するために、Chefのコードとそのテスト用のserverspecのコードが対応するように開発した。
 
 ここでは“ユーザー追加”のレシピのテスト例を図表7に示す。.kitchen.ymlのsuitesセクションでユーザー追加を行うChefのレシピを指定し、verifierセクションに追加されたユーザーの確認を行うserverspecの実行コマンドが記述されている。ほかのレシピについても同様にすることで、レシピの単位ごとに単体テストを行うことができる。
 
 
 
 

kitchenツールの
Hints & Tips

 kitchenの最大の利点は、簡単に作って壊せることである。逆に言うと「簡単に作り直せる」状態を保つ必要がある。
 
 たとえば、ミドルウェアの設定をするためのChefレシピを開発する場合を考える。実際に開発したいミドルウェアの設定を行うには、そのミドルウェアをインストールしたり、ネットワークを整えたりする作業があるだろう。そのような“環境の準備”にあたる部分は先にレシピとしてコード化して、.kitchen.ymlファイルに必ず最初に実行されるレシピとして組み込むことを勧める(図表8)。
 
 
 
 

バージョン管理+チケット管理
によるチーム開発の効率化

 インフラ構築の現場では、Excelで作業の管理をしたり、開発物をサーバー上のディレクトリで管理していることが多いのではなかろうか。しかし、そのような方法でChef開発を進めるのでは、インフラ管理をコード化するChefの恩恵を十分に受けられない。
 
 前節ではkitchenを使ってテストを自動化し効率的に開発を行う手法について紹介した。Chefの真価を発揮させるには「継続的インテグレーション」を取り入れるのがよい。「継続的インテグレーション」とはDevOpsにも取り入れられている手法の1つであり、“コードを1カ所に集め、ビルド(ここではChefの実行)、テスト”を行うことでインテグレーションを継続的に行う手法である。結合テストを開発初期から継続的に行うことがポイントである。
 
◆ なぜ継続的インテグレーションが必要なのか
 テストフェーズになって初めて結合テストを行ったら想定外の問題が発生した、というのはよくある話である。このような潜在的な問題は早期に発見することで、そのバグフィックスを効率化できる。ゆえにコードの量が少ない開発段階から結合テストを行うことが望ましい。
 
◆ 継続的インテグレーションを行うには
 チーム開発で継続的インテグレーションの自動ビルド(実行)と自動テストを行うには、前章で紹介したkitchenツール、そしてテスト駆動開発で開発したテスト用のserverspecのコードに加えて、バージョン管理ツールが必要だ。Subversionやgitなどのバージョン管理ツールを使うことで、複数のメンバーが開発したchefのコードが一元的に管理される。
 
◆ コードトラッキングによる開発効率化
 kitchen + serverspec + バージョン管理ツールによって、インテグレーションを継続的に行えるようになった。さらに、デバッグ作業を容易にするにはコードに加えて、誰が、いつ、どのようにコードを変更したのか、という付随的な情報も一元管理できると便利だ。そのために有用なのがRedmineなどのチケット管理ツールである。
 
 たとえば筆者はChef開発の現場で、SubversionとRedmineを組み合わせて使った。チケット(タスク)ごとにメッセージのやり取りやコードの変更履歴を紐づけ、Redmineを通じてブラウザ上で確認できる。これによって、たとえば結合テストを走らせて失敗したコードを確認し、そのコードを書いたメンバーにバグの修正を依頼する、というサイクルをRedmine上だけで行うことが可能になるのだ。
 
◆ ツールを使って効率的にChef開発を行う
 本稿では、実際の現場でChef開発を効率的に進めるためのkitchen CIツールについて紹介した。kitchenによってテスト環境を簡単に構築でき、テスト駆動開発を行うことが可能である。それに加えてバージョン管理・チケット管理のツールを組み合わせることでチーム開発の効率化が望める。
 
・・・・・・・・
◎参考文献
・kitchenツール:http://kitchen.ci/
・『チーム開発実践入門』池田尚史著、技術評論社 2014
・・・・・・・・
 
[IS magazine No.16(2017年7月)掲載]
 
 
・・・・・・・・

著者|中筋 香織 氏

日本アイ・ビー・エム システムズ・エンジニアリング株式会社
デジタル・プラットフォーム
ITスペシャリスト
 
 
 
日本アイ・ビー・エム システムズ・エンジニアリングに入社以来、Bluemixを使ったアプリ開発や、Chefによるインフラ構築に携わる。

related posts