タグ「Linux」が付けられているもの

UbuntuでProxyサーバロードバランス(3)

これまで(UbuntuでProxyサーバロードバランス(1)UbuntuでProxyサーバロードバランス(2))構築したとおり、Ubuntu Server 12.04LTSを使ってロードバランサーを構築し、Proxyサーバの負荷分散、障害検知と自動での切り離し、組み込みを動作させるところまで構築しました。

残った問題である、ロードバランサーがダウンしたときに結局システムが止まってしまうという問題に対処するため、ロードバランサーをクラスタ構成してみようと思います。

クラスタ構成と言っても色々ありますが、今回はkeepalivedのVRRPをそのまま使ってロードバランサーをActive / Standby型のクラスタにしてしまいます。


LB-2.jpg

単純にロードバランサー2を追加します。そしてProxyサーバの仮想IPアドレス(192.168.100.10)をVRRPによるフローティングアドレスにしてしまいます。

UbuntuでProxyサーバロードバランス(2)

前回(UbuntuでProxyサーバロードバランス(1))Proxyサーバに対するアクセスが負荷分散される状態まで構築をしましたが、Proxyサーバがダウンしたときにそれを検知して切り離す機能が無いため、ダウンしたProxyサーバにアクセスしようとし続けてしまいます。

そこで、Keepalivedを組み込んで、L4レベルでの死活監視を行わせます。

具体的にはProxyサーバのTCPポート / 8080がOpenしている状態を定期的に確認して、ポートがClose状態、または無反応になったら、そのサーバへの振り分けは行わないようにします。


UbuntuでProxyサーバロードバランス(1)

PROXYサーバをLinuxのLVS(ipvsadm)を使って冗長構成にする事を考えました。
LVSは既に使っている(RedHat Enterprise LinuxでWebサーバロードバランス)のですが、ここではWebサーバのバランシングではなく、Proxyサーバのバランシングを行います。
また、前回の検証時はRedHat Enterprise Linux ES3を使って検証を行っていましたが、今回はUbuntu Server 12.04LTSを使います。ipvsadmがディストリビューションに含まれているため、それにあわせてファイルの配置が変更になります。検証機も実機ではなくESXi上に立てることにします。
今回も目的はProxyサーバの耐障害性の向上で、負荷分散を目的とはしていませんが、構築の順序としては負荷分散機能(ipvsadm)→耐障害機能(keepalived)となります。


LB.jpg

※Proxyサーバの仮想IPアドレスは192.168.100.10にする

論理的にはロードバランサーがクライアントからの要求をすべて受けて、2台のProxyサーバに振り分ける構成になるため、図のようにロードバランサーの配下にProxyサーバ2台がぶら下がる構成になります。
物理的には同一セグメントでフラットに接続されている構成になります。
ロードバランサーの構成をNATにしてしまうと、ProxyサーバのアクセスログにクライアントのIPアドレスではなく、ロードバランサーのIPアドレスが記録されてしまう弊害がおきるため、構成はDSRにします。この構成の大きなメリットが2つあり、1つ目がソースIPアドレス(クライアントのIPアドレス)がそのままサーバに伝わることと、戻りパケットの処理にロードバランサーが介在しないことで、ロードバランサー自身の負荷が少なくなる事です。 デメリットはリアルサーバ側に若干細工が必要になることですが、今回はPROXYサーバも自前のため、デメリットになりません。

Proxyサーバの待ち受けポートは8080を使用しています。


ESXi上のLinuxゲストOSの時刻がずれる

ESXi上のゲストOSで動作させているDovecotがお亡くなりになる症状が出ました。

