カレンダー
    123
45678910
11121314151617
18192021222324
25262728293031
       
  12345
6789101112
13141516171819
20212223242526
27282930   
       
      1
2345678
9101112131415
16171819202122
23242526272829
3031     
    123
45678910
11121314151617
18192021222324
252627282930 
       
 123456
78910111213
14151617181920
21222324252627
28293031   
       
     12
3456789
10111213141516
17181920212223
24252627282930
31      
   1234
567891011
12131415161718
19202122232425
2627282930  
       
1234567
891011121314
15161718192021
22232425262728
293031    
       
     12
3456789
10111213141516
17181920212223
24252627282930
       
  12345
6789101112
13141516171819
20212223242526
2728293031  
       
  12345
6789101112
13141516171819
20212223242526
2728     
       
      1
2345678
9101112131415
16171819202122
23242526272829
3031     
   1234
567891011
12131415161718
19202122232425
262728293031 
       
 123456
78910111213
14151617181920
21222324252627
282930    
       
     12
3456789
10111213141516
17181920212223
24252627282930
31      

最新記事

2016.10.25

100台のサーバ情報を取得するには、Fabricが便利だった話(応用編)

crown
クラウドテックブログ ★もう一度読みたい良記事賞 12月 1位 受賞★

前回の復習

前回はFabricで情報収集するところまでを掲載しましたが、今回は収集データを加工/外部出力化する方法を説明します。

実装環境

  • Fabric サーバ
構築環境 OS ホスト名 IP
VirtualBox 5.0.14 CentOS 6.7 cent6-serv 192.168.56.101
  • クライアント
構築環境 OS ホスト名 IP
VirtualBox 5.0.14 CentOS 6.7 cent6-cri 192.168.56.102

実施すること

  • 取得データの csv 化及び外部ファイル化
    取得データの標準出力を外部ファイル化する方法を掲載します。
  • 取得データの定期取得/変更管理
    取得データを定期取得し変更管理する場合の方法を掲載します

収集データを外部ファイル化する場合

収集したデータについて、標準出力のみでは再利用しづらいので、外部出力することにしました。
また、そのさいに再利用しやすいように csvファイルにすることにしました。

以下が外部出力した際に工夫したポイントです。

  • データ加工について

    • データの加工は以下2種類の方法で可能の為、実施し易い方法もしくは複合的に
      • Fabricが対象サーバに実行するコマンド側で加工する(ワンライナーで記載できる方法であれば可能)
      • fabファイル自体がpythonのコードなので、取得データをpython側で加工する
  • 取得データの取り扱いについて

    • 取得データは標準出力として出力させる以外に変数として取り扱える
    • よって変数として取り扱い、加工/ファイル出力を行う
  • ファイル出力について

    • ファイル出力もpython側で出力させる事になる

上記を元に作成したコードは以下となります。

 from fabric.api import run, task
 from fabric.utils import abort

 import os
 import sys
 import tempfile

 def get_exception():
     return sys.exc_info()[1]

 @task
 def get_rpm():
     rpm_version = run("rpm -qa --queryformat='%{NAME},%{ARCH},%{VERSION}\n'")
     hostname = run("hostname")
     outputdir = '/home/test/output'
     temp = None
     try:
         temp = tempfile.mkstemp(dir=outputdir)
         f = os.fdopen(temp[0], "w")
         f.writelines(rpm_version)
         os.fchmod(temp[0], 0664)
         f.close()
     except Exception:
        e = get_exception()
        if isinstance(temp,list) and os.path.isfile(temp[1]):
        os.remove(temp[1])
        abort(str(e))
     finally:
        os.rename(temp[1], "%s/%s" % (outputdir,hostname))

