AmazonLinuxでSRPM落とす方法

会社で使ってるSubversionで下記のバグと同じ現象が発生した。

http://svn.apache.org/viewvc?view=revision&revision=1528718

現時点でAmazonLinuxのhttpdは2.2.25の最新リリースで、上のFixはまだ取り込まれていないので
SRPMを落としてPatchファイル作成してSpecファイル修正してオレオレrpmでアップデートした。

$ sudo get_reference_source -d -p httpd
$ sudo rpm -ihv /usr/src/srpm/debug/httpd-2.2.25-1.0.amzn1.src.rpm

あとはいつもの手順でPatchファイルを用意してSpecファイルを修正して終了です。
なんとAmazonLinuxのhttpdパッケージの当ててあるパッチ数が103個もありました。
追加で3個当てたので合計106個に。。。

そろそろSubversion管理やめたいというのものありますが、
できれば次のリリースにはこのFixは是非取り入れて欲しいですね!

muninでpostgres_tuplesの値取得ができなくて困ってた

しばらくなんで取得できなくて分からなくて困ってたけど、解決できた。
ただのミスコンフィグだった。

/etc/munin/plugin-conf.d/postgresに書いてた1行が原因だった。

env.PGDATABASE postgres

上記1行があるとデータベースpostgresの値を取得してしまうので常に値が0になってしまう。

正しく設定をしていないと シェルから/etc/munin/plugins/postgres_tuples_dbname
を実行した場合、下記のように値は取得できるけど

$ ./postgres_tuples_dbname
seqread.value 410785240167
idxfetch.value 49647137689
inserted.value 41229074
updated.value 19990804
deleted.value 10921116
hotupdated.value 17592857

下記の場合ではenv.PGDATABASE postgresに上書きされてしまい常に0になるんですね。

$ telnet 0 4949
Trying 0.0.0.0...
Connected to 0 (0.0.0.0).
Escape character is '^]'.
# munin node at localhost.localdomain
fetch postgres_tuples_dbname
seqread.value 0
idxfetch.value 0
inserted.value 0
updated.value 0
deleted.value 0
hotupdated.value 0
.
quit

muninでpostgreSQL値取得する場合、というより個別のデータベース指定で値取得する場合

env.PGDATABASE postgres

をはずしておきましょう。

Jenkins使ってデプロイしてみた

今のところに転職してまずデプロイを手動で行なっていることに驚いた。

環境はこんな感じ。

  • 使用言語はjava
  • scmはsubversion
  • インフラ環境はAWS
  • サービスはSass型のECサービス。

手順として概要はこんな感じ。

  • デプロイ担当の人のノートPCでEclipseでビルドする。
  • ビルドしたclassとかjsp等を拡張子指定してexportする。
  • exportしたものをbatでごにょごにょする。
  • ごにょごにょしたものをzipで圧縮する。
  • zipファイルをインスタンスにscpする。
  • ELBを手動で切り離す。
  • zipファイルを展開してtomcat再起動する。
  • ELBを手動で戻す。

当然かなりのオペミスが発生していて問題になっていた。
そこでJenkinsを使ってデプロイの仕組みを作ってみた。

javaの経験がまるでないのでよくわからないけど、
javaではwarファイルにまとめてデプロイするのが普通ぽい。

ただサービスの特性もあって現状の構成ではwarファイルにしての
デプロイが厳しいと感じたので手慣れているrpmにしてしまった。

簡単にJenkinsを導入する手順を自分用にまとめておく。

  • CI専用インスタンスを作成してJenkinsインストール。
  • Jenkinsでsvn upしてビルドするジョブを作成する。
  • rpmを作成するためのspecファイルをCIインスタンスで作成する。
  • Jenkinsでビルドしたclass等をspecファイルでrpmbuildするジョブを作成する。
  • CIインスタンスapacheを入れてデプロイに使うyumレポジトリを作成する。
  • 作成したレポジトリを参照するrepoファイルをデプロイしたいサーバに配置する。
  • CIインスタンスCapistranoをインストールする。
  • Capistranoでデプロイ用のタスクを作成する。
  • JenkinsでCapistranoを実行させるデプロイするジョブを作成する。

これだけなんだけど、本番環境で実稼動させるまでには結構時間かかった。

プロジェクト開始と同時にCIサーバ導入してゼロデプロイできるように
しないと運用入ってからCIサーバ入れるのは大変でした。

必ずプロジェクト開始と同時にCIサーバ入れる事をオススメします。
継続的デリバリなかなか読み終われない。。。

継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化

ec2でocfs2+iscsiクラスタを組んでみた

ここ最近、GlusterFSを使う規模でもないけどサービスとストレージの冗長化を実現したいという
要望のもと、ec2上でiscsi+gfs2またはocfs2で稼動できるか調べていました。

色々やってみたけどgfs2はcman(Cluster Manager)がマルチキャストを使うのでec2では難しいし、
ocfs2はドキュメントみる限りマルチキャスト使わないぽいから実現可能かもしれないけど、
使用できるLinux Kernelが限定されるので見送ろうかと思っていました。

