41
2日間Fabricを触った俺が 色々解説してみる @airtoxin

2日間Fabricを触った俺が 色々解説してみる

Embed Size (px)

Citation preview

Page 1: 2日間Fabricを触った俺が 色々解説してみる

2日間Fabricを触った俺が色々解説してみる

@airtoxin

Page 2: 2日間Fabricを触った俺が 色々解説してみる

Fabric?

Page 3: 2日間Fabricを触った俺が 色々解説してみる

About Fabric

Python(2.5-2.7)製のデプロイ・システムタスク実行ツール。

同様のツールにRuby製のCapistranoがある。

Page 4: 2日間Fabricを触った俺が 色々解説してみる

Install Fabric

Pythonとpipが入っているなら

$ (sudo) pip install Fabric

Page 5: 2日間Fabricを触った俺が 色々解説してみる

#!/usr/bin/env  python  #  -­‐*-­‐  coding:  utf-­‐8  -­‐*-­‐  

from  fabric.api  import  env,  local,  run  import  difflib  

env.hosts  =  [  ‘mydevelopment.jp'  ]  env.key_filename  =  [  '~/.ssh/mydevelopment.rsa'  ]  env.user  =  'airtoxin'  env.port  =  9724  

def  get_date():          remote_date  =  run(  'date'  )          local_date    =  local(  'date',  capture=True  )          for  line  in  difflib.ndiff(  [  remote_date  ],  [  local_date  ]  ):                  print  line

Example of Fabricfabfile.py

サーバー実行コマンドタスク名

ローカル実行コマンド

Pythonで実行結果を処理

Page 6: 2日間Fabricを触った俺が 色々解説してみる

Run Fabric

fabfile.pyのあるディレクトリで

$ fab get_date(タスク名)

Page 7: 2日間Fabricを触った俺が 色々解説してみる

タスクリスト

定義タスクの一覧確認は

$ fab --list

Page 8: 2日間Fabricを触った俺が 色々解説してみる

コマンド• リモートでコマンドを実行 → run(‘command’)

• ローカルでコマンドを実行 → local(‘command’)

• sudoでコマンドを実行 → sudo(‘command’)

• ディレクトリの移動 → with cd(‘dirname’):

• ファイルアップロード → put(‘localpath’, ‘remotepath’)

• ファイルダウンロード → get(‘remotepath’, ‘localpath’)

Page 9: 2日間Fabricを触った俺が 色々解説してみる

コマンド

大体なんとかなる。

というか

local, run, sudoがあるので実質何でもできる。

Page 10: 2日間Fabricを触った俺が 色々解説してみる

それって…

Page 11: 2日間Fabricを触った俺が 色々解説してみる

Shellでいいじゃん!!

Page 12: 2日間Fabricを触った俺が 色々解説してみる

正しい

Page 13: 2日間Fabricを触った俺が 色々解説してみる

Shell vs Fabric

Page 14: 2日間Fabricを触った俺が 色々解説してみる

Shell動作環境周りで考えることがほぼ無し。

サーバー操作の共通言語として多くのエンジニアが扱えることが期待出来る。

実際には可読性が低く、メンテナンス性が悪い。シェル芸の乱立。

属人化したサーバー保守・デプロイのコード。いざ修正しようとしても手がつけられない。

Page 15: 2日間Fabricを触った俺が 色々解説してみる

Fabric可読性の高いと言われるPythonで程よくラップしたコードが書ける。メンテナンス性の向上。

文字列、配列操作に長けているのでコマンドの返り値を処理するのが簡単。さらにPythonのライブラリも使える。

導入コストがほぼゼロ。

デコレーターとリスト内包表記さえ知れば問題なく使える学習コストの低さ。

Page 16: 2日間Fabricを触った俺が 色々解説してみる

Shell vs FabricShell Fabric

導入コスト-

プリインストール低~中程度

Pythonのpipによる

可読性 低い 謎文法, ワンライナー

高い Pythonのコード

文字列操作 難~普通程度 perl, awk等を利用

楽 ライブラリ等を利用

学習コスト 無し~高い 普段使い/初心者

低い~普通 リスト内包表記, decorator

情報量 多い 言わずもがな

中 ほぼ枯れている

Page 17: 2日間Fabricを触った俺が 色々解説してみる

Shell vs FabricShell Fabric

導入コスト - プリインストール

低~中程度 Pythonのpipによる

可読性 低い 謎文法, ワンライナー

高い Pythonのコード

文字列操作 難~普通程度 perl, awk等を利用

楽 ライブラリ等を利用

学習コスト 無し~高い 普段使い/初心者

低い~普通 リスト内包表記, decorator

情報量 多い 言わずもがな

中 ほぼ枯れている

Page 18: 2日間Fabricを触った俺が 色々解説してみる

後の事を考えるならFabric

Page 19: 2日間Fabricを触った俺が 色々解説してみる

Fabricサイコー

Page 20: 2日間Fabricを触った俺が 色々解説してみる

Shellでやってるの?

Page 21: 2日間Fabricを触った俺が 色々解説してみる

それって…

Page 22: 2日間Fabricを触った俺が 色々解説してみる

Fabricでいいじゃん!!

Page 23: 2日間Fabricを触った俺が 色々解説してみる

逆にね

Page 24: 2日間Fabricを触った俺が 色々解説してみる

実践Fabric1つのサーバーに対して特有の操作を行うことは少ない。

• 多数のサーバーに対して同じコマンドを実行

• 段階的,多段的なデプロイ

• ユーザーを変えたサーバー接続

など

Page 25: 2日間Fabricを触った俺が 色々解説してみる

実践Fabric

まずはfabfileの分割から

Page 26: 2日間Fabricを触った俺が 色々解説してみる

Example of Fabricfabfile.py

サーバー実行コマンドタスク名

ローカル実行コマンド

Pythonで実行結果を処理

#!/usr/bin/env  python  #  -­‐*-­‐  coding:  utf-­‐8  -­‐*-­‐  

from  fabric.api  import  env,  local,  run  import  difflib  

env.hosts  =  [  ‘mydevelopment.jp'  ]  env.key_filename  =  [  '~/.ssh/mydevelopment.rsa'  ]  env.user  =  'airtoxin'  env.port  =  9724  

def  get_date():          remote_date  =  run(  'date'  )          local_date    =  local(  'date',  capture=True  )          for  line  in  difflib.ndiff(  [  remote_date  ],  [  local_date  ]  ):                  print  line

Page 27: 2日間Fabricを触った俺が 色々解説してみる

fabfileの分割

fabfileをディレクトリ化しPythonのライブラリとして定義することが可能。

操作のまとまり毎にファイル分割して見通しをよくする。

Page 28: 2日間Fabricを触った俺が 色々解説してみる

fabfileディレクトリ内のファイルにタスクを定義。

__init__.pyで各ファイルをインポート

操作毎にファイルを分割。必要ならばサーバーへの接続情報のみを定義するタスクも書く。

fabfile構成

. ├── .gitignore └── fabfile ├── __init__.py ├── deploy.py ├── hosts.py ├── monitor.py └── test.py

Page 29: 2日間Fabricを触った俺が 色々解説してみる

ホストの設定のみ

hosts.py

. ├── .gitignore └── fabfile ├── __init__.py ├── deploy.py ├── hosts.py ├── monitor.py └── test.py

@taskdef staging():

env.hosts = ['mystaging.jp'

]

@taskdef production():

env.hosts = ['production.com','myhost.jp','myapp.jp'

]

Page 30: 2日間Fabricを触った俺が 色々解説してみる

実行タスク

. ├── .gitignore └── fabfile ├── __init__.py ├── deploy.py ├── hosts.py ├── monitor.py └── test.py

deploy.py

@task( default=True )def deploy():

with cd( '/path/to/myapp' ):run( 'git checkout .' )run( 'git pull' )run( 'npm install' )run( 'npm run compile' )run( 'forever restart app.js' )

@taskdef tagging():

hostname = local( 'hostname' )run( 'git tag {host}-

{datetime}'.format( host=hostname, datetime=now ) )

run( 'git push --tags' )

Page 31: 2日間Fabricを触った俺が 色々解説してみる

. ├── .gitignore └── fabfile ├── __init__.py ├── deploy.py ├── hosts.py ├── monitor.py └── test.py

__init__.py

#!/usr/bin/env python# -*- coding: utf-8 -*-

import hostsimport deployimport monitorimport test

Page 32: 2日間Fabricを触った俺が 色々解説してみる

Task List

fu:fabric_test$ fab -l Available commands:

deploy deploy.deploy deploy.tagging hosts.production hosts.staging monitor monitor.all monitor.disc_capacity monitor.load_average

@task( default=True )def deploy():

Page 33: 2日間Fabricを触った俺が 色々解説してみる

実行コマンド$ fab [task1] [task2] [task3]…

$ fab hosts.staging deploystagingサーバー群に対してdeployコマンドが実行される

hostを直接指定するなら$ fab -H myhost [tasks…]

Page 34: 2日間Fabricを触った俺が 色々解説してみる

Fabricの実行順Fabricはデフォルトでtaskを直列実行する。

host1,host2 と taskA,taskB がある時host1のtaskA

host2のtaskA

host1のtaskB

host2のtaskB と順次実行される

Page 35: 2日間Fabricを触った俺が 色々解説してみる

直列タスクfrom fabric.decorators import task, parallel

@taskdef deploy():

print env.host

fu:fabric_test$ fab hosts.production deploy [production.com] Executing task 'deploy' production.com [myhost.jp] Executing task 'deploy' myhost.jp [myapp.jp] Executing task 'deploy' myapp.jp

Done.

host毎に直列実行されている

Page 36: 2日間Fabricを触った俺が 色々解説してみる

並列タスクfrom fabric.decorators import task, parallel

@task@paralleldef deploy():

print env.host

fu:fabric_test$ fab hosts.production deploy [production.com] Executing task 'deploy' [myhost.jp] Executing task 'deploy' [myapp.jp] Executing task 'deploy' myapp.jp production.com myhost.jp

Done.

これだけ

並列実行されている

Page 37: 2日間Fabricを触った俺が 色々解説してみる

Fabricサイコー

Page 38: 2日間Fabricを触った俺が 色々解説してみる

fabfileの構成まとめ対象ホストが多数ある場合はホスト設定のみを行うタスクを作るのが便利。

[対象ホスト]と[実行コマンド]が分離できるので、[どこに] [何を]するのかが明確に区別できるようになる。

Page 39: 2日間Fabricを触った俺が 色々解説してみる

fabfileの構成まとめ@parallelした時に並列化されるのはタスク単位なので、実行のまとまりとしてタスクを定義する。

同時に実行されたらやばそうな所をまとめる感じでタスク定義を行えば良い。

Page 40: 2日間Fabricを触った俺が 色々解説してみる

Fabricまとめ

保守とか考えない・書捨てのワンライナーとかならShellでいい。

保守性を考えるならFabricを使おう。

Page 41: 2日間Fabricを触った俺が 色々解説してみる

おわり