2012年1月29日日曜日

DNS キャッシュ・サーバの冗長化

冗長化された DNS キャッシュ・サーバを構築します。

もご参照ください。



DNS キャッシュ・サーバとして、dnsmasq を利用します。

$ sudo yum install dnsmasq

上流の DNS サーバが、172.28.255.253172.28.255.254の場合、次のように設定します。

$ echo 'resolv-file=/etc/dnsmasq.resolv.conf' \
  | sudo tee /etc/dnsmasq.d/resolv.conf
$ echo 'nameserver 172.28.255.253' \
  | sudo tee /etc/dnsmasq.d/resolv.conf
$ echo 'nameserver 172.28.255.254' \
  | sudo tee -a /etc/dnsmasq.resolv.conf
$ echo 'nameserver 127.0.0.1' \
  | sudo tee /etc/resolv.conf

上流の DNS サーバが不知で、追加で名前解決したい IP アドレスとサーバのリストを /etc/hosts に追加します。

$ sudoedit /etc/hosts

dnsmasq デーモンを登録し、起動します。

$ sudo /sbin/chkconfig --add dnsmasq
$ sudo /sbin/chkconfig dnsmasq on
$ sudo /etc/init.d/dnsmasq start


ここまでの作業を dns01,dns02 サーバで行ったとして、冗長構成を組むこととします。
クライアント側で2台以上の DNS サーバを指定する冗長化だけではなぜダメなのか、といったあたりは、下記を参照していただければと思います。

[24時間365日]サーバ/インフラを支える技術

この書籍で紹介されている構成は、keepalived を使って冗長化されたロードバランサを構築し、ロードバランサ配下に2台の DNS サーバをぶら下げ、DNS サーバ2台をアクティブ・アクティブ構成としています。同一セグメント間の通信を考慮し、DSR(Direct Server Return)構成となっています。
ここまでやるのは、牛刀のような気がするので、ロードバランサ抜き、DSR 構成なしで、
DNS サーバ2台をアクティブ・アクティブ構成としてみました。DNS サーバに keepalived をインストールして構成します。


―――┬―――――――┬――― 192.168.1.0/24
   |.251     |.252 
   |       |   
   | .253     |   
   |←―――――→|   
   |     .254 |   
   |       |   
┌―┬┴┬―┐ ┌―┬┴┬―┐
| |8| | | |8| |
| └―┘ | | └―┘ |
| dns01  | | dns02  |
| ┌―┐ | | ┌―┐ |
| |0| | | |0| |
└―┴┬┴―┘ └―┴┬┴―┘
   |       |   
   | .100.253   |   
   |←―――――→|   
   |   .100.254 |   
   |       |   
   |.100.251   |.100.252
―――┴―――――――┴――― 172.28.0.0/16


クライアントでは、DNS サーバとして /etc/resolv.conf に以下のように記載します。

[奇数号機]
nameserver 192.168.1.253
nameserver 192.168.1.254
もしくは
nameserver 172.28.100.253
nameserver 172.28.100.254

[偶数号機]
nameserver 192.168.1.254
nameserver 192.168.1.253
もしくは
nameserver 172.28.100.254
nameserver 172.28.100.253


正常時は、奇数号機が dns01 保持の VIP に、偶数号機が dns02 保持の VIP に問い合わせるようにします。

異常時には、クライアント側では正常時と同じように問い合わせますが、サーバ側で正常な側が全て応答します。

keepalived は、VRRP 機能と、ロードバランスするためのチェック機能を備えています。
VRRP 機能を利用して、VIP を制御し、チェック機能を利用して DNS サーバ及びネットワーク到達性をチェックさせます。

正常時には、dns01 では、VIP 192.168.1.253 と 172.28.100.253 を保持し、dns02 では、VIP 192.168.1.254 と 172.28.100.254 を保持させます。
異常時には、keepalived を停止させることで VIP を放棄し、正常に動作している他方の DNS サーバで全 VIP を保持させます。