まあめんどくさいけどCentOS5.8(x86_64)のAMIを自作してなんとか稼動できたのでメモ。
障害時のテストとか同時書き込みの動作の書き込みのテストとかはこれからやる予定。

Management Consoleから普通に立ち上げます。t.microで十分です。

  • 8GBのEBSボリュームを作成してアタッチする

Management Cosoleから作成します。
/dev/sdfで立ち上げたインスタンスにアタッチします。

# mkfs.ext3 /dev/xvdf
# mkdir /ebs-root
# mount /dev/xvdf /ebs-root
  • CentOS 5.8をインストール
# cat <<EOF > centos.repo
[main]
cachedir=/var/cache/yum
debuglevel=2
logfile=/var/log/yum.log
exclude=*-debuginfo
gpgcheck=0
obsoletes=1
reposdir=/dev/null

[base]
name=CentOS-5.8 - Base
mirrorlist=http://mirrorlist.centos.org/?release=5.8&arch=x86_64&repo=os
enabled=1

[updates]
name=CentOS-$releasever - Updates
mirrorlist=http://mirrorlist.centos.org/?release=5.8&arch=x86_64&repo=updates
enabled=1
EOF
# yum -c centos5.repo --disablerepo=* --enablerepo=base --enablerepo=updates --installroot=/ebs-root -y groupinstall core
  • fstabを用意
# cat <<EOF > /ebs-root/etc/fstab
/dev/sda1  /         ext3    defaults        1 1
proc       /proc     proc    defaults        0 0
sysfs      /sys      sysfs   defaults        0 0
devpts     /dev/pts  devpts  gid=5,mode=620  0 0
tmpfs      /dev/shm  tmpfs   defaults        0 0
/dev/sda2  /mnt      ext3    defaults        0 0
/dev/sda3  swap      swap    defaults        0 0
EOF
  • modprobe.confを用意
# cat <<EOF > /ebs-root/etc/modprobe.conf
alias eth0 xennet
alias scsi_hostadapter xenblk
EOF
  • kernelをインストール

ここが一番大事でocfs2でサポートしてるカーネルと合わせないといけない。
見たところ最新のCentOS5.8カーネルのocfs2のパッケージがあるのでそのままインストール。

# yum -c centos5.repo --disablerepo=* --enablerepo=base --enablerepo=updates --installroot=/ebs-root -y install kernel-xen
  • system-auth-acを用意
# cat <<EOF > /ebs-root/etc/pam.d/system-auth-ac
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 500 quiet
auth        required      pam_deny.so
 
account     required      pam_unix.so
account     sufficient    pam_succeed_if.so uid < 500 quiet
account     required      pam_permit.so
 
password    requisite     pam_cracklib.so try_first_pass retry=3
password    sufficient    pam_unix.so md5 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so
 
session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
EOF
# cd /ebs-root/etc/pam.d
# rm system-auth
# ln -s sytem-auth-ac system-auth
  • PVGRUBの設定
# cat <<EOF > /ebs-root/boot/grub/menu.lst
default=0
timeout=0
hiddenmenu
title CentOS 5.8
    root (hd0)
    kernel /boot/vmlinuz-2.6.18-308.20.1.el5xen ro root=/dev/sda1 4
    initrd /boot/initrd-2.6.18-308.20.1.el5xen.img
EOF
  • 公開鍵の設定

sandbox4me.orgさんのところのgetsshkeyをそのまま拝借しています。

# cd /ebs-root/etc/rc4.d
# ln -s ../init.d/getsshkey S11getsshkey
# yum -c centos5.repo --disablerepo=* --enablerepo=base --enablerepo=updates --installroot=/ebs-root -y install curl
  • ネットワークの設定
# cat <<EOF > /ebs-root/etc/sysconfig/network
NETWORKING=yes
EOF
# cat <<EOF > /ebs-root/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=dhcp
ONBOOT=yes
EOF
  • その他の設定
# sed -i 's/SELINUX\=disabled/SELINUX\=permissive/g' /ebs-root/etc/selinux/config
# sed -i 's/SELINUX\=disabled/SELINUX\=enforcing/g' /ebs-root/etc/selinux/config
# cat <<EOF > /ebs-root/etc/sysconfig/i18n
LANG=ja_JP.UTF-8
EOF
# cp /ebs-root/usr/share/zoneinfo/Asia/Tokyo /ebs-root/etc/localtime

あとはEBSをアンマウントしてスナップショットを取得してAMIを作成するだけです。
UserProvidedなカーネルを使用できるようにKernel IDをaki-d409a2d5にしてAMIを作成します。

# ec2-describe-images -o amazon --filter "image-type=kernel"

で使用可能なアーキテクチャごとのKernel IDが調べられます。

ここまでできたら作成したAMIをベースにocfs2+iscsi構成ができると思います。
クラスタ構成の続きは後ほどメモします。

  • 追記

rpmデータベースが更新できていないので更新する作業が必要でした。
イメージを作成しているAmazon Linuxで実行します。

