ちょっと話題の記事

GlusterFSで高可用性メールサーバを構築する

はじめに

AWSでメールシステムの高可用性確保を考えたとき、どのような構成を思い浮かべるでしょうか。私が脳内に思い浮かべたのはこのような構成です。

rhs_mail-2

外部から内部へのメール配送は以下の流れになります。

  • Route 53にてMXレコードを2行(MailGateway1とMailGateway2)設定します。
  • MailGatewayからMailBoxへはPostfixのtransportとrecipient_bcc_mapsで冗長的に配送するよう設定します。

内部から外部へのメール配送は以下の流れになります。

  • ClientのメールクライアントソフトウェアでSMTPサーバとしてInternalELBを指定し、ELBがMailBox1とMailBox2に振り分けます。
  • MailBoxのpostfixではrelayhostに自AZのMailGateway、fallback_relayに別AZのMailGatewayを指定し、冗長的に配送するよう設定します。

またメール受信については、ClientのメールクライアントソフトウェアでPOP3/IMAPサーバとしてInternalELBを指定し、ELBがMailBox1とMailBox2に振り分けます。

しかしこの構成には欠点があります。メールボックスが分散的に配置されているがメールボックスの同期はされていないということです。このためそれぞれのメールボックスに別々にメールが保存されてしまいますし、片方のサーバに障害があった場合、そのサーバに保存されたメールはアクセス出来なくなってしまいます。 通常であれば外部ストレージを共有したActive-Standbyのクラスタ構成にするのが正攻法ですが、ここでは分散ファイルシステムであるGlusterFSを使ってメールボックスの分散配置と同期を行ってみたいと思います。

rhs_mail2-2

GlusterFSについては「EC2でGlusterFSを使ってみた | Developers.IO」という記事をご参照下さい。

以降の作業は1台目と2台目の両方のMailBoxサーバで実施します。

Brickの作成

Brick用にEBSを追加し、ext4のinode=512でフォーマットします。

$ sudo mkfs.ext4 -I 512 /dev/xvdf

Brick用のディレクトリを作成し、EBSをマウントします。また/etc/fstabを修正し、インスタンス起動時に自動でマウントされるよう設定しておきます

$ sudo mkdir -p /glusterfs/vol0
$ sudo mount /dev/xvdf /glusterfs/vol0
$ sudo vi /etc/fstab
/dev/xvdf /glusterfs/vol0 ext4 defaults,noatime 1 1
$ df -h
Filesystem            Size  Used Avail Use% マウント位置
/dev/xvda1            7.9G  1.1G  6.8G  14% /
tmpfs                 298M     0  298M   0% /dev/shm
/dev/xvdf             992M   34M  908M   4% /glusterfs/vol0

GlusterFSのインストール

GlusterFS用のyumレポジトリ情報をダウンロードして一部修正します。 (※修正する理由については「EC2でGlusterFSを使ってみた | Developers.IO」をご参照下さい)

$ sudo curl -o /etc/yum.repos.d/glusterfs-epel.repo http://download.gluster.org/pub/gluster/glusterfs/3.3/LATEST/EPEL.repo/glusterfs-epel.repo
$ sudo vi /etc/yum.repos.d/glusterfs-epel.repo
  # releaseverを6に書き換え

yumglusterfs-serverをインストールし、サービスを起動します。

$ sudo yum -y install glusterfs-server
$ sudo service glusterd start
Starting glusterd:                                         [  OK  ]
$ sudo chkconfig glusterd on

分散ファイルシステムの設定

本作業だけは1台目のMailBoxサーバだけで行います。 glusterコマンドで対話的にGlusterFSクラスタの設定を行います。

$ sudo gluster
gluster> peer status                                                                                                                           
No peers present                                                                                                                               
gluster> peer probe 172.31.27.73
Probe successful
gluster> peer status
Number of Peers: 1

Hostname: 172.31.27.73
Uuid: 83c8d48a-071e-4934-920f-b0fb8c0acdf4
State: Peer in Cluster (Connected)

2台目のMailBoxサーバからも確認してみましょう。

$ sudo gluster
gluster> peer status
Number of Peers: 1

Hostname: 172.31.12.220
Uuid: b5fca2b0-d656-4149-8e9e-f29feacefd54
State: Peer in Cluster (Connected)

それでは1台目のMailBoxサーバで、先ほど作成したBrick用EBSをReplicaボリュームとして設定します。

gluster> volume info
No volumes present
gluster> volume create gVol0 replica 2 transport tcp 172.31.12.220:/glusterfs/vol0 172.31.27.73:/glusterfs/vol0
Creation of volume gVol0 has been successful. Please start the volume to access data.
gluster> volume info
 
Volume Name: gVol0
Type: Replicate
Volume ID: dd667f18-5b53-48e1-a4fa-9ce87317b570
Status: Created
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: 172.31.12.220:/glusterfs/vol0
Brick2: 172.31.27.73:/glusterfs/vol0

作成したGlusterFS Voluimeを起動します。

