Murakumo 0.4.5をリリースしました。
https://rubygems.org/gems/murakumo/versions/0.4.5
今回はKeepalived/Heartbeatのような冗長化機能を追加しました。
server-01
[root@server-01 ~]# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
169.254.169.254 * 255.255.255.255 UH 0 0 0 eth0
10.0.0.0 * 255.255.255.0 U 0 0 0 eth0
10.0.0.0 * 255.255.255.0 U 0 0 0 eth1
default 10.0.0.232 0.0.0.0 UG 0 0 0 eth0
server-02
※169.254.169.254を設定しておかないとメタ情報がとれなくてはまります
[root@server-02 ~]# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
169.254.169.254 * 255.255.255.255 UH 0 0 0 eth0
10.0.0.0 * 255.255.255.0 U 0 0 0 eth0
default 10.0.0.232 0.0.0.0 UG 0 0 0 eth0
MurakumoとMySQLをインストールします。
/etc/murakumo.yml
--- address: 0.0.0.0 port: 53 auth-key: onion log-level: debug resolver: 10.0.0.2, 8.8.8.8 max-ip-num: 8 domain: ap-northeast-1.compute.internal init-script: /etc/murakumo-init.rb addr-includes: ^10\..* notification: host: 127.0.0.1 sender: sender@mail.from recipients: - recipient@mail.from # alias hostname, ttl, master/secondary/backup, weight alias: - mysql-server,60,master,100 health-check: mysql-server: interval: 5 timeout: 5 healthy: 2 unhealthy: 2 script: | mysql_check 'root' # hook of activation of backup/secondary activity-check: mysql-server: start-delay: 60 interval: 10 active: 2 inactive: 2 on-activate: /usr/local/sbin/attach_if
murakumo-init.rbでサーバ情報の取得するので、どちらのサーバも内容は同じです。
Aliasは「mysql-server」。
murakumo-init.rbはこんな感じ。
/etc/murakumo-init.rb
AWS_ACCESS_KEY_ID = '...' AWS_SECRET_ACCESS_KEY = '...' REGION = 'ap-northeast-1' # get self ip address ip_addr = Murakumo::Util.self_ip_address # get hostname tags = Murakumo::Util.ec2_tags(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, REGION) hostname = tags['Name'] || `curl -s http://169.254.169.254/latest/meta-data/local-hostname` # rewrite host option @options['host'] = "#{ip_addr}, #{hostname}" # get instances ip_addrs = Murakumo::Util::ec2_private_ip_addresses(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, REGION) # rewrite initial-nodes nodes = ip_addrs.select {|inst_id, ip_addr, status| status == 'running' }.map {|inst_id, ip_addr, status| ip_addr } @options['initial-nodes'] = nodes.join(',') unless nodes.empty?
それからENIをフェイルオーバーするスクリプトがこんな感じ。
/usr/local/sbin/attach_if
#!/bin/sh AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... REGION=ap-northeast-1 IF_ID=eni-... /usr/bin/murakumo-attach-ec2-attach-interface \ -k "$AWS_ACCESS_KEY_ID" -s "$AWS_SECRET_ACCESS_KEY" \ -r $REGION -n $IF_ID 2>&1 | logger exit 0
最後にserver-01/02でMySQLとMurakumoを起動します。
[root@server-01 ~]# /etc/init.d/mysqld start
Starting mysqld: [ OK ]
[root@server-01 ~]# /etc/init.d/murakumo start
Starting daemon...
Waiting for daemon to start...
Daemon status: running pid=15143
■実験
初期状態ではserver-01にENIが刺さっています。
server-01
[root@server-01 ~]# ifconfig | grep ^e
eth0 Link encap:Ethernet HWaddr 02:40:B5:1B:3F:9A
eth1 Link encap:Ethernet HWaddr 02:40:B5:12:49:35
server-02
[root@server-02 ~]# ifconfig | grep ^e
eth0 Link encap:Ethernet HWaddr 02:40:B5:37:0B:C0
Murakumoのステータスはこんな感じです。
[root@server-01 ~]# mrkmctl -L
IP address TTL Priority Weight Activity Hostname
--------------- ------ --------- ------ -------- ----------
10.0.0.133 60 Master 100 Active mysql-server
10.0.0.133 60 Origin - Active server-01
10.0.0.55 60 Backup 100 Active mysql-server
10.0.0.55 60 Origin - Active server-02
まず、server-01のmysqlを落としてみると…
server-01
[root@server-01 ~]# tail /var/log/murakumo.log
I, [2012-01-22T12:27:25.606223 #15143] INFO -- : health condition changed: mysql-server: unhealthy
I, [2012-01-22T12:27:25.722457 #15143] INFO -- : sent the notice: unhealthy
I, [2012-01-22T12:27:40.563515 #15143] INFO -- : activity condition changed: mysql-server: inactive
I, [2012-01-22T12:27:40.640112 #15143] INFO -- : sent the notice: inactive
[root@server-01 ~]# ifconfig | grep ^e
eth0 Link encap:Ethernet HWaddr 02:40:B5:1B:3F:9A
server-02
[root@server-02 ~]# tail /var/log/murakumo.log
I, [2012-01-22T12:27:42.704476 #13467] INFO -- : activity condition changed: mysql-server: active
I, [2012-01-22T12:27:42.820635 #13467] INFO -- : sent the notice: active
[root@server-02 ~]# ifconfig | grep ^e
eth0 Link encap:Ethernet HWaddr 02:40:B5:37:0B:C0
eth1 Link encap:Ethernet HWaddr 02:40:B5:12:49:35
server-01がUnhealthyになり、ENIがserver-02にアタッチされます。
[root@server-01 ~]# mrkmctl -L
IP address TTL Priority Weight Activity Hostname
--------------- ------ --------- ------ -------- ----------
10.0.0.133 60 Master 100 Inactive mysql-server
10.0.0.133 60 Origin - Active server-01
10.0.0.55 60 Backup 100 Active mysql-server
10.0.0.55 60 Origin - Active server-02
次に、server-01のmysqlを再起動します。
server-01
[root@server-01 ~]# tail /var/log/murakumo.log
I, [2012-01-22T12:31:15.765068 #15143] INFO -- : health condition changed: mysql-server: healthy
I, [2012-01-22T12:31:15.842994 #15143] INFO -- : sent the notice: healthy
I, [2012-01-22T12:31:30.658938 #15143] INFO -- : activity condition changed: mysql-server: active
I, [2012-01-22T12:31:30.739008 #15143] INFO -- : sent the notice: active
[root@server-01 ~]# ifconfig | grep ^e
eth0 Link encap:Ethernet HWaddr 02:40:B5:1B:3F:9A
eth1 Link encap:Ethernet HWaddr 02:40:B5:12:49:35
server-02
[root@server-01 ~]# tail /var/log/murakumo.log
I, [2012-01-22T12:31:28.776223 #13467] INFO -- : activity condition changed: mysql-server: inactive
I, [2012-01-22T12:31:28.855345 #13467] INFO -- : sent the notice: inactive
[root@server-02 ~]# ifconfig | grep ^e
eth0 Link encap:Ethernet HWaddr 02:40:B5:37:0B:C0
[root@server-01 ~]# mrkmctl -L
IP address TTL Priority Weight Activity Hostname
--------------- ------ --------- ------ -------- ----------
10.0.0.133 60 Master 100 Active mysql-server
10.0.0.133 60 Origin - Active server-01
10.0.0.55 60 Backup 100 Active mysql-server
10.0.0.55 60 Origin - Active server-02
今度はserver-01がActiveになり、ENIがserver-01にアタッチされます。
最後にサーバ自体が落ちたものとして、server-01のMurakumoを落としてみます。
server-02
[root@server-02 ~]# tail /var/log/murakumo.log
I, [2012-01-22T12:36:08.879923 #13467] INFO -- : activity condition changed: mysql-server: active
I, [2012-01-22T12:36:08.995964 #13467] INFO -- : sent the notice: active
[root@server-02 ~]# ifconfig | grep ^e
eth0 Link encap:Ethernet HWaddr 02:40:B5:37:0B:C0
eth1 Link encap:Ethernet HWaddr 02:40:B5:12:49:35
しばらくするとserver-01のダウンが検知されてserver-02がActiveになり、ENIがserver-02に移ります。
…とまあこんな感じで、元々内部DNS用途だったMurakumoですが、Gossipプロトコルがなかなか便利だったので冗長化機能も持たせてみました。非VPCだとENIは使えませんが、そこは本来のDNSによる冗長化を使うということでどうせオワコンだし
Keepalivedはそもそも使えないしL7のチェックはちょっとめんどくさいし、Heartbeatはマルチキャスト使えないしヘルスチェックはやっぱりめんどいし、、、ということでミドルウェアのヘルスチェック込みで手軽にVPCで冗長化したい案件にはちょうどよいと思います。
絶賛、人柱募集中 ぜひぜひご利用ください。