# yum install db43
# for i in `ls`; do db_dump $i | db43_load $i.db43; mv -f $i.db43 $i; done

munin で rrdファイルを指定のpermission/ownerで出力させる

umaskを思い出したのでメモ。
これでnode追加するたびに作業がなくなる。

/opt/munin/bin/munin-cron (3行目当たりに)

# for rrdcached group
umask 002

muninアカウントのプライマリグループ変更

$ id munin
uid=497(munin) gid=496(munin) groups=496(munin),498(rrdcached)
$ sudo usermod -g rrdcached munin
$ sudo usermod -G munin munin
$ id munin
uid=497(munin) gid=498(rrdcached) groups=498(rrdcached),496(munin)

crond 再起動

$ sudo /etc/init.d/crond restart

rrdcached と munin 続き

デフォルトのmunin.confだとパフォーマンスがかなり悪いのでいくつか設定を追加してみた。
結果から言うとfastcgi+graph/htmlの動的生成とrrdcachedの導入で相当の数のrrdオブジェクトを扱う事が可能になると思う。
デメリットとしてはgraph/html生成時に少し待ち時間が増える事と、rrdcachedがメモリを結構使うのでswapしないように注意。
早く2.0.xのrpm配布されないかな。

  • htmlファイルもgraph同様にcgiで動的に生成

/etc/opt/munin/munin.conf

html_strategy cgi

/etc/httpd/conf.d/munin.conf

<VirtualHost *:80>
    ServerName munin.example.org
    DocumentRoot /opt/munin/www/docs
    Alias /static /opt/munin/www/docs/static
    ScriptAlias /cgi-bin/ /opt/munin/www/cgi/

    # Rewrites
    RewriteEngine On

    # HTML
    RewriteCond %{REQUEST_URI} !^/static
    RewriteCond %{REQUEST_URI} .html$ [or]
    RewriteCond %{REQUEST_URI} =/
    RewriteRule ^/(.*)          /opt/munin/www/cgi/munin-cgi-html/$1 [L]

    # Ensure we can run (fast)cgi scripts
    <Directory "/opt/munin/www/cgi/">
    Options +ExecCGI
    <IfModule mod_fcgid.c>
        SetHandler fcgid-script
    </IfModule>
    <IfModule !mod_fcgid.c>
        SetHandler cgi-script
    </IfModule>
    </Directory>

</VirtualHost>

apache graceful restart

$ sudo service httpd graceful
  • rrdcachedの導入(epelのrrdtool-1.4.7に既に含まれてるのインストール作業はなし。)

/etc/opt/munin.conf

rrdcached_socket /var/rrdtool/rrdcached/rrdcached.sock

/etc/sysconfig/rrdcached (障害対策でデータを守りたい場合は -j オプションあったほうがいい)
オプションの順番に注意。-s と -m は一番最初にしないとオプション通りに起動しない罠。

OPTIONS="-s rrdcached -m 664 -l unix:/var/rrdtool/rrdcached/rrdcached.sock -l 127.0.0.1 -b /var/opt/munin -w 3600 -z 3600 -f 86400"

munin/apacheアカウントをrrdcached グループに入れる

$ sudo usermod -G rrdcached munin
$ sudo usermod -G rrdcached apache

rrdファイルがmuninアカウントで作成されるためpermissionとownerを変更する
環境によってはrrdファイルの存在するディレクトリのパーミッションも直さないいけないかも(追記修正)

#!/bin/sh

FILE_NUM=`find /var/opt/munin -name "*.rrd" -type f -user munin -group munin -perm 644|wc -l`
if [ $FILE_NUM -eq 0 ];then
  exit 1
fi

for i in `find /var/opt/munin -name "*.rrd" -type f -user munin -group munin -perm 644`; do
  sudo chmod 664 $i
  sudo chown :rrdcached $i
done
exit 0

rrdcached 起動

$ sudo chkconfig rrdcached on
$ sudo service rrdcached start

rrdcached のstatsが確認できる

$ telnet 127.0.0.1 42217
Trying 127.0.0.1...
Connected to localhost (127.0.0.1).
Escape character is '^]'.
STATS
9 Statistics follow
QueueLength: 0
UpdatesReceived: 3024
FlushesReceived: 108
UpdatesWritten: 54
DataSetsWritten: 756
TreeNodesNumber: 216
TreeDepth: 9
JournalBytes: 0
JournalRotate: 0
quit
Connection closed by foreign host.

手動でrrdcached のcacheをフラッシュする

$ telnet 127.0.0.1 42217
Trying 127.0.0.1...
Connected to localhost (127.0.0.1).
Escape character is '^]'.
FLUSHALL
0 Started flush.

参考

rrdcached と munin

munin 2.0.1 で実稼動500ぐらいのnodeの値を取得してみたところ、1.4.7よりパフォーマンスがでない。
I/O負荷が逆に増えてしまったぐらいで、なんとかならないかとrrdcached の設定を追加してみたが、
今チェックしたらmunin 2.0.2がでてたのでまたやり直そう。。。