上記コードの説明を以下に記載します。

  • from fabric.api import run, task
  • from fabric.utils import abort
    • `fabric.utils.abort’をimport
    • `fabric.utils.abort’は、エラー時に、実行をabortする為に利用
  • import os import sys import tempfile
    • python モジュールの import
    • os os依存の操作をする為のモジュール。ファイル操作に利用
    • sys エラー処理時のエラー出力の為に利用
    • tempfile temp ファイル生成の為に利用
  • def get_exception
    • エラー出力の為の Fabric タスク
    • エラー時に他 task から呼び出される形で実行される
  • @task,def get_rpm():
    • 情報収集用の Fabricタスクとして get_rpm 名として定義
  • os_version = run("rpm -qa --queryformat='%{NAME},%{ARCH},%{VERSION}\n'")
    • rpm -qa --queryformat='%{NAME},%{ARCH},%{VERSION}\n'をリモートサーバで実行し、実行結果を rpm_versionに格納
    • この様に、Fabricではリモートコマンド結果を変数に格納できる
    • よってリモートコマンド結果をローカル上で利用できるため、情報収集時のデータ加工が容易くできる
  • hostname = run("hostname")
    • hostnameコマンド結果を hostname 変数に格納
  • outputdir = '/home/test/output'
    • output ディレクトリの定義
  • temp = None
    • temp 関数のリセット
  • try:
    • outputdir配下にtempファイルとして、rpm_versionを出力する処理を実行
  • except Exception:
    • エラー判定部(詳細な説明は割愛)
    • エラー時には、tempファイルを削除し、処理をabort
  • finally:
    • tempファイルをhostnameファイルへリネーム

上記コマンドの実行結果は以下の通りです。
尚、今回は -h で指定するノードを複数ノードを指定して実行しています。

$ fab -H 192.168.56.101,192.168.56.102 -f /home/test/rpm.py get_rpm
[192.168.56.101] Executing task 'get_rpm'
[192.168.56.101] run: rpm -qa --queryformat='%{NAME},%{ARCH},%{VERSION}
'
[192.168.56.101] Login password for 'test': 
[192.168.56.101] out: libxml2,x86_64,2.7.6
[192.168.56.101] out: setup,noarch,2.8.14
(略)
[192.168.56.101] out: grub,x86_64,0.97
[192.168.56.101] out: 

[192.168.56.101] run: hostname
[192.168.56.101] out: cent6-stg-serv
[192.168.56.101] out: 

[192.168.56.102] Executing task 'get_rpm'
[192.168.56.102] run: rpm -qa --queryformat='%{NAME},%{ARCH},%{VERSION}
'
[192.168.56.102] out: libxml2,x86_64,2.7.6
(略)
[192.168.56.102] out: grub,x86_64,0.97
[192.168.56.102] out: 

[192.168.56.102] run: hostname
[192.168.56.102] out: cent6-stg-cli
[192.168.56.102] out: 


Done.
Disconnecting from 192.168.56.101... done.
Disconnecting from 192.168.56.102... done.
$ 

また、上記実行後、以下の様にファイルが生成されます。

$ pwd
/home/test/output
$ ls
cent6-cli cent6-serv
$ cat cent6-stg-cli
libxml2,x86_64,2.7.6
setup,noarch,2.8.14
glibc-headers,x86_64,2.12
(略)
$ cat cent6-stg-serv
libxml2,x86_64,2.7.6
setup,noarch,2.8.14
freetype,x86_64,2.3.11
$

上記の様にfabファイルは基本的にはpythonのプログラムなので、pythonでできる事は可能となるので、応用はしやすかったです。

収集データの定期取得/変更管理をする場合

さて、収集データを外部ファイル化することができましたが、必要都度取得するのも手間になりますので、取得データ自体を管理ファイルにしようと思いました。

上記の場合、定期取得及び取得情報変更時の変更管理が必要となりますが、Fabricだけでは実装ができませんので、私は以下の様に複数のツールを組み合わせて実装しました。

  • Fabric
    • 情報取得を担当
  • git
    • 変更管理を担当
  • cron
    • fabコマンドの定期実行を担当
    • 取得データのgit commit/puch を担当

上記構成を具体化したのが以下の図です。

ブログ素材_fab2回目.jpg

まとめ

上記よりFabricを一時的な情報収集以外にも使用することができました。
Fabricはデプロイツールとして有名ですが、応用利用が可能なツールであることが分かりましたので、今後も工夫して使っていきたいと感じました。

Y.Iさんのプロフィール

  • ペンネーム
    Y.I
  • 業務区分
    インフラエンジニア

  • プロフィール
    オンプレ運用エンジニアに携わってきたがクラウドエンジニアへ転向中。
    AWS認定ソリューションアーキテクトを83%で取得合格。