fbpx

[和訳] ChefDK 0.3.0 リリース! ポリシーファイルを導入 #opschef_ja #getchef_ja

この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。

本項は ChefDK 0.3.0 Released! Introducing Policyfiles (2014/10/02) の和訳です。

ChefDK 0.3.0をリリースできたことを私達は嬉しく思います。ダウンロードページから取得できます。本日のリリースは新しいポリシーファイル機能のプレビューリリースを含みます。これはインフラ管理のためにChefコードの開発と配布方法を改善する極めて重要なマイルストーンです。

ポリシーファイルとは

ポリシーファイルについて深く話す前に、この機能が完全ではないこととデザインのいくつかがまだ固まっていないことを明確にしておきたいと思います。私達のゴールのひとつはChefを始めようとする試みをより簡単にすることですが、もしあなたがChefに関して初心者であるならこれを用いることはよい考えではありません。もしあなたが経験を積んだユーザなら、これを使って是非フィードバックを寄せてください。
これを試してみる場合、隔離されたOrganizationで行ってください。もしオープンソース版Chef Server 11.xを使っているならサーバを分けてください。プレリリース機能を試すときのよいやり方は別として、ポリシーファイルのプレビューリリースを用いる際になぜ慎重さが必要となるのか、これから説明します。

今日からポリシーファイルを使う

本項の残りはポリシーファイルが何なのか、なぜこのようなデザインに決定したか、などなどの完全な説明です。
と、その前に、簡単な例を見てみましょう。まず最初にすべて見てみたいのならGitHubからサンプルコードをダウンロードできます。では始めましょう。まずはChefDK 0.3.0をインストールします。そして、chefコマンドでapp Cookbookの雛形を作成し、そのディレクトリにcdコマンドで移動します。


chef generate app policyfile_demo
cd policyfile_demo

Policyfile.rbという名前で次の内容のファイルを作成します。


name "jenkins"

default_source :community

run_list "java", "jenkins::master", "recipe[policyfile_demo]"

cookbook "policyfile_demo", path: "cookbooks/policyfile_demo"

chef installコマンドを実行します。これは依存関係を解決し、サードパーティCookbookをキャッシュにインストールし、Policyfile.lock.jsonファイルを生成します。このファイルを調べると、使われている各Cookbookとそれが含む名前、バージョン、ソース、コンテンツハッシュなどなどに関する情報を含んでいることがわかるでしょう。
ポリシーファイルをNodeに適用してみるには、デモ用途のChef ServerのOrganizationが必要になります。サンプルレポジトリには、knife serveを用いてChef Zeroの一時サーバを作成するためのknifeの設定ファイルを含んでいます。あるいは独自のものを利用してもよいでしょう。
ポリシーをアップロードするためにchef push demoコマンドを実行します。ChefDKはあなたの通常のknife設定ファイルを利用するので、必要であれば-c PATHを用いて別ファイルを指定してください。次のような出力が得られるでしょう。


WARN: Uploading policy to policy group demo in compatibility mode
WARN: Uploading cookbooks using semver compat mode
Uploaded policyfile_demo 0.1.0 (f04cc40f)
Uploaded java 1.28.0 (299d981f)
Uploaded jenkins 2.1.2 (f5d46bcd)
Uploaded apt 2.6.0 (278be58f)
Uploaded runit 1.5.10 (b400659b)
Uploaded build-essential 2.0.6 (88a112f9)
Uploaded yum-epel 0.5.1 (631202c9)
Uploaded yum 3.3.2 (0a0d0426)
Policy uploaded as data bag item policyfiles/jenkins-demo

興味があれば、knifeコマンドでアップロードしてデータを調査できます。
chef-clientをポリシーファイルモードに設定するには、次のディレクティブをclient設定ファイルに追加します。


use_policyfile true
deployment_group 'jenkins-demo'