keepalived のパッケージを前々回 rpm 化しました。
~/rpmbuild/RPMS/x86_64/keepalived-1.2.1-6.el5pcs.x86_64.rpm
として作成しているものとし、以下のようインストール、設定します。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
[ "dns01" = "`uname -n | awk -F. '{print $1}'`" ] && PRIMARY=1
sudo rpm -ivh ~/rpmbuild/RPMS/*/keepalived-1*.rpm
sudo sed -i -e 's!^# chkconfig:.*$!# chkconfig: 345 99 01!' /etc/init.d/keepalived
sudo /sbin/chkconfig --del keepalived; sudo /sbin/chkconfig --add keepalived
cat << EOF | sudo tee /etc/keepalived/dns_check.sh
#!/bin/bash

IPs1="192.168.1.101 192.168.1.102 192.168.1.103 192.168.1.104"
IPs2="172.28.100.101 172.28.100.102 172.28.100.103 172.28.100.104"
EOF
cat << 'EOF' | sudo tee -a /etc/keepalived/dns_check.sh

/usr/bin/dig +time=001 +tries=3 @127.0.0.1 localhost.localdomain
if [ 0 -ne $? ]; then
  /etc/init.d/keepalived stop
  exit 1
fi

TRIES=3
while :
do
  for i in $IPs1
  do
    ping -W 1 -c 1 $i && break 2
  done

  TRIES=$((TRIES-1))
  if [ $TRIES -le 0 ]; then
    /etc/init.d/keepalived stop
    exit 1
  fi
done
TRIES=3
while :
do
  for i in $IPs2
  do
    ping -W 1 -c 1 $i && break 2
  done

  TRIES=$((TRIES-1))
  if [ $TRIES -le 0 ]; then
    /etc/init.d/keepalived stop
    exit 1
  fi
done
exit 0
EOF
sudo chmod 755 /etc/keepalived/dns_check.sh

cat << EOF | sudo tee /etc/keepalived/keepalived.conf
vrrp_instance VIP1 {
  state BACKUP
  interface eth0
  garp_master_delay 5
  virtual_router_id 2
  priority $((100+PRIMARY))
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass password
  }
  virtual_ipaddress {
    172.28.100.253/16 dev eth0 label eth0:0
    192.168.1.253/24 dev eth8 label eth8:0
  }
}
vrrp_instance VIP2 {
  state BACKUP
  interface eth0
  garp_master_delay 5
  virtual_router_id 3
  priority $((100-PRIMARY))
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass password
  }
  virtual_ipaddress {
    172.28.100.254/16 dev eth0 label eth0:1
    192.168.1.254/24 dev eth8 label eth8:1
  }
}
virtual_server 127.0.0.1 65053 {
  delay_loop 3
  real_server 127.0.0.1 53 {
    MISC_CHECK {
      misc_path "/etc/keepalived/dns_check.sh"
      misc_timeout 60
    }
  }
}
EOF

1行目では、dns01 サーバでのみ PRIMARY 変数を「1」と定義してます。dns02 サーバでは未定義です。57行目、73行目の値が異なります。dns02 サーバではどちらも「100」ですが、dns01 サーバでは、VIP1(172.28.100.253,192.168.1.253)の優先度が「101」となり、VIP2(172.28.100.254,192.168.1.253)の優先度が「99」となります。
結果として、dns01,dns02 双方で keepalived が正常に動作しているときには、VIP1 が dns01 サーバ側で、VIP2 が dns02 サーバ側で保持されることになります。異常と判断された場合には、異常な側の keepalived を停止させる(停止してしまう場合、停止していると判断される場合も含む)ことで、正常な側で VIP1,VIP2 が保持されます。
56行目、72行目の ID は0~255の値を指定します。同一セグメント内に同じ ID を使用する VRRP プロトコルを利用するものが存在してはなりません。
61行目、77行目のパスワードは適宜変更してください。
58行目、74行目にて、VRRP の死活監視間隔を1秒ごとに設定しています。
88行目の設定により、監視用プログラム /etc/keepalived/dns_check.sh を呼び出すようにしています。85行目の設定により3秒ごとに起動します。89行目でタイムアウトを60秒に設定していますが、keepalived がタイムアウトを検知するだけでさほどの意味はありません。指定の監視プログラムが短時間で確実に終了するように書かれていないと、監視プログラムのプロセス数が3秒ごとに増えていくので注意が必要です。タイムアウトしたからといっても、keepalived が KILL してくれるわけではありません。
84行目のポート指定はダミーです。無効なプロトコルとして起動時にログが出力されても無視してかまいません。監視プログラムを定期的に呼び出すためだけに84~92行目の設定を入れています。
keepalived の設定についは man で調べてください。

監視プログラムの説明をします。
13行目にて、dig コマンドにて問い合わせを行っています。1秒でタイムアウトします。3回試行します。失敗した場合は DNS サーバが正常に起動していないものとして keepalived を停止させます。
8行目で定義した IP アドレスに対し ping を実行します。1秒でタイムアウトします。いずれかの IP アドレスに対する ping が成功した場合、ループは正常終了します。3回試行します。失敗した場合は、eth8 もしくは eth8 につながるネットワークのどこかに不具合があるものとして、keepalived を停止させます。
同じく9行目で定義している IP アドレスに対してもチェックします。eth0 のチェックとなります。
8行目、9行目には、全 DNS クライアントを指定するとか、まず停止しないだろうと思われるネットワーク機器を指定しておけばよいのではないかと思います。最初に指定したものへの ping 疎通が確認できれば後続のものへの ping は実行しないので、たくさん指定しても負荷の問題とはなりません。VIP の切り替えを速くしたいのであれば、少なく指定した方がよいです。ネットワークが復活しても keepalived を自動起動するからくりは今のところ用意していないので、どのようにバランスを取るべきか考える必要はあります。



0 件のコメント:

コメントを投稿