今回は・・・
前回につづいて、アプリケーションの導入と環境設定の自動化を考えます。
アプリケーションの設定に関しては、
(1) リファレンス環境を用意して、手動で設定・テストする。
(2) 設定内容をバージョン管理システムに登録する。
(3) 新規環境から、バージョン管理システムに登録された内容を取得して自動設定できるようにする。
という流れを考えてみます。まずは試しに、PostgreSQLの設定をGithubに登録してみましょう。
PostgreSQLとGithubという選択に深い意味はありません。特にGithubは、そもそもアプリケーションの設定管理のためのツールではないので、やってみたらいろいろ不便な点も見えてくるはずです。逆にそこから、アプリケーション設定のバージョン管理に必要な要素を考えられたらいいかも・・・という意図です。
リファレンス環境の用意とgithub登録
はじめに、前回のツール(virt-construct.py)と設定(vm01.conf)を利用して、仮想マシンvm01を用意します。vm01にログインしたら、普通にPostgreSQLをインストールして、DBの初期化とpostgresのパスワード設定まで行います。
[root@vm01 ~]# yum -y install postgresql-server [root@vm01 ~]# service postgresql initdb [root@vm01 ~]# service postgresql start [root@vm01 ~]# su - postgres -c "psql -c \"ALTER USER postgres encrypted password 'pas4pgsql'\"" [root@vm01 ~]# service postgresql stop
続いて、設定ファイル「postgresql.conf」「pg_hba.conf」を編集しますが、その前に、これらのファイルをローカルのgitでバージョン管理できるようにします。
[root@vm01 ~]# cd /var/lib/pgsql [root@vm01 pgsql]# git init [root@vm01 pgsql]# git add data/postgresql.conf [root@vm01 pgsql]# git add data/pg_hba.conf [root@vm01 pgsql]# git commit -m "initial status"
ここで、おもむろに「postgresql.conf」「pg_hba.conf」を任意に編集して、納得のいく設定ができたらgitにcommitして、タグ(devlopment_1.0)を振っておきます。
[root@vm01 pgsql]# git commit -a -m "log and security settings for development environment" [root@vm01 pgsql]# git tag development_1.0
ちなみにここでは、ログ出力設定とパスワード認証設定を行いました。
[root@vm01 pgsql]# git show commit 62e22ce98d9354bfa42444416b8a72747de85136 Author: root <root@vm01.(none)> Date: Thu Aug 23 13:51:31 2012 +0900 log and security settings for development environment diff --git a/data/pg_hba.conf b/data/pg_hba.conf index fb080ea..014eb16 100644 --- a/data/pg_hba.conf +++ b/data/pg_hba.conf @@ -67,8 +67,8 @@ # TYPE DATABASE USER CIDR-ADDRESS METHOD # "local" is for Unix domain socket connections only -local all all ident +local all all md5 # IPv4 local connections: -host all all 127.0.0.1/32 ident +host all all 127.0.0.1/32 md5 # IPv6 local connections: -host all all ::1/128 ident +host all all ::1/128 md5 diff --git a/data/postgresql.conf b/data/postgresql.conf index 8c99f80..cd64a2c 100644 --- a/data/postgresql.conf +++ b/data/postgresql.conf @@ -499,3 +499,12 @@ default_text_search_config = 'pg_catalog.simple' #------------------------------------------------------------------------------ #custom_variable_classes = '' # list of custom variable class names + +log_destination = 'syslog' +syslog_facility = 'LOCAL0' +syslog_ident = 'postgres' +log_line_prefix = '%u %d ' +log_connections = on +log_disconnections = on +log_statement = 'all' +
最後にこれらをgithubにpushしておきます。ここでは、githubに新規のリポジトリ「https://github.com/enakai00/pgsql_configs.git」を作成してあるものとします。(pushするためのSSH鍵の設定などは、githubの入門ページなどよしなに参照してください。)
[root@vm01 pgsql]# git remote add origin git@github.com:enakai00/pgsql_configs.git [root@vm01 pgsql]# git push -u origin master [root@vm01 pgsql]# git push --tags
リファレンス環境の再現スクリプト
新規にRHELをインストールした環境に対して、PostgreSQLをインストールして、githubにあげた設定を自動適用するスクリプトを用意します。さっくりとこんな感じで。
pgsql_deploy.sh
#!/bin/sh -x GitRepository=$1 # Repository URL ConfigTag=$2 # Restore Tag RepoName=${GitRepository##*/} RepoName=${RepoName%\.git} # restore configs to /tmp/gittmp/$RepoName function git_restore { rm -rf /tmp/gittmp mkdir -p /tmp/gittmp cd /tmp/gittmp git clone $GitRepository cd $RepoName if [[ ! -z $ConfigTag ]]; then git checkout $ConfigTag fi } yum -y install postgresql-server service postgresql initdb service postgresql start su - postgres -c \ "psql -c \"ALTER USER postgres encrypted password 'pas4pgsql'\"" service postgresql stop git_restore cp -rv /tmp/gittmp/$RepoName/* /var/lib/pgsql/ restorecon -r /var/lib/pgsql chkconfig postgresql on
使い方は、次のようにリポジトリのURLと適用したいタグを指定します。
./deploy_psql.sh https://github.com/enakai00/pgsql_configs.git development_1.0
そして、このスクリプトをKVMホストの/var/www/html/scripts/以下に保存して、「http://
アプリケーション環境の自動再現
これまでに用意した道具を使って、アプリケーション環境の自動再現を行なってみましょう。次の設定ファイルからvirt-construct.pyを実行して、新たな仮想マシンvm02を自動構築します。
vm02.conf
[variables] # # Generic variables referenced as ${variable} # vmname=vm02 hostname=vm02 diskpath=/var/lib/libvirt/images/vm02.img ip=192.168.122.198 vcpus=2 ram=1024 disksize=8 network=network:default os-variant=rhel6 url=http://binaries.nrt.redhat.com/contents/RHEL/6/3/x86_64/default/ netmask=255.255.255.0 gateway=192.168.122.1 nameserver=192.168.122.1 # PostgreSQL deployment data pgsql_deployscript=http://192.168.122.1/scripts/deploy_pgsql.sh pgsql_gitrepo=https://github.com/enakai00/pgsql_configs.git pgsql_gittag=development_1.0 [virt-install] # # virt-install options except ks.cfg # --noautoconsole --noreboot is automatically added # --name ${vmname} --vcpus ${vcpus} --ram ${ram} --disk path=${diskpath},size=${disksize},sparse=false --network ${network} --os-variant ${os-variant} --location ${url} [kickstart] # # ks.cfg contents # url --url=${url} lang ja_JP.UTF-8 keyboard jp106 network --onboot yes --device eth0 --bootproto static --ip ${ip} --netmask ${netmask} --gateway ${gateway} --nameserver ${nameserver} --hostname ${hostname} rootpw passw0rd timezone --isUtc Asia/Tokyo bootloader --location=mbr zerombr clearpart --initlabel --drives=vda part /boot --fstype=ext4 --size=500 part swap --size=1024 part / --fstype=ext4 --grow --size=200 reboot %packages @base @core @japanese-support git # mandatory to use configserver %end %post --log=/root/anaconda-post.log set -x cat <<EOF > /etc/yum.repos.d/base.repo \[baseos] name="Repository for base OS" baseurl=${url} gpgcheck=0 enabled=1 EOF # PostgreSQL deployment curl ${pgsql_deployscript} -o /tmp/tmp$$ . /tmp/tmp$$ ${pgsql_gitrepo} ${pgsql_gittag} rm /tmp/tmp$$ %end
この設定ファイルでは、ks.cfgの%postセクションの最後で、先に作成したdeploy_pgsql.shをダウンロードして実行しています。これにより、RHELのインストールと同時にPostgreSQLのインストールと環境設定まで行われることになります。
$ sudo ./virt-construct.py -c vm02.conf
インストール完了後にvm02にログインして、%postの実行ログを見るとこんな感じ。
[root@vm02 ~]# cat anaconda-post.log + cat + curl http://192.168.122.1/scripts/deploy_pgsql.sh -o /tmp/tmp10124 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 101 709 101 709 0 0 55941 0 --:--:-- --:--:-- --:--:-- 692k + . /tmp/tmp10124 https://github.com/enakai00/pgsql_configs.git development_1.0 ++ GitRepository=https://github.com/enakai00/pgsql_configs.git ++ ConfigTag=development_1.0 ++ RepoName=pgsql_configs.git ++ RepoName=pgsql_configs ++ yum -y install postgresql-server Loaded plugins: product-id, security, subscription-manager (中略) Installed products updated. Verifying : postgresql-libs-8.4.11-1.el6_2.x86_64 1/3 Verifying : postgresql-server-8.4.11-1.el6_2.x86_64 2/3 Verifying : postgresql-8.4.11-1.el6_2.x86_64 3/3 Installed: postgresql-server.x86_64 0:8.4.11-1.el6_2 Dependency Installed: postgresql.x86_64 0:8.4.11-1.el6_2 postgresql-libs.x86_64 0:8.4.11-1.el6_2 Complete! ++ service postgresql initdb Initializing database: [ OK ] ++ service postgresql start Starting postgresql service: [ OK ] ++ su - postgres -c 'psql -c "ALTER USER postgres encrypted password '\''pas4pgsql'\''"' ALTER ROLE ++ service postgresql stop Stopping postgresql service: [ OK ] ++ git_restore ++ rm -rf /tmp/gittmp ++ mkdir -p /tmp/gittmp ++ cd /tmp/gittmp ++ git clone https://github.com/enakai00/pgsql_configs.git Initialized empty Git repository in /tmp/gittmp/pgsql_configs/.git/ ++ cd pgsql_configs ++ [[ ! -z development_1.0 ]] ++ git checkout development_1.0 Note: checking out 'development_1.0'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b new_branch_name HEAD is now at 62e22ce... log and security settings for development environment ++ cp -rv /tmp/gittmp/pgsql_configs/data /var/lib/pgsql/ `/tmp/gittmp/pgsql_configs/data/postgresql.conf' -> `/var/lib/pgsql/data/postgresql.conf' `/tmp/gittmp/pgsql_configs/data/pg_hba.conf' -> `/var/lib/pgsql/data/pg_hba.conf' ++ restorecon -r /var/lib/pgsql ++ chkconfig postgresql on + rm /tmp/tmp10124 [root@vm02 ~]# tail /var/lib/pgsql/data/postgresql.conf /var/lib/pgsql/data/pg_hba.conf ==> /var/lib/pgsql/data/postgresql.conf <== #custom_variable_classes = '' # list of custom variable class names log_destination = 'syslog' syslog_facility = 'LOCAL0' syslog_ident = 'postgres' log_line_prefix = '%u %d ' log_connections = on log_disconnections = on log_statement = 'all' ==> /var/lib/pgsql/data/pg_hba.conf <== # TYPE DATABASE USER CIDR-ADDRESS METHOD # "local" is for Unix domain socket connections only local all all md5 # IPv4 local connections: host all all 127.0.0.1/32 md5 # IPv6 local connections: host all all ::1/128 md5
vm01からgithubにpushしておいた設定が再現されていることが分かります。
考察
この手法の便利なところは、vm01でさまざまな設定変更を行った場合でも、変更後の状態をgithubにpushしてタグを振っておけば、vm02.confの変数指定(pgsql_gittag=development_1.0)で任意のタグの状態を再現できるところです。PostgreSQLを使った開発中アプリケーションのテストを行う際に、任意の設定のPostgreSQL環境をすぐに再現して、きれいな状態でテストを実行できます。また、ご存知の通りgitは分散バージョン管理システムですので、(多少のgitの知識があれば)vm02で設定変更を行なって、それをgithubにpushすることも可能です。
一方、改善点としては、deploy_pgsql.sh自体に環境再現のロジックが埋め込まれていて、このシェルそのもののメンテナンスを誤ると、正しく環境が再現できなくなる恐れがあります。また、gitでは、ファイルのオーナ情報やハードリンク情報は保存できない点にも注意が必要です。この例では、コピー先のファイルのオーナ情報を保存する形でコピーすることで対応していますが、すべての場合にこれでうまくいくわけではありません。結局のところ、deploy_pgsql.shに人依存の「職人技」が残ってしまう可能性があるということでしょうか。。。
根本の問題は、使用するアプリケーションごとに、deploy_hogehoge.shを作りこまないといけない点。本来は、アプリケーションの提供者がアプリケーション標準のツールとして、このような道具を用意することですが、なかなか標準化は難しそうです。
この後は、普段から使用しているアプリケーション環境にこの手法を適用して、しばし、メリット/デメリットをみてみることにします。