use_policyfile trueディレクティブはポリシーファイルモードを有効にし、deployment_group 'jenkins-demo'は“jenkins”というポリシー名と“demo”というポリシーグループを同時に指定しています。
現時点では、修正がリリースされていないバグがchef-clientのポリシーファイルモードに存在します。次のChef 11のマイナーリリースとChef 12のプレビューリリースでは修正が含まれる予定です。手パッチするには、/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.16.2/lib/chef/policy_builder/policyfile.rbの160行目を


Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::RemoteFileVendor.new(manifest, api_service) }

から


Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::RemoteFileVendor.new(manifest, http_api) }

に変更してください。これでchef-clientはポリシーをNodeに適用できます。Chefは次の点を除いて普通通りに動作します。

  • Policyfile.lock.jsonからrun listを用いる。
  • Policyfile.lock.jsonに指定されたCookbookをダウンロードする。実行時では依存関係を解決しない。

もっと詳しく

ポリシーファイルは、chef-clientが使うべきCookbookのリビジョンと適用すべきRecipeを単一のファイルを通して正確に指定できるChefの機能です。このファイルはNodeのグループに関連付けたChef Serverにアップロードされます。それらのNodeがchef-clientを実行すると、ポリシーファイルで指定されたCookbookを取得し、ポリシーファイルのrun listで指定されたRecipeを実行します。ポリシーファイルに与えられたリビジョンは、インフラに新しい構成を安全に信頼できるものとしてデプロイするために、開発環境を通して昇格できます。
Policyfile.rbrun_listを指定しChefDKにCookbookを見つけさせるRuby DSLです。次のようになります。


# Policyfile.rb
name "jenkins"

default_source :community

run_list "java", "jenkins::master", "recipe[policyfile_demo]"

cookbook "policyfile_demo", path: "cookbooks/policyfile_demo"

chef installを実行したとき、ChefDKは必要なすべてのCookbookをキャッシュし、利用するCookbookのバージョン、Cookbookのコンテンツハッシュ、Cookbookのソース、その他関係するデータを記載したPolicyfile.lock.jsonを生成します。これは次のようになります。なおコンテンツは簡潔にしています。