エラーログを見ると
Jul 21 18:39:10 mail dovecot: imap: Fatal: Time just moved backwards by 18 seconds. This might cause a lot of problems, so I'll just kill myself now. http://wiki2.dovecot.org/TimeMovedBackwards
Jul 21 18:39:11 mail dovecot: imap: Fatal: Time just moved backwards by 17 seconds. This might cause a lot of problems, so I'll just kill myself now. http://wiki2.dovecot.org/TimeMovedBackwards
Jul 21 18:39:13 mail dovecot: imap: Fatal: Time just moved backwards by 17 seconds. This might cause a lot of problems, so I'll just kill myself now. http://wiki2.dovecot.org/TimeMovedBackwards
というエラーを吐いていて意訳すると
時間が18秒も戻ってるよ。なんか、すげーヤバイ。オレ、とりあえず落ちるわ。後ヨロ(http://wiki2.dovecot.org/TimeMovedBackwards 見といてね)
とかそんな感じ。

Wiki(http://wiki2.dovecot.org/TimeMovedBackwards)を見ると、Dovecotは時間に敏感なので、時間が数秒戻るとマシンに問題があると判断して自分から自殺してしまう、ntpdを使って時刻同期しておいてくれ。
あと、ntpdは時間のズレが激しすぎるとSTEP動作になっていきなり時間を戻してしまうから、-xオプションを付けて起動するか、ntp.confに"tinker step 0"と書いておくこと。
みたいに書かれていたので、その通り/etc/default/ntpに
NTPD_OPTS='-g' ↓ NTPD_OPTS='-g -x'
起動オプションとして -x を追加した。

ただ気になるのが、ntpdで時刻同期をしていたのにOSの時刻が著しくずれていたという点。
普通であれば、ntpdは時間のズレを少しずつ補正する(Slew動作)のだが、そのズレが著しい場合には一気に時間を補正する(Step動作)。ここで問題になっているのはOSの時間が著しくずれていたからStep動作で時間が一気に巻き戻った→Dovecotが時間の巻き戻りを検出して自殺した、という部分なので、ntpdの動作オプションで -x を付けて起動する事でStep動作への切り替わりを発生しにくく抑止したことは対処療法でしかなく、根本的にはOSの時刻が著しくずれていた事が問題になる。

なぜ?

メールサーバはここ何年ずっとDovecotで運用してきている、ntpdの設定もほぼ同じ。その間プラットフォームは色々と移っているが、その間問題無く動いていた。
思い当たる節は・・・仮想化?(ESXi)

そういえば・・・と思い出したのが、VMware Server上でLinux Kernel 2.6を動作させると時間がずれるという話。
仮想化環境でLinuxを動かすときは何かTipsがあったんじゃないかと思い出して調べてみたところ、アタリっぽい。

VMware-toolsの設定でホストとの時間調整を行わない設定にして、時刻同期はntpdのみとした。
$ sudo vmware-toolbox-cmd timesync status $ sudo vmware-toolbox-cmd timesync disable
全てのゲストOSにその設定を行って、様子を見ることにした。

Linuxでマルチホーム

とあるところでマルチホームの構成を組まなきゃならない事になったので、手元のUbuntu(とCentOS)で色々テストしてみました。

結果から言うとiproute2を使えば、マルチホームが組めます。

例えば簡単に考えるとNICを2枚差しして別々のIPアドレスを振って、ISP毎に別のルータを介して接続します。

iproute2-test.jpg

こうすると、Linuxのルーティングテーブルが1つしかない為、Linuxのデフォルトルートが10.1.1.1(ルータ1)に向いていた場合、入ってきたインターフェース(NIC2 = 10.2.2.2)と出て行くインターフェース(NIC1 = 10.1.1.2)が違ってしまい、ISP2からのリクエストをISP1から応答する事になるため、通信が行えない事になります。

また、LinuxからISP1を経由したインターネットへのアクセスは行えますが、ISP2へのアクセスはスタティックルートで指定したIPアドレスを除き、出来ない事になります。

ネットワーク機器の場合、バーチャルルータやVRF等の機能を持っていれば複数のルーティングインスタンスを起動することが出来るため、ルーティングインスタンス毎に別のデフォルトルートを指定する事ができたり、ソースルーティングやポリシーベースルーティングの機能を使って、目的に応じてデフォルトルートを振り向けることが出来るのですが・・・。

Linuxのiproute2が入っている場合、このルーティングテーブルを複数持つことができるため、ISP1とISP2に同時に接続する事が出来るようになります。

先にiptable2のルーティングテーブルを複数持たせる設定を行います。

/etc/iprotue2/rt_table2
#
# reserved values
#
255	local
254	main
253	default
0	unspec
#
# local
#
#1	inr.ruhep
2	ISP2

このファイルの255 local、254 main、254 default, 0 unspecは最初から記載のあるエントリです。そして2個目のルーティングテーブルとして2 ISP2を追記しました。

Ubuntu(debian)の場合、NICの設定は/etc/network/interfaceで行うのですが、1枚目のNICは普通に記述します。

auto eth0
iface eth0 inet static
	address 10.1.1.2
	netmask 255.255.255.0
	network 10.1.1.0
	broadcast 10.1.1.255
	gateway 10.1.1.1

そして2枚目のNICは

auto eth1
iface eth1 inet static
	address 10.2.2.2
	netmask 255.255.255.0
	post-up ip route add 10.2.2.0/24 dev eth1 src 10.2.2.2 table ISP2
	post-up ip route add default via 10.2.2.1 table ISP2
	post-up ip rule add from 10.2.2.2 table ISP2
	post-down ip rule del from 10.2.2.2 table ISP2

という風に記述します。

CentOSの場合、NICの設定は/etc/sysconfig/network-scriptsで行うので、

/etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=none
ONBOOT=yes
NETMASK=255.255.255.0
IPADDR=10.1.1.2
GATEWAY=10.1.1.1
TYPE=Ethernet
USERCTL=no
IPV6INIT=no
PEERDNS=yes
/etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
BOOTPROTO=none
ONBOOT=yes
NETMASK=255.255.255.0
IPADDR=10.2.2.2
TYPE=Ethernet
USERCTL=no
IPV6INIT=no
PEERDNS=yes
/etc/sysconfig/network-scripts/rule-eth1
from 10.2.2.2 table ISP2
/etc/sysconfig/network-scripts/route-eth1
10.2.2.0/24 dev eth1 src 10.2.2.2 table ISP2
10.2.2.0/24 dev eth1 src 10.2.2.2
default via 10.2.2.1 table ISP2

という風に記述します。

ルーティングテーブル(それぞれ)を確認すると、

$ sudo ip route show table main
10.2.2.0/24 dev eth1  proto kernel  scope link  src 10.2.2.2
10.1.1.0/24 dev eth0  proto kernel  scope link  src 10.1.1.2
default via 10.1.1.1 dev eth0  metric 100 
$ sudo ip route show table ISP2
10.2.2.0/24 dev eth1  scope link  src 10.2.2.2
default via 10.2.2.1 dev eth1 

という具合に、mainのテーブルと ISP2(と名付けた)テーブルのそれぞれが別のゲートウェイを向いているようになります。

追加作成したテーブル(ISP2)はip ruleコマンドで確認出来ます。

$ ip rule
0:	from all lookup local
32765:	from 10.2.2.2 lookup ISP2
32766:	from all lookup main 
32767:	from all lookup default 

この状態であれば、ISP1からNIC1に入ったクエリはNIC1からISP1経由で応答し、ISP2からNIC2に入ったクエリはNIC2からISP2経由で応答する事ができるため、マルチホームに対応する事が出来るようになります。

但し、F5のBIG-IPやRadwareのLinkproof、PIOLINKのPAS等のWANマルチホーミング装置を使った場合は、インターネットからのincoming方向の負荷分散や、冗長化(片方の回線がダウンした場合に、もう片方の回線にトラフィックを片寄せする機能)を行う為に、インターネット側に応答するDNSパケットを細かく制御してくれますが、Linuxのiproute2のマルチホーミングではそこまでの対応はしてくれません。

Linuxだけで何とかしてみる方法としてiproute2での対応は、負荷分散についてはある程度工夫することで対応出来るかと思いますが、単純なラウンドロビンではなく、回線負荷も考慮した動的な負荷分散は難しいですし、片方の回線がダウンしたときの処理を考えると可用性の向上も難しいでしょう。

それにしても、、、おとなしくWAN回線のinboundトラフィックのマルチホーミング装置があれば、このような方法は取らなくても良いのですが、、、。

ボンディング(最終)

できれば、最終にしたいのですが、



bondingの件。検証すればするほど、ネットワーク側の設定についての理解が必要だと認識します。


え、と。はっきり言って、ネットワークのことについて、訳わかんないならば

mode=1にしなさい。おとなしく。


ちなみに前述のとおり、mode=1の動作としてカーネルバージョンが低いときは、
切り戻りの動作で一部不具合があるので、注意した方がいいです。




というのをあらためて実地検証してみますが。



追記。

Ubuntu9.04でbondingの設定
/etc/modprobe.d/bonding.conf
alias bond0 bonding
options bond0 mode=1 arp_interval=1000 arp_ip_target=192.168.10.254 primary=eth0

/etc/network/interfaces
auto lo
iface lo inet loopback

iface eth0 inet manual
iface eth1 inet manual

auto bond0
    iface bond0 inet static
    address 192.168.10.1
    netmask 255.255.255.0
    network 192.168.10.0
    gateway 192.168.10.254
    post-up /sbin/ifenslave bond0 eth0 eth1
    pre-down /sbin/ifenslave -d bond0 eth0 eth1


設定変更を反映させる
ifconfig bond0 down
rmmod bond0
modprobe bond0
ifconfig bond0 up
/etc/init.d/networking restart


LinuxのBonding。
最近、触る機会が無いっていうか。。。
なんですが、ちょっとモードをまとめてみます。



Bondingとは。
Linux の kernel 2.4.12以降で実装された、NICをチーミング(Teaming)する機能。(ketnel 2.4.18以降で標準で組み込まれています)
複数のNICを論理的に1つのNICと見なして束ねることで、耐障害性を向上したり、送受信のパフォーマンスを(分散処理することによって)上げる技術。

NICを束ねたものとして仮想のデバイスを使用します。通常NICは/dev/eth0、/dev/eth1、/dev/eth2・・・というデバイス名を使用しますが、束ねたあとの仮想デバイスは/dev/bond0、/dev/bond1、/dev/bond2・・・というデバイス名を使用します。



ボンディング?

LinuxのBondingの話。

どうしても、箱屋さんにはネットワークが鬼門になっていて、
ネットワーク屋さんは、箱屋さんにイラッとくるようですが。


LinuxのBondingもそんな一つ。



Fedora オンラインでアップグレード

Fedora 9の公開が間近ということもあって、身に回りのFedoraをオンラインでバージョンアップしてみた。
(サスガにFedoraCore 5はキビシイだろうし・・・)

基本的には
1.そのメジャーバージョンでのアップデートを行う
yum update
2.再起動
shutdown -r now
3.fedora-releaseの更新
rpm -Uvh fedora-release-x-x.noarch.rpm fedora-release-notes-x-x.noarch.rpm
4.yumのキャッシュをクリア
yum clean all
5.アップグレード
yum upgrade
6.再起動
shutdown -r now
という手順になるのだが、細かい部分では色々トラブルも起きる。
都度、対応する事になるのだが、、一番苦痛なのは依存関係でyum upgradeに失敗した場合。
ダウンロードも含めてやり直しになる。
時間がかかるのは仕方ないけど、、。最初からやり直しというのは・・・。精神的にダメージが大きいです。

ずっとほっといたのが悪いのは判っちゃいるんですけど。


信頼できるLinux?

結局Linux使うとしたら何使う?という話。


個人的に使うのであれば、ですが。

サーバ目的であれば手堅くCentOSAsianuxを選ぶところです。
クライアント目的であれば、Ubuntuあたりをチョイスしたいところです。
PC-UNIX全般から選べるのなら、迷わずNetBSDかFreeBSDかSolaris/x86をチョイスします。
でも、仕事になるとRedHatEnterpriseと答えますが。


・・・本当はBSDのサーバが信頼できるんだけど、サポートが得られないからなぁ・・・


 遊べる(=面白い)OSと、お仕事で使えるOSが違うというのが悲しいところです・・・。