SlideShare a Scribd company logo
Fabric Essentials
Yoshinari Takaoka
Kauli.inc
Agenda
目的:Capistrano から Fabric に移行したので
基本的なプラクティスを共有したい
●

Fabric の紹介

●

チュートリアル

●

Kauli のプラクティス

●

これからの展開

●

まとめ
Fabric の紹介
Fabric?
●

●

ssh で繋がったサーバ群にコマンドを一気に実行
するツール
それなりの台数が並んだサーバ群のシステム管理
やデプロイに使われる

●

http://fabfile.org/

●

同種のソフト
- Ruby の Capistrano や mina
- Perl の Cinnamon など
Fabric に移行した理由
●

Python で楽に書ける
- Kauli は Python の会社

●

Capistrano と出来ることにあまり差異はないようだ
- Capistrano でも現在込み入ったことはしていない
- Ruby なソフトウェアは バージョンアップ的な意味で 運用にあ
まり優しくない
Capistrano とやれることに差がないのであれば
移行してメンテできる人を増やした方がよい
チュートリアル
インストールは簡単(Ubuntu 12.04)
$ apt-get install build-essential python-dev
python-virtualenv
$ virtualenv fabrictest
$ cd fabrictest
$ source bin/activate
$ pip install fabric
以下、この環境を前提に説明します。
まずは Hello World

●

●

public な callableオブジェクト (関数やクラスな
ど) を実行単位(タスク) として定義
local 関数は localhost でシェルコマンドを実行
... 実は古いスタイルだけどね(後述)
まずは Hello World(2)
実際に以下をやってみる
●

fabfile.py に保存

●

task を一覧する
$ fab -l

●

タスクを実行する
$ fab hello

... デフォルト。変更可
リモートでコマンドを実行
●

run と sudo 関数をタスクの中で呼び出せばよい。
これらはリモートでコマンドを実行するときの基本。
local と区別する
リモートでコマンドを実行(2)
●
●
●

前のページのコードを実際に実行してみる
ssh で接続できることが前提
実行先のホストをどこかで指定する必要がある
- 指定する方法多数。Fabric を使うにあたっての
肝なのでこの後詳述。
実行先のホストを指定する方法(1)
●

●

ホスト単位
- 個々のホストを指定する
ロール(Role)単位
- 同じ役割の複数のホストをひとまとめにして
名前を付け、それを指定する
- fabfile.py 内で env.roledefs の定義が必須
実行先のホストを指定する方法(2)
●

env 変数でホストやロールを指定する
実行先のホストを指定する方法(3)
●

デコレータでホストやロールを指定する
実行先のホストを指定する方法(4)
●

コマンドラインからホストやロールを指定可
$ fab -H host1 hello
$ fab -R role1 hello
ホスト指定の裏技
$ fab hello:hosts=”host1,host2”
$ fab hello:roles=”role1”
●

●

●

上記はこれまで説明してきたどの指定方法よりも優
先される
デコレータの指定などを無視して意図しない動作を
させることが可能
事故の元なので使うべきではない。てか使うな。
ホスト指定方法と優先順位
               (優先順位高)
●
●
●
●

ホスト指定の裏技
デコレータ
env.hosts, env.roles 変数
コマンドライン
               (優先順位低)
優先順位を知った上でホスト指定を組み立てる
ことが重要
例題1:
Q. どのホストが呼び出されるか?
$ fab hello
def hello():
run(“echo 'hello world'”)
デコレータや env.hosts, env.roles が指定されて
いないと、どこも指定されていないのと同義
例題2:
Q. どのホストが呼び出されるか?
$ fab -H host1 hello
def hello():
run(“echo 'hello world'”)
例題3:
Q. どのホストが呼び出されるか?
$ fab -H host1 hello
@host('host2')
def hello():
run(“echo 'hello world'”)
例題4:
Q. どのホストが呼び出されるか?
$ fab -H host1 hello
env.hosts = ['host3','host4']
@host('host2')
def hello():
run(“echo 'hello world'”)
例題5:
Q. どのホストが呼び出されるか?
$ fab hello
env.roledefs = { 'role1': [ 'host1','host2','host3'] }
@host('host2')
@roles('role1')
def hello():
run(“echo 'hello world'”)
例題6:
Q. どのホストが呼び出されるか?
$ fab hello:hosts=”host2, host3”
@hosts('host1')
def hello():
run(“echo 'hello world'”)
ホスト指定まとめ(1)
●

ホスト指定の裏技は使うな
- デコレータや env 変数の設定を全て上書きでき
るので意図しない動作を産む可能性大