{
"name": "jenkins",
"run_list": [
"recipe1", "recipe[jenkins::master]", "recipe[policyfile_demo::default]" ], "cookbook_locks": { "policyfile_demo": { "version": "0.1.0", "identifier": "f04cc40faf628253fe7d9566d66a1733fb1afbe9", "dotted_decimal_identifier": "67638399371010690.23642238397896298.25512023620585", "source": "cookbooks/policyfile_demo", "cache_key": null, "scm_info": null, "source_options": { "path": "cookbooks/policyfile_demo" } }, "java": { "version": "1.24.0", "identifier": "4c24ae46a6633e424925c24e683e0f43786236a3", "dotted_decimal_identifier": "21432429158228798.18657774985439294.16782456927907", "cache_key": "java-1.24.0-supermarket.getchef.com", "origin": "https://supermarket.getchef.com/api/v1/cookbooks/java/versions/1.24.0/download", "source_options": { "artifactserver": "https://supermarket.getchef.com/api/v1/cookbooks/java/versions/1.24.0/download", "version": "1.24.0" }

このCookbook群はあなたのVMやクラウドインスタンスでテストできます。あなたのChef Serverに結びつけたNode群にこのポリシーを適用する準備ができたら、特定のpolicy groupにポリシーのリビジョンをプッシュするためにchef pushコマンドを実行してください。私達はChef Serverにどのようにpolicy groupを実装するか決定していませんが、基本的なレベルでは、Nodeのコンテナであり、“staging”や“prod-cluster-1″といった名前をつけられる、与えられたポリシーと同じリビジョンをすべて適用するNode群です。ポリシーは“jenkins-master”や“webapp”や“database”といった名前を持ち、マシンの機能的な役割を示します。chef-clientの個々のインスタンスはpolicy grouppolicy両方を構成します。
chef pushコマンドはCookbookのコンテンツのSHA-1ハッシュに従って各Cookbookを格納する、新しいCookbookストレージAPIを用いてCookbookをアップロードし、chef-clientはインフラに一貫したCookbookコード群を適用します。新しいCookbook APIについてはChef RFCを見てください。chef-clientが動作する際、ポリシー名とポリシーグループを構成から読み込み、Serverから現在のポリシーの名前とグループを要求します。そして新しいストレージAPIからCookbookを取得し、普通通りに動作を行います。

動機とFAQ

ポリシーファイルはChefが構成コードをマシンに配布する現在の方法からかなり大きな変更です。私達のデザインの目的とポリシーファイルに関するよくある質問への答えをまとめました。

有用な仕事を行うためにマシンを構成するワークフローに注目

Chefの現在のツール、特にknifeはChef ServerのREST APIと密接な関係があり、それにより個々のオブジェクトを操作したりChef Serverにアップロードしたりすることに集中していました。chef-clientは、組織に対して何か有用な仕事を行うようにホストを構成するため、実行時にそれらの部品を組み立てます。ポリシーファイル機能により、私達は個々のコンポーネントというよりシステム全体を構築、構成するというワークフローに注目しようとしています。
例えば、ポリシーファイルはシステム全体を記述し、Policyfile.lockファイルの個々のリビジョンはすべての必要なコンポーネントとしてひとかたまりでChef Serverへアップロードされます。

コードの見通し

現在のChefでは、Nodeに適用する正確なCookbook群は次の項目で定義されています。

  • Nodeのrun_listプロパティ
  • Nodeのrun_listやそれらのRoleに再帰的に含まれるあらゆるRole
  • さまざまな制約演算子に従って、特定のNodeに対して有効な、正当なCookbookバージョン群を制限するEnvironment
  • Cookbook Metadataに指定された依存関係
  • Environmentと依存関係の評価基準に適合する最適なCookbook群を取得しようとする依存関係解決器の実装
  • あなたや組織の誰かかどうかに関わらず、Cookbookの特定バージョンの更新 (詳細は“Cookbookの変異性”を参照)

これらの条件はchef-clientの実行のたびに再評価され、chef-clientが実行するCookbookがどれか、roleの更新や新しいCookbookのアップロードの影響がどうなるか、正確に言い表せないことになります。
ポリシーファイル機能は、ワークステーション上でCookbook群を計算し、その結果を可読ドキュメントとして生成することで、この問題を解決します。chef-clientは、あなたが特定のポリシーグループを明示的に変更するまで、事前に計算した同じ結果を再利用します。

Roleの変異性

Roleは現在、グローバルなオブジェクトで、既存のRoleに対する変更はそのRoleをrun_list(直接指定か他のRoleのrun_listかに関わらず)に含むすべてのNodeにただちに適用されます。つまり、既存のRoleを更新することは大変危険であり、このため多くのユーザはそれらを放棄してしまおうと主張しています。ポリシーファイル機能はこの状況を2つの方法で改善します。
第一に、RoleはCookbook群が計算されるとき、言い換えるとchef installの段階で展開されます。RoleはPolicyfile.lock.jsonファイル内には現れません。この結果、Roleはポリシーの特定のリビジョンに“焼き入れ”され、Roleへの変更は段階的にテストと展開が可能となります。
第二に、ポリシーファイルは多数のNodeに対するrun_listの一元管理の別方法を提供するので、ポリシーとNode間の一対多関係ができあがります。これにより、ユーザが望むなら、ワークアラウンドとしてのRole Cookbookを使う必要なしに、Nodeのrun_listを管理するためのRoleの使用をやめることができます。

Cookbookの変異性

現在のChef Serverは、Cookbookの既存のバージョンが変異することを認めています。言い換えると、バージョン番号の変更なしでコードを変更して再アップロードできるので、“apache2 1.0.0″Cookbookはその時々で異なるコードとなりうる、ということです。これは初心者やある種のCIパターンによく見られることで、開発中のCookbookのリビジョンをChef Serverにアップロードすることに都合がよい反面、Roleの変異性と同じ問題を抱えています。あるユーザは厳格なテストプロセスに従ってこれが行われれば、すべての貢献者の変更点がマージされるなど完全に統合してよくテストされたCookbookのみがChef Serverに送られると主張します。このプロセスはよい開発習慣を強制しますが、すべての人に適切ではなく、Chef Serverから安全なふるまいを得るための必要条件ではありません。
ポリシーファイル機能は、Cookbookの変異性を認めない新しいChef ServerのCookbook配布APIを用いることで、この問題を解決します。名前の衝突を防ぐために、Cookbookは名前と、Cookbook自身の内容から計算された任意のIDによって格納されます。
名前とバージョンの衝突が引き起こす特に大きな問題は、ユーザが上流のCookbookをフォークして一時的に利用する必要がある場合です。ユーザが変更点を提供してメンテナがよく反応するとしても、ユーザはフォークを使わなければいけない期間があるでしょう。そして、バージョニングのジレンマもあります。ユーザがバージョンを上げなければ、Chef Server上でCookbookの現在のコピーは上書きされてしまいます。反対に、バージョン番号を上げると、Chef Server上でより新しいバージョンの上書きによって修正されるような将来のリリースのバージョン番号と衝突するかもしれません。
内容に基いたIDをメタデータとして用いることで、このような問題を容易にします。

でも、不明瞭なIDって混乱の元じゃ?

このような不明瞭なIDは、ユーザが慣れている名前やバージョン番号スキームに比べて十分でないことは重々承知しています。例えば、“my-cookbook 1.2.3″は“my-cookbook ddf827″に比べて十分に意味があると感じるでしょう。この問題を解決するため、ChefDKと新しいServer APIは次のようにしています。

  • Policyfile.rbを用いると、名前とバージョン番号という表現でほとんどのCookbookを取り扱うことができます。SupermarketのようなアーティファクトサービスでのCookbookは、慣れた形の名前とバージョン指定を用いることができ、gitでのCookbookは、慣れた形でのブランチ/タグ/リビジョンを用いることができ、ディスク上のCookbookはパスを指定できます。不明瞭なIDはほとんどの場合で目につきません。
  • Policyfile.lock.jsonと同様に、Cookbookに関する特別のメタデータが格納され、APIレスポンスに含まれます。これは、Supermarket、git、ローカルディスクなどといったCookbookの出元と、gitリビジョンのようなアップストリームIDを含みます。ローカルディスクから読み込まれたCookbookでは、ポリシーファイルの実装がCookbookがgitレポジトリにあるかを検知し、アップストリームURL、現在のリビジョンID、レポジトリがダーティーであるかどうか、コミットがリモートにプッシュされているかどうかを収集します。
  • 新しいCookbookストレージAPIにアップロードされたCookbookは、1.0.0-devのようにプレリリース部分を持つ拡張SemVerバージョン番号を持ちます。

Chef Serverでの不経済な計算の制限

chef-clientの実行に与えるCookbook群を決定するため、Chef ServerはすべてのCookbookのすべての既知のバージョンの依存関係データを読み込まなければならず、正確なCookbook群を決定するために(NPに)不経済な計算を走らせなければいけません。計算をWorkstationに行わせて、計算の頻度を落とすことは、Chef Serverをより効率のよいものとします。

ポリシーファイルはどこに置くの?

現在、ポリシーファイルを構成するには3つの主要な方法があります。

  • ポリシーファイルと関連するCookbookをデプロイするアプリケーションと同じレポジトリに格納します。内製の独自アプリケーションをデプロイするChefに慣れ親しんだ開発者なら、アプリケーションのソースコードと同じレポジトリにポリシーファイルを投入し、アプリケーションに関連したCookbookに加えてすべてまとめてバージョン管理しましょう。
  • Cookbookにポリシーファイルを格納します。レポジトリごとに単一のCookbookというワークフローに従っているなら、ポリシーファイルを最上位のCookbook、言い換えるとサーバの主要なアプリケーションをデプロイする最大の責任を負うCookbookのレポジトリに含めます。
  • 単一のディレクトリにすべてのポリシーファイルを格納します。これはモノリシックなCookbookレポジトリワークフローでポリシーファイルを用いる最も一般的な方法でしょう。このような方法でうまく運用するにはもう少し詳しい内容が必要です。

これを使わなくちゃいけなくなるの?

この変更は、Chef Client、ChefDK、Chef Serverに既存の機能と一緒に加えられたものです。既存のAPIを削除したり軽視したりする予定はありません。この計画は、現在の状況に比べてより安全でより自由な別の方法への切り替え手段を人々に提供することにあります。とは言うものの、これが広く採用されたならば、結局はChef Serverから依存関係解決器を削除することになるでしょう。

Berkshelfを置き換えるの?

ポリシーファイルはBerkshelfにおける“environment cookbook”パターンに対する完全な置き換えです。ポリシーファイルはberksから頂いたコードで、依存関係解決器とファイル取得器を提供します。よって、Berkshelfのいくつかの用途を置き換えるものとなるでしょう。しかし、Berkshelfよりは頑固ではないので、すべての用途でBerkshelfを置き換えるものとはならないでしょう。今後どうなるか注視していく必要があります。

レポジトリごとに単一Cookbookを使わなくちゃいけなくなるの?

いいえ。私達は“巨大レポジトリ”ワークフローをサポートするための最適な方法を考えていますので、サポートされるでしょう。特に、Policyfile.rbファイル(別の名前もサポートします)のバージョニングについて、chef-repoの内と外の場合のトレードオフに関する研究が必要です。私達はこのデザインを公表するためのドッグフードテストを計画しています。“巨大レポジトリ”ワークフローを用いているユーザは第三者のCookbookのための単一レポジトリを用いる利益を得るでしょうが、それは任意のもので、ユーザはそうすると決めたならベンダーブランチから少しずつ変換できます。

ポリシーファイルを使うにはワークフローを変えなくちゃいけないの?

その問いに対する答えは“ワークフロー”の定義次第です。
前述の通り、chef-repoを用いるかどうかは選択できますし、第三者のCookbookを取得するのにポリシーファイルを使うことやベンダーブランチのようなそれ以外の方法を使うこともできます。
あなたのチームは動作すると確認して完全に統合された“リリース”CookbookのみをChef Serverに配布することを決定できますが、製品バージョンの変異リスクなし、Cookbookの変異性問題に対するワークアラウンドとしてdevoddなどのようなバージョニング方式の必要なしで、Cookbookの開発バージョンも安全にChef Serverに配布できます。
とは言うものの、Workstationから製品環境へどのようにコードを構成したかという技巧は異なるでしょう。特に、ポリシーファイル機能を推奨された方法で用いるなら、更新したCookbookやRoleを配布してすべてのマシンにただちに適用することはできません。古いAPIを用いているツールは更新が必要です。

ポリシーファイルはバージョン付けされるの?

現時点では、Policyfile.lock.jsonファイルを格納するChef ServerのポリシーAPIに詳細なデザインはありません。決定したことの1つとしては、このファイルはpolicy groupによってネームスペースを確保されるということです。これが意味するところは、最低でもリリースプロセスの異なる段階に対してポリシーを自由に更新することが可能ということです。
例えば、“dev”“stage”“prod”というポリシーグループがある場合、新機能は“dev”で繰り返し、致命的な修正は“prod”にリリースするというように、お互いに自由に行えるということです。
これがすべて実装されれば、Policyfile.rbファイルとPolicyfile.lock.jsonファイルはリビジョンコントロールにコミットし、リリース要求に適したブランチポリシーを用いることで、ポリシーをバージョン付けできるようになります。
とは言うものの、過去の変更の取り消し、やり直し、追跡のような操作をサポートする機能は構想段階です。

Environmentはどうなるの?

Environmentがポリシーファイルとどのように動作するかの最終決定はまだ行っていません。互換モードではEnvironmentとポリシーファイルを同時に使うことはできませんが、この決定は覆される可能性があります。
ポリシーファイルはEnvironment機能におけるCookbookバージョン指定を完全に置き換えます。しかし、Environmentは、ユーザにとって重要な、Environment間のAttributeを設定するための便利な方法を提供しています。Environmentの頭の痛い問題は、Environmentの更新はそのEnvironmentに属するすべてのNodeにただちに伝播するという、他のたくさんのChefの機能と同様の諸刃の剣を提供していることです。正常に行われた場合はとても便利ですが、同様に失敗もすぐにすべてのNodeに伝播してしまいます。反対に、もしEnvironment Attributeがポリシーファイルに格納されるなら、変更点の影響のテストがより簡単に行えるようになり、更新の適用方法を操作できるようになりますが、変更を広く適用することがより難しくなります。

互換モード

ポリシーファイル機能はChef Serverにはまだ存在していない新しいAPIに依存しています。この機能のプレビューを提供するために、現在の実装はポリシーファイルの動作を真似するためにChef Serverの既存のAPIを用いて互換モードで動作しています。これは同じOrganization、あるいは同じオープンソース版Chef Server 11.xにおいて、安全にポリシーファイルと現在のコード配布機構を使うことを難しくしています。そのため、私達はポリシーファイル機能を試す場合は分割したOrganizationの利用を推奨しています。

Cookbookアーティファクトストレージ

互換モードでは、ChefDKは、既存の/cookbooksエンドポイントを用いる内容のハッシュに基いたCookbookのストレージを実装しなければいけません。このため、ハッシュIDをX.Y.Zバージョン番号にマッピングしています。この動作はポリシーファイルの動作を真似するためのその場しのぎです。ポリシーファイル機能を互換モードで試す場合、次の点に注意してください。

  • ポリシーファイルコマンドによってアップロードされるCookbookは、ソートされていない順序の巨大なバージョン番号がつきます。ポリシーファイルモードで動作していないあらゆるchef-clientは、あなたがEnvironmentでバージョン指定しているように慎重でない限り、普通にアップロードされたCookbookではなく、それらのCookbookを選んでしまうでしょう。
  • /cookbooksエンドポイントはこのような用途に作られていないので、それらのCookbookの“真の”バージョン番号や追加的なメタデータを表示しません。実装の最終形では任意のCookbook IDをより簡単に扱えるように計画していますが、既存のAPIにできることはほとんどありません。
ポリシーファイルストレージ

互換モードでは、Chef DKはData Bag ItemをPolicyfile.lock.jsonファイルに格納します。他のData Bag Itemとの衝突の機会を極力減らすために、ChefDKは“policyfiles”Data Bagにそれらすべてを格納します。個々のPolicyfile.lock.jsonリビジョンは$policyname-policygroupの形式でIDが与えられます。

今後予定している機能

ポリシーファイル機能の実装はまだまだ完全ではありません。次は製品として提供できるリリースへ向けて私達が作業している機能の一覧です。

  • 保守的な更新: Policyfile.lock.json内のCookbook群をアップデートします。
  • Roleサポート: Policyfile.rb内のrun listでRoleはまだサポートされていませんが、もうすぐされるでしょう。
  • ポリシーファイル Attribute: Policyfile.rb内に直接RoleレベルのAttributeを設定できるようになります。
  • 複数のrun listをサポート: ポリシーファイルはrun listの上書きをサポートしません。Policyfile.rb内で名付けられたrun listが代替として用意されます。
  • 内製Cookbookホスティング: 現在、ファイアウォールの背後にCookbookをホストできません。Chef Serverの/cookbooksエンドポイントを“ミニSupermarket”として扱えるようにサポートを追加するか、完全なSupermarketインスタンスを実行できるようにします。
  • Server APIサポート: 前述の通り、ポリシーファイルとCookbookストレージの“ネイティブ”サポートをChef Serverに追加します。

サミットでお会いしましょう!

ポリシーファイルに関することで何か話したいことがあれば、コミュニティサミットがとてもよい場所です。聞きたいことがあるのに行けないというなら、私達はメーリングリストやIRCで質問を受け付けています。


新規CTA