読者です 読者をやめる 読者になる 読者になる

Funcを試してみた

Fedora Python

FuncはPythonで書かれたシステム管理フレームワーク。管理対象サーバに対して、Pythonで記述したスクリプトを一斉に実行することができる。

Func(Fedora Unified Network Controller)
https://fedorahosted.org/func/

Funcはgihyo.jpの記事で知った。非常に丁寧に書かれた記事で、これだけでFuncの概要や基本的な使い方を知るには十分なんだけれども、バージョンアップで変わってしまった点や個人的にちょっと躓いた点があったのでメモを残しておく。

モジュール構成

Funcで管理する/管理されるサーバ群はマスターとクライアントに分けられる。マスターがcertmaster、クライアントがfunc。各クライアントのことはminimonと呼ぶ。ゆえに設定ファイルは/etc/func/minimon.conf。

certmasterとfuncはそれぞれ独立した名前空間をもつPythonモジュール。しかし、funcがcertmasterに依存しているので、クライアントにはfuncだけ、マスターにはcertmasterだけ、といったインストールの仕方はできない。certmasterとfuncの間はXMLRPC over HTTPSで通信する。そのため、pyOpenSSLも必要。

いずれにせよ、yumでインストールすれば必要なモジュールは同時にインストールされるはず。

インストール

Fedora Core 7以降ならば簡単。

$ sudo yum install func

Fedora Core 6やCentOS 5.0のようにPython2.4の環境ではsrc.rpmから入れる。funcとcertmasterの最新版は以下のURLで公開されている。

certmasterのインストール。

$ curl -O http://people.fedoraproject.org/~mdehaan/files/certmaster/certmaster-0.19-1.fc8.src.rpm
$ sudo rpmbuild --rebuild certmaster-0.19-1.fc8.src.rpm

funcのインストール。

$ curl -O http://people.fedoraproject.org/~mdehaan/files/func/func-0.18-1.fc8.src.rpm
$ sudo rpmbuild --rebuild func-0.18-1.fc8.src.rpm

初期設定

マスター側ではPort 51235、クライアント側ではPort 51234を開放することが必要。ここには「将来のリリースにならないとポートは変えられない」と書いてあるが、minion.conf, certmaster.confのlisten_portでポート番号は変えられるようなことがFuncのwikiに書いてあったような気がする。後で調べる。

まず、マスター側でcertmasterを起動。

$ sudo /sbin/service certmaster start

クライアント(minion)側で/etc/certmaster/minion.confにマスターのホスト名を設定する。上記のgihyo.jpの記事等、バージョン0.18以前の解説記事には「/etc/func/minion.confに設定する」と書いてあるので注意が必要。オフィシャルな解説はこれ

$ cat /etc/certmaster/minion.conf
# configuration for minions
 
[main]
certmaster = certmaster.perezvon.net
log_level = DEBUG
cert_dir = /etc/pki/certmaster

minion.confを設定したならば、クライアント側のデーモン(funcd)を起動。

$ sudo /sbin/service funcd start

再度マスター側に戻って、マスター側で証明書リクエストに対して署名を行う。

$ sudo certmaster-ca --list
client.perezvon.net
$ sudo certmaster-ca --sign client.perezvon.net

基本的な使い方

以下のコマンドで、すべてのクライアントに対して、利用可能なモジュールを問い合わせる。

$ sudo func "*" call system list_modules
on https://client.perezvon.net:51234 running system list_modules ()
 ['command', 'copyfile', 'filetracker', 'func_module', 'hardware', 'jobs', 'mount', 'nagios-check', 'netapp.options', 'netapp.snap', 'netapp.vol', 'netapp.vol.clone', 'networktest', 'process', 'reboot', 'rpms', 'service', 'smart', 'snmp', 'sysctl', 'test', 'yumcmd']

例えば、/sbin/serviceを使ってサービスを再起動するならば、

$ sudo func "*" call service restart httpd
on https://client.perezvon.net:51234 running service restart (httpd)
0

特定のホストに対してだけコマンドを実行するならば、第一引数にホスト名を指定する。

$ sudo func client.perezvon.net call service restart httpd

組み込みモジュールはいくつかあるが、例えば、commandを使うとsshと同じように任意のコマンドを実行できる。

$ sudo func client.perezvon.net call command run "/bin/date"
on https://client.perezvon.net:51234 running command run (/bin/date)
[0, 'Fri Mar 28 07:19:04 JST 2008\n', '']

組み込みモジュールの一覧は以下のURLにまとまっている。ただし、開発中のものも混ざっているみたいだし、「後で書く」的なドキュメントも多い。

https://fedorahosted.org/func/wiki/ModulesList

PythonモジュールとしてのFunc

コマンドラインからちょっと触ってみると、結果の出力やエラー出力が非常に不親切なことが多い。もちろん、開発途上だからという理由もあるんだろうけど、FuncはPythonスクリプトの中で使うことを想定したライブラリ・フレームワークだからという点も大きいと思う。

$ func client.perezvon.net call process info "aux"

と実行するとクライアント側のプロセス一覧が得られるが、出力結果があからさまにPythonのリストをダンプしたものなので、非常に見にくい。Funcは自分で管理スクリプトを書かないと便利さがあまり分からないだろう。

組み込みモジュールを使った場合は、次のような感じでかける。example.orgexample.comのクライアント群に対してyum updateを実行するスクリプト。

import func.overlord.client as fc
client = fc.Client("*.example.org;*.example.com")
client.yum.update()

まだ全然試していないが、自分でもモジュールを書けるようなので、使い方によっては非常に役に立ちそう。処理の一括実行だけならば、Capistranoでもできそうだし、管理するサーバ数が増えればPuppetでやるのが普通だろうけど、Pythonで書けるのはやはりメリットだな。