●

ホスト指定の裏技を除けば、実質デコレータが一番
優先順位が高い

●

ドキュメントちゃんと嫁

●

素振り大事。実際に動かして挙動を押さえておく。
ホスト指定まとめ(2)
- ホストやロールについて
http://docs.fabfile.org/en/1.8/usage/execution.html#defining-host-lists

- ホスト指定の優先順位
http://docs.fabfile.org/en/1.8/usage/execution.html#order-of-precede
nce
Kauli でのプラクティス
Kauli でのプラクティス
●

指定している設定値

●

Capistrano の “on” や “with” の代替

●

戻り値の検査

●

複数のタスクを組み合わせて一度に実行
指定している設定値(1)
●

env 変数で指定

●

直感的でわかりやすい
env.colorize_errors = True
- エラーに色を付けて知らせる
env.warn_only = True
- エラーに警告出してスルー(デフォルトは即終了)
指定している設定値(2)
env.parallel = True
- multiprocessing モジュールによる並列実行
- @parallel デコレータによる指定が不要に
env.pool_size = 5
- 同時に実行させるプロセス数
- CPU の数と相談しましょう
指定している設定値(3)
env.disable_known_hosts = True
- ssh の known_hosts を無視する
- man in the middle attack に対して無防備になるので注意
- 多数のホストに対して実行する場合に速度的な問題が出た
場合は試すと良い
env.timeout = 3
- ssh の接続タイムアウト(秒)
- 子プロセスによる並列実行を前提にしているため
接続待ちのプロセスがたまると LA があがるため短めに。
戻り値の検査
●

デフォルトでは、実行したコマンドの戻り値が 0 で
あれば正常と見なし、それ以外ならエラー
それに従わないコマンドもそれなりに存在する

●

コマンドの戻り値が undoc だと調べるのがたるい
- git とか puppet とか
- ソース読む羽目になったり
Capistrano の “on” や “with” の代替
cap> with role1 uname -a
$ fab -R role1 cmd:'uname -a'
cap> on host1 uname -a
$ fab -H host1 cmd:'uname -a'
Capistrano の “on” や “with” の代替(2)
●

実装は簡単

●

コマンドラインからタスクには引数を渡せる
- fab -H host1 cmd:'uname -a'

●

引数の部分にカンマが含まれている場合は要エスケープ
- fab -H host1 cmd:'ls -d /path/{to,hoge}/'
複数のタスクを組み合わせて一度に実行(1)

●
●

●
●

ネストした関数で複数のタスクを実行
複数のホストを組み合わせたタスクを同時に実行
させたい場合に重宝
execute 関数を使う
ホスト指定と組み合わせると意図しない動作になり
がちなので注意
複数のタスクを組み合わせて一度に実行(2)

●

以下のようにホスト指定をするとデプロイが3回行われる
$ fab -H host1,host2,host3 deploy
複数のタスクを組み合わせて一度に実行(3)
●

Kauli では、この手のタスクでは -R と -H によるホ
スト指定を禁止している
これからの展開
これからの展開
●

モジュール化

●

新しいスタイルのタスク定義へ
モジュール化(1)

●

●

これまでは fabfile.py 1ファイルにタスクを書く前提で説明をしてきた
が、Fabric では Python 流にモジュールを区切ることが可能
fabfile.py からモジュールを import すればドット
区切りでタスクを呼び出せる
モジュール化(2)
●

いろいろなプロダクトのタスクを分割するのに
役立つ
$ fab some_product.deploy
$ fab infra.pull_some_file

… みたいな感じ

●

fabfile.py への一極集中を解消

●

新しいスタイルのタスク定義が必須
新しいスタイルのタスク定義(1)
●

既存の関数ベースのタスク定義に @task デコレー
タを付ける

●

または、Task クラスを継承してクラスを作る

●

現在新スタイルのタスクは未使用

●

これまで説明してきた古いスタイルのタスク定義と
は共存不可
- ひとつでも新しいスタイルのタスクがあると、古い
スタイルのタスクはリストから外れ、使えなくなる
新しいスタイルのタスク定義(2)
まとめ
●
●

●

Fabric は Python で簡単に書ける
ホストの指定方法が肝。これさえ把握すれば多分ど
うとでもなる
Kauli では特に凄いことをしてるわけではない
皆で良くしていくもの。 Patches welcome.

●

モジュール化の方向に持って行きたい

●

ドキュメントもよく読みましょう
- http://docs.fabfile.org/
ご清聴ありがとうございました。

More Related Content

Fabric Essentials