この記事について
puppetを初めて触ってから3,4年くらい経ったが、その間に思ったことなどをまとめてみる. なぜpuppetか、何に使っているか、使っていて思ったこと、課題など.
利用状況を簡単に
こんな環境で使ってます.
puppetの使用環境
CentOS 5 and 6で、puppetは2.7.21. 大体4つくらいの独立した(ネットワーク的に分断された)環境で、サーバ台数は合計百数十台. サーバ上で稼働する(した)ソフトウェアはHadoop, fluentd, MongoDB, Cassandra, MySQL, Munin等.
何に使っているか
上記ソフトウェアの環境は基本的にpuppetで構築している.が、puppetで完結できていることだけではないので、それは後述
使っていて思ったこと
今まで使っていて思ったことなどを書いてみる.
puppetで何が良いか
puppetだけではなく、chef等でも一緒だと思うけど、この手のソフトウェアを使わない場合だと、シェルスクリプトで頑張るか、VMのイメージをコピーするか、になると思う. それぞれに対して比較すると
- シェルスクリプト等でやる場合
- 色々全部自分で書かないといけないのでしんどい. 単一の環境、初回構築なら良いけど、ちょっと違う環境を作るとか、一旦作った環境に変更を加えるとか. 規模が大きくなってくると、モジュール化したり、過去に作ったものを再利用したくなるけど、その点でもつらい.
- VMのイメージコピーの場合
- 既に構築済の環境に対する変更をどう適用するか、環境の変更履歴をどう管理するか、というところが課題.
puppetは、”このサーバはこうあるべき”と定義すれば、前の状態がどうであってもその状態にしてくれるので、いちいちチェックして、期待と違ったら処理をして、みたいなことを書かなくて済む. また、クラス、モジュール、等再利用性を促すような言語の機能もあるので、うまく書けば既存のコードを流用しつつ、新しい要件に対応するようにマニフェストを変更していくようなこともやりやすい.
ただ、実はそれだけではなくてInfrastructure as Code, サーバ環境がコードで表現できるようになり、アプリケーションのコードと同じように変更管理、レビュー、テスト、デプロイができるようになるのが大きいと思う. このあたりはnaoyaさんの記事に詳しく書かれている.
puppetの使いどころ
サーバ構築のうち、何をpuppetでやるべきか?サーバ構築はBootstrapping, Configuration, Orchestrationの3つのレイヤに分けて考えられることが多いが、この中だとConfigurationの部分をpuppetでやることが有効
つまり、
- Bootstrappingに相当する部分、OSインストール、ネットワーク設定、puppet自体のインストール、はやらない(やれない)
- Orchestrationに相当する部分、複数台の協調操作が必要な操作もやらない. 今はここはfabric(局所的にserf)でやっている.
- その他、puppetが動作可能になった後のconfigurationで、単一サーバ内で完結するようなものは全てpuppetで行う.
という感じにしている.
マニフェストのいい感じの書き方
いい感じ、というのは読みやすく、再利用しやすい、ということ. これは、使い始めてからずっと試行錯誤しているところ. そのための要素としては、以下があると思う.
- モジュールの書き方
- モジュールを組み合わせて、実際のサーバに適用するマニフェストにする部分をどう書くか
- 環境依存する部分をどのように切り出すか
まず、1について. モジュールはライブラリのように環境が変わっても再利用可能なものであるべき. どのような書き方が良いか、というのはこのドキュメントに書かれている. puppetlabs公式のntpモジュールが、お手本としては良いらしい.
2については、以下で紹介されている、RoleとProfileという考え方を導入するのが良い.
moduleを複数まとめてprofileが構成され、さらに複数profileをまとめてroleが構成される. node(=物理ホスト)は、一つのroleに紐付けられる、という形になっている. 例えば、profile::webserver
にはhttpdとphpが必要で、role::www::dev
は、profile::webserver
とprofile::database
が含まれる、みたいな形に書く. ただ、自分はまだroleの必要性がしっくりきてないので、profileとroleを分けていない.
3については、hieraやENCを使ってあるサーバに適用するクラス(role/profile)や、そのパラメータをマニフェストの外に切り出す、というのが定番らしい. ただ、自分はまだこれらは導入していなくて、以下のように変数をまとめたクラスを作って、それを呼び出すときの引数で環境を切り替える、という風にしている. 今後はhiera or ENCに移行していきたい.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
1 2 3 4 5 6 |
|
1 2 3 4 5 |
|
puppetmasterについて
つい最近まではpuppetmasterを使っていた. ただ、以下の問題があった.
- 新しくサーバを構築するときにpuppetmasterが無ければ立てる必要がある
- 証明書が面倒. 自動署名にはしてるけど、同じホスト名でサーバの再構築することもそれなりにあったので、その度に証明書のクリアが必要. クリアしてなくてうまく同期できない、というのも良くあった.
なので、最近はgitリポジトリにmanifestを配置して、各サーバでgit clone. という風にしている. マニフェストを更新した時は、fabricを使って並列にgit pull & puppet applyする. 証明書の問題から開放されたし、サーバ台数が増えてもgitリポジトリを複数にすればスケールするし、gitが無くてもmanifestだけコピーすれば環境作れるし、でとても楽になった.
今後の課題
今はできていないので、これから取り組みたいこと.
テスト
上記の通り、puppet化、というかコード化するメリットとしてCI的なものは外せないと思うのだけど、まだできていない. 幸い先人の事例があるので、こちらを真似しながら環境はできた. ただ、まだ実験的な段階で、プロセスとして固まってない. Dockerだけでなく実機の環境もあるので、Dockerでテストして、通ったものは即検証環境に自動的にデプロイして、みたいな形にしたい.
外部モジュール(Puppet Forge)の利用
puppetを始めた当初は、公開されているモジュールがあると言っても今一つやりたいことにフィットしなくて、全て自分で書いていたのだけど、最近は公開されているものを有効活用した方が良い気がしてきた. 実際serfとかsensuとかのモジュールを使ってみたが、全然変更の必要が無く使えたので、これからは外部のものも使っていきたい. ただ、自分のいる環境はInternetにつながらないのでpuppet module
コマンドは使えず、どうやって配布するかを考えないといけない. (自前リポジトリとか立てられるのかな…)
最後に
最近Infrastructure as Codeという言葉も良く聞かれるようになったし、自分も今までpuppetを使ってて思ったことを一度まとめてみようと思って書いてみた. しかし、puppetってやっぱり日本語の記事が少ない. 入門的な記事はあるのだけど、どう使ってるとか、何に困ったとか、どう工夫してるとかの情報がもっとあると良いなぁ. Qiitaでそれぞれのタグを見てみたら、Chefの投稿が242に対して、Puppetは11でした…