Requirements
- OpenDJ
- OpenAM
- HAProxy
- keepalived
Overview
- サーバ2台
- それぞれOpenDJ、OpenAM、HAProxy、keepalivedをインストール
- HAProxyはkeepalivedでアクティブ-スタンバイにし冗長化
- OpenAM、OpenDJはHAProxyでバランシングし冗長化
Install
HAProxy
- haproxyをyumでインストール
yum install haproxy
SSL対応させる場合は開発版を入れる。
# !/bin/bash
### VARIABLES ###
PRE_PACK="openssl-devel pcre-devel make gcc"
VER="1.5.1"
# Setup Colours
black='\E[30;40m'
red='\E[31;40m'
green='\E[32;40m'
yellow='\E[33;40m'
blue='\E[34;40m'
magenta='\E[35;40m'
cyan='\E[36;40m'
white='\E[37;40m'
boldblack='\E[1;30;40m'
boldred='\E[1;31;40m'
boldgreen='\E[1;32;40m'
boldyellow='\E[1;33;40m'
boldblue='\E[1;34;40m'
boldmagenta='\E[1;35;40m'
boldcyan='\E[1;36;40m'
boldwhite='\E[1;37;40m'
Reset="tput sgr0" # Reset text attributes to normal
#+ without clearing screen.
cecho () # Coloured-echo.
# Argument $1 = message
# Argument $2 = color
{
message=$1
color=$2
echo -e "$color$message" ; $Reset
return
}
clear
cecho "Installing/upgrading your web server..." $boldgreen
yum -y -q install $PRE_PACK > /dev/null
mkdir -p /src
cd /src
wget -q http://www.haproxy.org/download/1.5/src/haproxy-$VER.tar.gz
tar xzf haproxy-$VER.tar.gz && rm -f haproxy*.tar.gz;
cd haproxy-$VER
cecho "Configuring and Making HAPROXY" $boldgreen
make TARGET=linux2628 CPU=x86_64 USE_OPENSSL=1 USE_ZLIB=1 USE_PCRE=1 # compiles it with compression and ssl support; use CPU=x86_64 for CentOS x64 or i686 where approriate
cecho "Installing HAPROXY" $boldgreen
make install
cecho "Adding HAProxy User" $boldyellow
id -u haproxy &>/dev/null || useradd -s /usr/sbin/nologin -r haproxy
cecho "Creating config and Adding Daemon" $boldgreen
cp /usr/local/sbin/haproxy* /usr/sbin/ # copy binaries to /usr/sbin
cp /src/haproxy-$VER/examples/haproxy.init /etc/init.d/haproxy # copy init script in /etc/init.d
chmod +x /etc/init.d/haproxy # setting permission on init script
mkdir -p /etc/haproxy # creating directory where the config file must reside
cp /src/haproxy-$VER/examples/examples.cfg /etc/haproxy/haproxy.cfg # copy example config file
mkdir -p /var/lib/haproxy # create directory for stats file
touch /var/lib/haproxy/stats # creating stats file
cecho "checking config and starting service" $boldyellow
service haproxy check # checking configuration file is valid
service haproxy start # starting haproxy to verify it is working
chkconfig haproxy on # setting haproxy to start with VM
exit 0
- socketファイル用のディレクトリを作成
mkdir /var/run/haproxy
- 証明書
# 鍵と証明書からpemファイルを作成
cat server.key server.crt > /etc/ssl/certs/server.pem
- haproxy.cfgを編集する
global
daemon
maxconn 50000
stats socket /var/run/haproxy/haproxy.sock mode 0600 level admin
defaults
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend sso_in
# SSL対応
#bind 192.168.34.100:443 ssl crt /etc/ssl/certs/example.com.pem
bind 192.168.34.100:80
maxconn 30000
default_backend ju_sso
backend ju_sso
mode http
# 強制https
#redirect scheme https if !{ ssl_fc }
# 強制的に/openam以下にリダイレクト
# acl has_openam_uri path_beg -i /openam
# redirect location https://am-proxy.example.com/openam if !has_openam_uri
cookie SERVERID insert nocache
balance roundrobin
server s1 192.168.34.10:8080 maxconn 30000 cookie 01 id 1001 check inter 2000 rise 2 fall 5
server s2 192.168.34.11:8080 maxconn 30000 cookie 02 id 1002 check inter 2000 rise 2 fall 5
option forwardfor
frontend ldap_in
bind 192.168.34.100:3389
maxconn 10000
default_backend ju_ldap
backend ju_ldap
mode tcp
balance roundrobin
server s1 192.168.34.10:389 maxconn 10000 check
server s2 192.168.34.11:389 maxconn 10000 check
listen stats :8181
mode http
stats enable
stats realm Haproxy\ Statistics
stats uri /
stats auth haproxy:ju
バックエンドのポートと受け付けるポートが同じだとalready listenになるので別ポートにする。
server s1 192.168.34.10:8080 maxconn 30000 cookie 01 id 1001 check inter 2000 rise 2 fall 5
stickysessionの設定。同一cookieは同じバックエンドに割り振る。
standby側はnon_local_ipにもbind出来るようにカーネルパラメータを変えて対応。master側もやっておく。
sysctl -w net.ipv4.ip_nonlocal_bind=1
- 管理ツールのhatopを入れておく
wget http://hatop.googlecode.com/files/hatop-0.7.7.tar.gz
tar xvf hatop-0.7.7.tar.gz
cd hatop-0.7.7
install -m 755 bin/hatop /usr/local/bin
install -m 644 man/hatop.1 /usr/local/share/man/man1
- テスト
hatop -s /var/run/haproxy/haproxy.sock
keepalived
- インストール
yum install keepalived
- keepalived.confの設定
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_script chk_haproxy {
script "killall -0 haproxy" # verify the pid existance
interval 2 # check every 2 seconds
weight 2 # add 2 points of prio if OK
}
vrrp_instance VI_1 {
interface eth1 # interface to monitor
state MASTER
virtual_router_id 51 # Assign one ID for this route
priority 100 # 101 on master, 100 on backup
virtual_ipaddress {
192.168.34.100 # the virtual IP
}
track_script {
chk_haproxy
}
}
priority
はアクティブ側を101、バックアップ側を100とする。
Openstack上に構築する場合
sysctl -w net.ipv4.ip_nonlocal_bind=1
を実行しカーネルパラメータを変える。これをやらないと同時に同じIPが複数立ち上がる。
OpenDJ
- Ansibleのインストール
yum install --enablerepo=epel ansible
- OpenDJ用roleのダウンロード
ansible-galaxy install warren.strange.opendj
- playbook作成
- hosts: localhost
connection: local
roles:
- warren.strange.opendj
- playbook実行
ansible-playbook opendj.yaml
-
ホスト名設定
-
1台目
hostname openam.example.com sed -i -e "s/^HOSTNAME=.*/HOSTNAME=openam.example.com/g" /etc/sysconfig/network echo "192.168.34.10 openam.example.com" >> /etc/hosts echo "192.168.34.11 openam2.example.com" >> /etc/hosts echo "192.168.34.100 openam-proxy.example.com" >> /etc/hosts
-
2台目
hostname openam2.example.com sed -i -e "s/^HOSTNAME=.*/HOSTNAME=openam2.example.com/g" /etc/sysconfig/network echo "192.168.34.10 openam.example.com" >> /etc/hosts echo "192.168.34.11 openam2.example.com" >> /etc/hosts echo "192.168.34.100 openam-proxy.example.com" >> /etc/hosts
-
-
レプリケーション設定
/opt/opendj/bin/dsreplication
どの処理を実行しますか?
1) レプリケーションを有効にする
2) レプリケーションを無効にする
3) 1 台のサーバーでレプリケーションを初期化
4) すべてのサーバーを初期化
5) 外部初期化前
6) 外部初期化後
7) レプリケーションの状態を表示
8) Purge Historical
c) 取消し
選択肢: 1
>>>> 最初のサーバーのサーバー管理接続パラメータを指定します
ディレクトリサーバーのホスト名または IP アドレス [openam.example.com]: [Enter]
ディレクトリサーバーの管理ポート番号 [4444]: [Enter]
グローバル管理者のユーザー ID、またはグローバル管理者が定義されていない場合はバインド DN [admin]: cn=Directory Manager
ユーザー 'cn=Directory Manager' のパスワード: [password]
最初のサーバーのレプリケーションポート (未使用のポート) [8989]: [Enter]
最初のサーバーのレプリケーションポート 8989 への接続時に、暗号化された通信を使ってレプリケーションしますか ? (yes / no) [no]: [Enter]
>>>> 2 番目のサーバーのサーバー管理接続パラメータを指定します
ディレクトリサーバーのホスト名または IP アドレス [openam.example.com]: openam2.example.com
ディレクトリサーバーの管理ポート番号 [4444]: [Enter]
グローバル管理者のユーザー ID、またはグローバル管理者が定義されていない場合はバインド DN [admin]: cn=Directory Manager
ユーザー 'cn=Directory Manager' のパスワード: [password]
サーバー証明書:
ユーザー DN: CN=localhost, O=Administration Connector Self-Signed Certificate
有効期間: 'Fri Oct 03 05:18:27 UTC 2014' から
'Thu Sep 28 05:18:27 UTC 2034' まで
発行者: CN=localhost, O=Administration Connector Self-Signed Certificate
このサーバー証明書を信頼しますか ?
1) いいえ
2) はい、このセッションでのみ信頼します
3) はい、トラストストアにも追加します
4) 証明書の詳細を表示します
選択肢 [2]: 2
2 番目のサーバーのレプリケーションポート (未使用のポート) [8989]: [Enter]
2 番目のサーバーのレプリケーションポート 8989 への接続時に、暗号化された通信を使ってレプリケーションしますか ? (yes / no) [no]: [Enter]
グローバル管理者を作成する必要があります。
レプリケート中のサーバーインスタンスの管理用に作成するグローバル管理者の資格を指定してください。
グローバル管理者のユーザー ID [admin]: [Enter]
グローバル管理者のパスワード: [password]
パスワードの確認: [password]
レプリケートするベース DN を 1 つ以上選択してください。
ベース DN dc=example,dc=com をレプリケートしますか ? (yes / no) [yes]: [Enter]
ベース DN dc=openam,dc=forgerock,dc=org をレプリケートしますか ? (yes / no) [yes]: [Enter]
接続を確立しています ..... 完了。
登録情報を確認しています ..... 完了。
サーバー openam.example.com:4444 上のレプリケーションポートを構成しています ..... 完了。
サーバー openam2.example.com:4444 上のレプリケーションポートを構成しています ..... 完了。
サーバー openam.example.com:4444 上のベース DN dc=example,dc=com のレプリケーション構成を更新しています ..... 完了。
サーバー openam2.example.com:4444 上のベース DN dc=example,dc=com のレプリケーション構成を更新しています ..... 完了。
サーバー openam.example.com:4444 上のベース DN dc=openam,dc=forgerock,dc=org のレプリケーション構成を更新しています ..... 完了。
サーバー openam2.example.com:4444 上のベース DN dc=openam,dc=forgerock,dc=org のレプリケーション構成を更新しています ..... 完了。
サーバー openam.example.com:4444 上の登録構成を更新しています ..... 完了。
サーバー openam2.example.com:4444 上の登録構成を更新しています ..... 完了。
サーバー openam.example.com:4444 上のベース DN cn=schema のレプリケーション構成を更新しています ..... 完了。
サーバー openam2.example.com:4444 上のベース DN cn=schema のレプリケーション構成を更新しています ..... 完了。
サーバー openam2.example.com:4444 上の登録情報を、サーバー openam.example.com:4444 のコンテンツで初期化しています ..... 完了。
サーバー openam2.example.com:4444 上のスキーマを、サーバー openam.example.com:4444 のコンテンツで初期化しています ..... 完了。
レプリケーションが正常に有効になりました。 レプリケーションが機能するには、レプリケートするベース DN のコンテンツを初期化する必要があります (dsreplication initialize を使用して初期化)。
この操作の詳細なログについては /tmp/opendj-replication-4237327164984323237.log を参照してください。
OpenAM
1台目と2台目で微妙にインストール時の手順が異なるので注意。
1台目
-
公式サイトよりOpenAMのwarファイルをダウンロード。
-
依存パッケージのインストール
yum install java-1.6.0-openjdk
yum install tomcat6 tomcat6-webapps tomcat6-admin-webapps
tomcat7の場合はmanagerのアップロード容量制限があるのでwebから上げる場合は制限をゆるくする
vi /usr/share/tomcat/webapps/manager/WEB-INF/web.xml
<max-file-size>52428800</max-file-size>
<max-request-size>52428800</max-request-size>
- hostnameの設定
※ここと後述のOpenAM設定のhostnameが一致していないとエラーでインストール出来ないので注意。
$ cat /etc/sysconfig/networkk
openam-test.example.com
- SELinuxをDisabled
cat /etc/sysconfig/selinux
SELINUX=disabled
- tomcatのmanagerユーザ追加
vim /etc/tomcat6/tomcat-users.xml
# 以下を追加
<role rolename="manager"/>
<user username="admin" password="password" roles="manager"/>
- 設定ファイルの書き込みが出来るようにする。
chown -R root:tomcat /usr/share/tomcat6
-
example.com:8080にアクセス。
-
カスタム設定から設定をしていく
-
デフォルトユーザ
pass: password -
ポリシーエージェント
pass: agentpassword
設定ストアの詳細 編集...
SSL が有効
ホスト名
待機ポート
ルートサフィックス
ユーザー名
ディレクトリ名 いいえ
localhost
50389
dc=example,dc=com
cn=Directory Manager
/usr/share/tomcat6/OpenAM-11.0.0
ユーザーストアの詳細 編集...
SSL が有効
ホスト名
openam-proxy.example.com
待機ポート
3389
ルートサフィックス
dc=example,dc=com
ユーザー名
cn=Directory Manager
ユーザーデータストアタイプ いいえ
172.16.42.120
ポート
389
dc=example,dc=com
cn=Directory Manager
OpenDJ
サイト設定の詳細 編集...
このインスタンスは、ロードバランサの背後には設定されません。
設定ストアはOpenAMでユーザデータストアはOpenDJにする。OpenDJのホストとポートはロードバランサのホストとポートにする。
エラーが出たら設定用のフォルダが既に出来ているので一度削除してから再度入れなおす
2台目
1台目と途中までは同じで「既存の配備に追加する」を選択する。
既存の配備に追加で既に存在するOpenAMのURLを入力する。
サイト名: test
ロードバランサのURL: http://openam-proxy.example.com:80/openam
自動的に設定が埋まるので「次へ」を押す。
サイト名、ロードバランサのURLを入力しインストールを進める。ここで失敗が間違っていてもログイン後「設定」→「サーバーおよびサイト」より設定を直せるので問題ない。
インストールが終了したら各インスタンスへログインし「設定」→「サーバーおよびサイト」より親サイトの箇所が空欄になっているホストの親ホストを設定したサイトに変更する。
検証
HAProxyが落ちた場合
# 落とす前のip
openam1 $ ip -f inet a
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
inet 192.168.34.10/24 brd 192.168.34.255 scope global eth1
inet 192.168.34.100/32 scope global eth1
# HAProxyを落としてみる
openam1 $ service haproxy stop
# VIPがfailoverされているのが分かる
openam1 $ ip -f inet a
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
inet 192.168.34.10/24 brd 192.168.34.255 scope global eth1
openam2 $ ip -f inet a
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
inet 192.168.34.11/24 brd 192.168.34.255 scope global eth1
inet 192.168.34.100/32 scope global eth1
VIPはスタンバイ側に引き継がれる。
# 再度HAProxyを起動させると元に戻る。
openam1 $ service haproxy start
openam1 $ ip -f inet a
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
inet 192.168.34.10/24 brd 192.168.34.255 scope global eth1
inet 192.168.34.100/32 scope global eth1
OpenDJが落ちた場合
# 手動で停止
service opendj stop
- OpenAMにアクセス。ー>問題なし。
- OpenAMでユーザ情報に変更を加えるー>問題なし。
- ユーザ情報変更後落ちていた方のOpenDJを起動。
# レプリケーション状態確認
$ /opt/opendj/bin/dsreplication status -h localhost -p 4444 -I admin -w password -X
Suffix DN : Server : Entries : Replication enabled : DS ID : RS ID : RS Port (1) : M.C. (2) : A.O.M.C. (3) : Security (4)
------------------------------:--------------------------:---------:---------------------:-------:-------:-------------:----------:--------------:-------------
dc=example,dc=com : openam.example.com:4444 : 26 : true : 29535 : 29036 : 8989 : 0 : : false
dc=example,dc=com : openam2.example.com:4444 : 22 : true : 4242 : 16196 : 8989 : 1 : : false
dc=openam,dc=forgerock,dc=org : openam.example.com:4444 : 0 : true : 10822 : 29036 : 8989 : 0 : : false
dc=openam,dc=forgerock,dc=org : openam2.example.com:4444 : 0 : true : 24071 : 16196 : 8989 : 0 : : false
[1] The port used to communicate between the servers whose contents are being replicated.
[2] The number of changes that are still missing on this server (and that have been applied to at least one of the other servers).
[3] Age of oldest missing change: the date on which the oldest change that has not arrived on this server was generated.
[4] Whether the replication communication through the replication port is encrypted or not.
落ちていた方がM.C(Missed Change)が溜まっているのが分かる。
-
レプリケーションは勝手には始まらない。
-
起動直後は差分が発生している。ー> OpenAMからユーザ一覧を見ると更新後の値が常に表示される。
-
更新ログが進んでいる方のLDAPに常にクエリ(更新も参照も)が行くようになる。
-
dsreplicationで遅れている方を進んでいるサーバで初期化
/opt/opendj/bin/dsreplication initialize -h openam.example.com -p 4444 -O openam2.example.com --portDestination 4444 -X -I admin -w password
-
ログが追いついた。
-
再度OpenAM上からユーザ情報更新 ー> 同期されているのでマルチマスタ状態でどちらを更新しても同期される。
-
結論: OpenDJが落ちたら進んでる方のデータで初期化させる
OpenAMが落ちた場合
# 手動で落とす
service tomcat6 stop
- ロードバランサにアクセス -> 問題なし。
# 再起動
service tomcat6 start
-
バランシング確認 -> 問題なし。
-
停止中に片側で設定変更した場合dsreplicationの初期化が必要な気がする。
ホストが落ちた場合
- リクエストが全て片側に寄る
- ホスト再起動後全てのサービスを起動で問題なし
Session Failoverさせる
設定
「設定」-> 「グローバル」 -> 「セッション」より作成済みのサイトに対してSession Failoverを設定する。
Session Failover手順
- バランサから外す
- Session Failoverが有効になっていれば同期されているCTSを参照してSessionがFailoverされる
トークンはOpenAM内蔵のコンフィグ用のOpenDJディレクトリのRoot DNのou=tokens
以下に格納されている。