gluster> volume status gVol0
Volume gVol0 is not started
gluster> volume start gVol0
volume statStarting volume gVol0 has been successful
gluster> volume status gVol0
Status of volume: gVol0
Gluster process                                         Port    Online  Pid
------------------------------------------------------------------------------
Brick 172.31.12.220:/glusterfs/vol0                     24009   Y       4460
Brick 172.31.27.73:/glusterfs/vol0                      24009   Y       4476
NFS Server on localhost                                 38467   Y       4466
Self-heal Daemon on localhost                           N/A     Y       4472
NFS Server on 172.31.27.73                              38467   Y       4482
Self-heal Daemon on 172.31.27.73                        N/A     Y       4488

分散ファイルシステムのマウント

デフォルトで起動しているsendmailを停止した上で、メールボックスが保存される/var/spool/mailディレクトリに作成したGlusterFS Volumeをマウントします。

$ sudo service sendmail stop
Shutting down sm-client:                                   [  OK  ]
Shutting down sendmail:                                    [  OK  ]
$ sudo mv /var/spool/mail /var/spool/mail.org
$ sudo mkdir /var/spool/mail
$ sudo mount -t glusterfs 172.31.12.220:/gVol0 /var/spool/mail/
$ df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/xvda1            7.9G  1.2G  6.7G  15% /
tmpfs                 298M     0  298M   0% /dev/shm
/dev/xvdf             992M   34M  908M   4% /glusterfs/vol0
172.31.12.220:/gVol0  992M   34M  908M   4% /var/spool/mail

このボリュームもインスタンス起動時に自動マウントされるよう、/etc/fstabを修正しておきます。

$ sudo vi /etc/fstab
172.31.12.220:/gVol0 /var/spool/mail glusterfs defaults,noatime 1 1

Postfixのインストール、設定

yumコマンドでpostfixをインストールします。

$ sudo yum -y install postfix

PostfixはDefaultでmailbox形式でメールを保存しますので、特別な設定は必要ありません。自ドメインのメールはLocalに、自ドメイン以外のメールはMail Gatewayに配送するように設定して下さい。 設定が終わったらpostfixのサービスを起動します。またsendmailはもう使わないのでchkconfigでoffにしましょう。

$ sudo service postfix start
Starting postfix:                                          [  OK  ]
$ sudo chkconfig sendmail off
$ sudo chkconfig postfix on

またシステムで標準的に使用するmtaをpostfixに変更しておきます。

$ sudo alternatives --config mta 

2 プログラムがあり 'mta' を提供します。

  選択       コマンド
-----------------------------------------------
*+ 1           /usr/sbin/sendmail.sendmail
   2           /usr/sbin/sendmail.postfix

Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:2

Dovecotのインストール、設定

POP3/IMAPサーバとしてDovecotをインストールします。

$ sudo yum -y install dovecot

環境に合わせて設定します。一点だけ、メール保存場所の設定については、postfixと同様に/var/spool/mailを指定します。

$ sudo vi /etc/dovecot/conf.d/10-mail.conf
mail_location = mbox:~/mail:INBOX=/var/spool/mail/%u

設定が終わったらサービスを起動します。

$ sudo service dovecot start
Starting Dovecot Imap:                                     [  OK  ]
$ sudo chkconfig dovecot on

動作確認

それでは実際にメールを送信して同期の確認をしてみます。 動作確認で使うmailxパッケージをインストールします。

$ sudo yum -y install mailx

1台目のMailBoxサーバからmailxコマンドでメールを送信してみます。

$ mail ec2-user
Subject: test mail from mbox1
test mail from mbox1
.
EOT
$ ls /var/spool/mail
ec2-user

2台目のMailBoxサーバで確認します。

$ mailx
Heirloom Mail version 12.4 7/29/08.  Type ? for help.
"/var/spool/mail/ec2-user": 1 message 1 new
>N  1 EC2 Default User      Wed Jan 29 02:00  18/712   "test mail from mbox1"
& 1
Message  1:
From ec2-user@ip-172-31-27-73.localdomain  Wed Jan 29 02:00:32 2014
Return-Path: <ec2-user@ip-172-31-27-73.localdomain>
X-Original-To: ec2-user
Delivered-To: ec2-user@ip-172-31-27-73.localdomain
Date: Wed, 29 Jan 2014 02:00:32 +0000
To: ec2-user@ip-172-31-27-73.localdomain
Subject: test mail from mbox1
User-Agent: Heirloom mailx 12.4 7/29/08
Content-Type: text/plain; charset=us-ascii
From: ec2-user@ip-172-31-27-73.localdomain (EC2 Default User)
Status: R

test mail from mbox1

& quit

ちゃんとメールボックスが同期されています!

まとめ

メールユーザ数が多かったりメール流量が多い場合の性能に留意が必要ですが、MultiAZライクなメールサーバが構築出来ました。一般的にGlusterFSは小サイズ大量のファイルを扱うより大サイズ少量のファイルを扱う方が得意と言われますので、Maildir形式と比べMailbox形式のほうが分散ファイルシステムには向いていると思います。

またRedHat Storageのようなエンタープライズ向けの製品を使えば、より一層堅牢なシステムになるのでは無いでしょうか。RedHat Storageはテストドライブがありますので、こちらも検証してみます!