Upload
uchio-kondo
View
2.589
Download
0
Embed Size (px)
Citation preview
GMO Pepabo, Inc. Uchio KONDO
2015/07/04 Pepabo Techconf in Fukuoka
2015年のPuppet
me
近藤 うちお @udzura 技術基盤チーム
アドバンスドシニア
自動化厨DevOps’er
hashicorp太郎
Puppet?
Puppetと聞いて どう思った?
Puppet> 古い > 独自言語でとっつきにくい > MizzyさんのPuppet 2系の記事 > 古い > 時代はChef、いやChefすらオワコン、Itamaeでは????
> いやRubyなんて(ry、Ansibleでは??????
Puppet> 古い > 独自言語でとっつきにくい > MizzyさんのPuppet 2系の記事 > 古い > 時代はChef、いやChefすらオワコン、Itamaeでは????
> いやRubyなんて(ry、Ansibleでは??????
Puppetは2015年のいまも 継続的に開発されている アクティブなツールです
本プレゼンテーションで Puppetの誤解を
少しでも解けるのなら、幸いです
Puppetのご紹介
Puppetとは> 構成管理のための言語です
Puppetとは> 構成管理のための言語ですChef っぽいやつ
Puppetとは……> サーバのファイル、パッケージ、サービス、ユーザその他設定をいい感じに収束させてくれて、
> なおかつコードとして残せる感じのやつです
じっと見ていると Perl Rubyに見えてくる
Puppetその他> 中身はRuby > なので後述しますがChefと同様Rubyで!拡張機能が書けます
> clientとmaster/agent構成を選べる > Chefと同様(ry
> librarian-puppet というやつでコミュニティのマニフェストを使える > ChefのBerkshelfと同様(ry
Puppetとは> 構成管理のための言語ですChef っぽいやつ
Chef が分かれば すぐ覚えられます
Puppetの歴史(独断と偏見版)> 2005年 Puppetがリリースされたらしい > ~~~ > 2010年 Puppet 2.6 > 2012年 Puppet 3 が出る
Puppetの歴史(独断と偏見版)> 2005年 Puppetがリリースされたらしい > ~~~ > 2010年 Puppet 2.6 > 2012年 Puppet 3 が出る > 2013年 伊藤直也さんが入門Chefを刊行
2014年からのPuppet> 2014年 いいかげんPuppet3.6とかになる > 突然puppetserverが出現、 clojure で書かれる
> 2015年 突然Puppet4が出る > そして伝説へ……
勢いあるね?
Why Puppet
ペパボでPuppetな理由> 社内のノウハウが非常に蓄積されている > minneのような新規のPJもPuppetで構成管理をはじめ、非常に多くのアドバイスのもと完了した
> 一番スピードが出せる
ペパボでPuppetな理由> 「RubyのDSLじゃない」ことのメリット > Rubyの機能をむやみに呼んでしまわない > Kernel#systemやFile.exist?を直接呼ぶ混乱
> 他のツールに比べると、勢いはあるが根本的な仕様変更は少ない > 良い枯れ方をしていると判断
ツール選びで大事なこと> ひとつのツールに精通する > ちゃんとそのコミュニティに貢献する > 今日はPuppetに貢献するぞ!
Puppet language update
puppetserverの JVM化
それまで> puppetmasterという名前だった > Ruby製 > Rack対応していて、Passengerで動かすなどしていた
puppetserverの登場> 2014/09 Puppetlabsのアナウンス > https://puppetlabs.com/blog/puppet-server-bringing-soa-to-a-
puppet-master-near-you > 要約: Clojureにするわ > えっ。……?
_人人人人人人人人人人_ > 突然の < ‾Y^Y^Y^Y^Y^Y^Y‾
勢いある事例> PuppetserverのためにClojureのWAFをつくったらしい > Trapperkeeper という名前 > https://github.com/puppetlabs/trapperkeeper
勢いある事例> PuppetserverのためにClojureのWAFをつくったらしい > Trapperkeeper という名前 > https://github.com/puppetlabs/trapperkeeper
> 既存のPuppet parserはJRuby
複数JVM言語カジュアル
こう変わった> 高速になったらしい > 今まで以上にインストールが楽 > yum install puppetserver 一発に
> 運用も楽 > Apache/Passengerのノウハウはいらない
> 設定ファイルが新しくなっている > 既存の設定も読んでくれる、徐々にマイグレートしよう……
Puppet4
Puppet3の時代の終焉> Puppet 3.7 あたりからめちゃくちゃdeprecation warningが出るように……
> ついこないだ(2015/04)、Puppet4のリリースがされた! > https://puppetlabs.com/blog/say-hello-open-source-puppet-4
消えた機能> Ruby 1.8.7 サポートをやめる > Bad Practice的機能が消えている > Ruby DSL…… > import文 > node inheritance
> ベストプラクティスに沿っていれば、何れにしても使わなそう
EPP(Embedded PuPpet)> ERBのようにPuppetを埋め込む…… > http://puppet-on-the-edge.blogspot.co.uk/2014/03/templating-with-embedded-puppet.html
Ruby並みにイテレータが……> each! map! filter!!!!
Ruby並みにイテレータが……> each! map! filter!!!!
type hinting!!
その他変更> パッケージが All-In-One に > Autoloadingの挙動変更(依存をきっちり書かないと見えなくなる)
> Optional Typing > 文法的変更(substring記法、Hashの展開など……) > その他たくさん…… > http://www.slideshare.net/PuppetLabs/puppet-language-40-puppetconf-2014
既存のマニフェストは……?> deprecation warningを真面目に倒していれば問題は少ない > Rails的な乗り切り方ですね
> 後述するFactorとかRubyな奴も動く > リモートのmoduleは……PRやforkで……
“– http://www.slideshare.net/PuppetLabs/puppet-language-40-puppetconf-2014
“Yamata no Orochi”
なお、今日のExcuse> あまりに最近出たのでPuppet 4の検証が十分ではありません……
> 今日の色々な例は、Puppet 3.xの最新版(3.8系)で確認しています……
> 「2014年のPuppet」かもしれない
Puppetを書く
ディレクトリのパターン
ここで登場する名著
このパターン. ├── Puppetfile ├── Vagrantfile ├── config/ ├── hiera/ ├── manifests/ ├── modules/ ├── roles/ ├── spec/ └── vendor/ └── modules/
このパターン. ├── Puppetfile ├── Vagrantfile ├── config/ ├── hiera/ ├── manifests/ ├── modules/ ├── roles/ ├── spec/ └── vendor/ └── modules/
…… 設定、capistranoとか …… hieraのデータ …… 実際に実行する、エントリポイント …… 全体で使うモジュール …… ロールとして扱うモジュール …… serverspecです! …… librarianで入れるモジュール
モジュールの中のディレクトリ> こっちはPuppet的に規約がある > manifests/init.pp がデフォルトで読まれるクラス consul になる
> その他は manifests/config.pp ならクラス consul::config を定義する
modules/consul ├── files/ ├── manifests/ └── templates/
tamplates/, files/ 配下は……> 諸説ある > destとディレクトリを合わせた方がいいんじゃね?派 > /etc/foo/foo.conf なら templates/etc/foo/foo.conf
> 名前だけ合わせればいいよ派 > /etc/foo/foo.conf なら templates/foo.conf だけ > 被ったらサブディレクトリを切るなど
> 状況による。個人的に後者でも混乱しないことが多い
クラスを作る
黄金パターン> dnsmasq を管理するモジュールなら:
modules/dnsmasq/manifests/ ├── config.pp ├── init.pp ├── install.pp └── service.pp
init.pp> 他のクラスを読み込む > 依存を明示的に書く
その他> install.pp > パッケージを入れる
> config.pp > カスタマイズした場合設定を管理する
> service.pp > サービスの状態(有効か、立ち上がっているか)の定義 > 定義しておけば、他のモジュールから notify でキックで再起動できる > config.ppは変更時にかならずservice.ppをnotifyするはず
それ以外っぽい要素は> 適宜クラスを作成すれば良い > 依存するyum repoを定義するのを切り出すとか > プラグインのインストールを切り出すとか
一つのクラスの責務を 小さくするのがコツ
依存関係の記述
Puppetの依存関係解決は自動じゃない> Chefのように「上から実行」とは限らない > -> と ~> がある > Resource[‘A’] -> Resource[‘B’] > AのあとにBを設定する
> Resource[‘A’] ~> Service[‘B’] > Aを設定したら、サービスBを再起動する
「一発で通す」ために> ChefにしてもPuppetにしても、「失敗するんで何回かキックする」ということがあるはず > 冪等性万歳!
> しかしPuppetの場合、「ここが足りないからエラーなんだな」というのを追いかければ、 依存性を明示することで「通せる」ようにしやすい
具体例> Nagiosを入れる > Nagiosの自作プラグインを入れる
どっちが先かは実行時による> なので、「プラグイン」→「Nagios」の順だと、 nagios-plugins-allパッケージの生成するディレクトリが作られていないので、プラグインのfileリソースが失敗する
> なので nagios-plugins-all -> カスタムプラグインの依存を明示したい
すればいいじゃない
無事通るようになる> よかったですね
「通知する」パターン> 典型的: 「zipを落として解凍したい」 > 解凍する処理が毎回走ると無駄なので、refreshonly にして notify でキック
> Chefで言うと…… > action :nothing する > ダウンロードの処理とかで notify ‘exec[unzip]’
例えばこう
Defined Types
Defined Types> 「ひとまとまりのリソース定義」を独立したリソースのように見せかけることができる
> マクロ感覚 > コツとしては、Defined Typesの中でも 依存関係を意識すること
ここでも具体例> consulのcheck設定をdefined typeにした
> ディレクトリのためにconsulパッケージが必須とする
> テンプレートの場所は規約で。
こういう書き方ができるようになる> 依存記述が綺麗になる > <| |> はマニア機能だが、「~に所属するすべてのリソース」ぐらいの意味
その他のベストプラクティス
参考便利スライド> http://www.slideshare.net/PuppetLabs/upgrading-puppet
> Puppet 4対応記法こそが良い記法です
Puppet in Action
Puppet in Action とは> あんまり日本語で説明している人がいないような機能を紹介します
Hiera
Hieraとは> Hierarchy Data > 環境別の設定項目をYAMLに切り出せる
Hieraの例です> hiera/hieta.yaml
> hiera/development/common.yaml
Custom Function
Puppetの関数をrubyで書ける> rootfsがaufsかを判定する例 > Docker分岐カジュアル
Custom Facter
そもそもFacterとは> 設定対象サーバの様々なパラメータを動的に簡単に取得するやつ
> たとえばホスト名、OSの種類、メモリやCPUの情報、インタフェース、などなど……
> factor ではない
そもそもFacterとは> 設定対象サーバの様々なパラメータを動的に簡単に取得するやつ
> たとえばホスト名、OSの種類、メモリやCPUの情報、インタフェース、などなど……
> factor ではない > いろいろ言いましたが、Chefでいうohaiです
カスタムFactorもRubyで。
なんでFunctionよりFacterか> Facterは、環境変数で上書きできるので、色々な意味で扱いやすい
> FACTER_FOO で $::foo に値が入る
☕ 休憩 ☕
PuppetとインフラCI
ここからの話題は Chef/Ansible/Itamaeにも
置き換えられるよ!
あと、ここから 難易度一気に上がる気がする……
「壊れないマニフェスト」
再掲:「一発で通す」ために> ChefにしてもPuppetにしても、「失敗するんで何回かキックする」ということがあるはず > 冪等性征万歳!
> しかしPuppetの場合、「ここが足りないからエラーなんだな」というのを追いかければ、 依存性を明示することで「通せる」ようにしやすい
再掲:「一発で通す」ために> ChefにしてもPuppetにしても、「失敗するんで何回かキックする」ということがあるはず > 冪等性征万歳!
> しかしPuppetの場合、「ここが足りないからエラーなんだな」というのを追いかければ、 依存性を明示することで「通せる」ようにしやすい
再現しないマニフェスト> 「本番なら動くけど手元で再現できないなあ……」
> 逆に、「本番に適用するのこわくね?」 > 安心感が欲しい
apply恐怖症を克服する> そのためには、何度もカジュアルにpuppetマニフェストを実行することが
> 一番の近道である。 > なんども実行できるということは、どこでも実行できるということにつながる
よろしい ならばCIだ
Docker
DockerとインフラCI> Puppetのテストなので、「実際に」何かのマシンにpuppetを流さないといけない
> マシンの例: > VirtualBox……重い > kvm……重い、Mac上で動かせない > 世の中にはコンテナ技術というものがある……なるほど?
Dockerが解決すること> 軽量で、すぐに立ち上がること > ベースとなるイメージのコード化、使い回し > Macでも手軽に試せる > boot2dockerの存在
Dockerが解決しないこと> kernelは、ホストのLinuxのそれになる…… > なので一部のパッケージが動かなかったりする
> まだまだバグ、undocumentedな挙動がある
cap_set_file問題
cap_set_file問題> httpd、systemdなど一部のパッケージが aufsバックエンドでインストールできない
> 原因は、aufs側の問題で、カーネルのバージョンをあげると解決 > 3.18以降とのこと > https://github.com/boot2docker/boot2docker/pull/818 など
> devicemapperでは問題は起きない(ただしパフォーマンスの問題はある)
気持ちになって Dockerを使う
Serverspec
Serverspecとは> Puppetに限らず、サーバの状態を宣言的に、手軽に検査する敷居の低いツール
> rspecを利用 > specinfraという、サーバ操作をいい感じに抽象化するライブラリを使う
なんだかPuppetと相性がいい気がする> 気のせい?
Puppetを流したあとで> もちろん、Serverspecも流す! > Puppet的には通過するけどいけてないパターン(例: サービスが立ち上がったはいいけどすぐに落ちる)もあるので、それを検知する
Ruby 2.0系のトラップ……> コメントに日本語が混ざると、エンコーディングってやつがね……
> RUBYOPT=-Eutf-8:utf-8 を渡して解決 > 詳細の話は > http://docs.ruby-lang.org/ja/2.2.0/method/Encoding/s/default_external.html
Drone.io
って何?> CIするやつ > トラヴィスなんとかのようなことがOSSでできて、割と運用が楽
> 書いた: 「Drone.io のご紹介」 > ムックもある「Dockerエキスパート養成読本」
http://www.slideshare.net/udzura/droneio
Drone loves Docker> 具体的には、ビルドごとにDockerのコンテナを立ち上げるので、クリーンな環境でテストができて便利である
Docker in Dockerする> Dockerコンテナからは、当然Dockerサーバ自体が見えるので、
> そこをクライアントから叩けばコンテナないから別のコンテナを立ち上げ、アクセスできる
> DockerによるインフラCIが実現!!1
docker-in-docker> Dockerfileです
> refs: https://registry.hub.docker.com/u/igneoussystems/docker-client/dockerfile/
ここまでの全体の様子
ここまでの全体の様子
Puppetのコードをプッシュ
ここまでの全体の様子
Drone.io のジョブで 素のDockerコンテナを作成。 そのコンテナにPuppetを適用、
Serverspecも流す
ここまでの全体の様子
※merge後のCIが成功したら、Puppetserverに自動でマニフェストを配備
(Continuous Delivery)
CIのコツ
ずばり、やりすぎないことです……
インフラCIのyak要素> そもそも本番と環境違うじゃん > Docker vs KVM, Xen……(時にはベアメタル) > 動かないマニフェストはどうしても動かない > エッジすぎる技術要素 > Dockerは人類には早すぎるのか?何度も思い、心が折れそうになりました
CIでスキップする分岐があってもいいじゃない……
> 「何も動かさない」ことと「まあ、だいたい動いてる」こととの間には越えられない壁がある
インフラCIの将来……> そもそもOpenStack基盤できつつあるしそこでやればいいんじゃと思ってる(起動時間問題はある)
> vagrant-kvm とかを試す
Puppetと未来のデプロイについて
手動のサーバ構築をイメージをポンと起動するだけに
したお話
イメージぽんのための概念> Orchestration > Application Service Deployment
> Configuration > System Configuration
> Bootstrapping > OS install > Cloud or VM Image Launch
http://mizzy.org/blog/2010/03/26/1/
要するに> 秘伝のイメージを作る > できれば完全にコード化された形で作る
> 秘伝のイメージの起動初期化処理を完璧にする > 既存サーバとの繋ぎこみを綺麗にする
> これらすべてが自動化すれば、サーバ構築はすべて自動化できるということになる
バンド「The DevOps」> メンバー紹介 > ドラム: Packer > ベース: cloud-init > ギター: Consul > ボーカルはあなたのWebアプリだ!
Packer
Packerがやってること> プラットフォーム別に起動・接続・イメージ化を抽象化する(Builder)
> 接続して様々なプロビジョニング処理を走らせる(Provisioner)
> 後処理をする(Post-Processor)
AWS/OpenStackなどのクラウドでは> あらかじめ公開鍵ペアをAPI経由で用意 > 最低限のイメージからインスタンスを立ち上げる > 立ち上げたインスタンスにつなぐ > シェル、ファイルアップロードなど 各種プロビジョニングをする
> イメージ化のAPIを叩いてイメージにする
AWS/OpenStackなどのクラウドでは> あらかじめ公開鍵ペアをAPI経由で用意 > 最低限のイメージからインスタンスを立ち上げる > 立ち上げたインスタンスにつなぐ > シェル、ファイルアップロードなど 各種プロビジョニングをする
> イメージ化のAPIを叩いてイメージにする
ここはBuilderで やってくれる
AWS/OpenStackなどのクラウドでは> あらかじめ公開鍵ペアをAPI経由で用意 > 最低限のイメージからインスタンスを立ち上げる > 立ち上げたインスタンスにつなぐ > シェル、ファイルアップロードなど 各種プロビジョニングをする
> イメージ化のAPIを叩いてイメージにする
ここはBuilderで やってくれる
※まあOpenStackのは自作したけど、それはまた別の機会で……
AWS/OpenStackなどのクラウドでは> あらかじめ公開鍵ペアをAPI経由で用意 > 最低限のイメージからインスタンスを立ち上げる > 立ち上げたインスタンスにつなぐ > シェル、ファイルアップロードなど 各種プロビジョニングをする
> イメージ化のAPIを叩いてイメージにする
プロビジョニングが うまくいかないとダメ
そこでPuppet
Puppetを流す!> masterをあらかじめ立てておけば、 > あとは puppet agent するだけで完成!
Puppetの質が重要> そのために、一発で通るPuppetであることが非常に重要
> なのでCIなど、壊さない工夫が重要になる > Packerのプラグインがあるけど…… > シェル数行なのでシェルプロビジョナでやればいいと思う
イメージはできた
それからどうする?
cloud-init
cloud-initって知ってますか……> AWSerは「userdata」とかサラッと言ってるけど割と独特の概念
> OpenStack, GCEその他でも共通 > 今日は覚えて帰ってください
cloud-init概要> クラウド系プラットフォームにおいて、 > イメージからVMを立ち上げて、直後に走らせる処理を簡潔に書くミドルウェア
> その「初期化指示書」がuserdataと呼ばれる > シェルスクリプト > 宣言的にyamlで記述もできる
yaml
こんなことをさせる> 起動時にHDDを拡張する > ホスト名を変える > mackerel、Consulなどのクラスタにジョインする
> 起動したよ~って通知する > などなど……
深い話は> [cloud-init zetta.io] で検索するとわりといいドキュメントが出る
> [cloud-init kenchan per-xxx]でry > もしくは会場のlinyowsさんに聞く
userdataの指定の様子> nova boot \ --flavor m1.xlarge \ --image foo_base_image \ --security-groups base,www --user-data ./userdata/foo.yaml
やった!起動したぞ
起動したあとも いろいろあるんだわ……
Consul
Consul> クラスタをいい感じにしてくれるやつ > ヘルスチェックとか > クラスタの状態に応じて設定ファイルを自動生成するとか
> やっぱり通知とか
詳細は前回のやつで……> [udzura consul]
まとめ
Puppetはナウい
Puppetは 枯れていつつも 開発が活発
情報が 古いだけで古いイメージ
よくない
Puppetは 扱いやすい!
Puppetでなくてもいいけど、 ツールの本質を掴んで
使いこなそう!
Puppetはナウい
Special Thanks
圧倒的感謝> 人間puppet masterこと@lamanotlama さん
> 若手インフラ @hfm さん > Puppet学習初期のこのお二人のご指導なくして、ここまで素早い学習はなかったと思います
画像引用元> タイトル画像 > https://commons.wikimedia.org/wiki/File:Takarazuka_Grand_Theater05s4s3104.jpg > GFDL+creative commons2.5
[PR]
ペパボにはPuppetを使う仕事があります> 福岡でもインフラ絶賛募集! > ペパランチョンでお話を。 > https://pepabo.com/recruit/pepaluncheon/?fukuoka