読む前にこの記事のポイントを音声で確認できます。この音声は本記事をもとにAIツール(NotebookLM)で自動生成したもので、発音や言い回しが不自然な箇所や、内容の誤りが含まれる可能性があります。理解の補助としてご利用ください。
ロードバランシング方式(ラウンドロビンや比率など)は、クライアントからの初回アクセスをどのサーバに送るかを決めるものです。2回目以降も同じサーバに送り続けたいときに使うのが、パーシステンス(セッション維持)です。この記事では、よく使われる送信元 IP アドレスと Cookie(HTTP Cookie Insert)のパーシステンスを設定し、動作を確かめます。
- 送信元 IP アドレスパーシステンスのプロファイルを作る(Timeout を 300 秒に)
- プロファイルを Virtual Server に適用する
- パーシステンスのレコードと Timeout の動きを確かめる
- Cookie パーシステンス(HTTP Cookie Insert)のプロファイルを作る
- Virtual Server に適用し、挿入された Cookie を確かめる
この記事は、次の記事で作った Web-VS(Virtual Server)と Web-Pool(Web-01:80、Web-02:80)の構成を使います。
BIG-IP 16.1.2 で検証しています。16.1 系はすでに F5 のサポート期間が終わっているので、これから構築する場合はサポート中のバージョンを選んでください。
パーシステンスとは
ラウンドロビンだけで振り分けると、同じクライアントからのアクセスでも、来るたびに別のサーバに送られることがあります。パーシステンスを使うと、初回アクセスで決まったサーバに、同じクライアントからの2回目以降のアクセスも送り続けます。
処理の負荷を分けるだけで、どのサーバが応答しても困らないアプリケーションなら、パーシステンスはいりません。一方、EC サイトのカートのように、ログイン状態や入力途中のデータをサーバ側で持っているアプリケーションでは、一連の処理を同じサーバで受ける必要があるので、パーシステンスを使います。
「同じクライアント」をどう見分けるかで、パーシステンスの種類が分かれます。
| 種類 | 同じクライアントの見分け方 | 記録する場所 | 使える通信 |
|---|---|---|---|
| 送信元 IP アドレス (Source Address Affinity) | 送信元 IP アドレスが同じ | BIG-IP のパーシステンステーブル | TCP/UDP の通信全般 |
| Cookie (HTTP Cookie Insert) | BIG-IP が応答に入れた Cookie の値 | クライアントのブラウザ(Cookie) | HTTP(HTTPS は BIG-IP で復号する場合) |
送信元 IP アドレスパーシステンス
送信元 IP アドレスが同じなら同じクライアントと見なし、振り分け先のサーバを固定します。設定は、Persistence のプロファイルを作り、Virtual Server に適用する流れです。
プロファイルを作る
Local Traffic ›› Profiles ›› Persistence を開くと、プロファイルの一覧が表示されます。最初から用意されているプロファイルのうち、Type が Source Address Affinity の source_addr が送信元 IP アドレスパーシステンスです。
この記事の画面は、実際の画面ではなく、検証時の画面から設定する項目(見るポイント)を抜き出して描いたイメージです。バージョンによって、項目の並びや表記は変わります。
| Name | Type | Parent Profile | Partition / Path |
|---|---|---|---|
| cookie | Cookie | (none) | Common |
| dest_addr | Destination Address Affinity | (none) | Common |
| hash | Hash | (none) | Common |
| host | Host | (none) | Common |
| msrdp | Microsoft® Remote Desktop | (none) | Common |
| sip_info | SIP | (none) | Common |
| 1source_addr | Source Address Affinity | (none) | Common |
| ssl | SSL | (none) | Common |
| universal | Universal | (none) | Common |
| No. | 項目 | 内容 |
|---|---|---|
| 1 | source_addr | 最初から用意されている送信元 IP アドレスパーシステンスのプロファイル。そのまま使っても動作します |
| 2 | Create… | 新しいプロファイルを作ります(実際の画面では一覧の右上にあります) |
ここでは、Timeout を変えたプロファイルを新しく作ります。Create をクリックし、Name に custom-src-persist、Persistence Type に Source Address Affinity を選ぶと、親プロファイル(Parent Profile)が source_addr の設定画面に切り替わります。この時点の値は source_addr と同じです。値を変えたい項目は、右端の Custom にチェックを入れると編集できるようになります。
よく変えるのは Timeout です。初期値は 180 秒で、その間に同じクライアントからの通信がないと、パーシステンスの記録が消えます。EC サイトなどで、利用者が180秒以上操作しないと別のサーバに振り分けられてしまうので、必要に応じて長くします。ここでは 300 秒(5分)にして、Finished をクリックします。
| 1Name | custom-src-persist |
| Persistence Type | Source Address Affinity |
| Parent Profile | source_addr |
| Match Across Services | ☐ |
| Match Across Virtual Servers | ☐ |
| Match Across Pools | ☐ |
| Hash Algorithm | Default |
| 2Timeout | Specify… 300 seconds |
| Prefix Length | None |
| Map Proxies | ☑ Enabled |
| Override Connection Limit | ☐ |
| No. | 項目 | 設定内容 |
|---|---|---|
| 1 | Name/Persistence Type | custom-src-persist/Source Address Affinity |
| 2 | Timeout | 300 秒(初期値 180 秒)。Custom にチェックを入れてから変更します |
| 3 | Finished | クリックしてプロファイルを作ります。一覧に custom-src-persist(Parent Profile が source_addr)が追加されます |
Virtual Server に適用する
Local Traffic ›› Virtual Servers ›› Virtual Server List で Web-VS をクリックし、Properties タブから Resources タブに切り替えます。Default Persistence Profile で custom-src-persist を選び、Update をクリックします。
| Default Pool | Web-Pool |
| 1Default Persistence Profile | custom-src-persist |
| Fallback Persistence Profile | None |
| No. | 項目 | 設定内容 |
|---|---|---|
| 1 | Default Persistence Profile | custom-src-persist を選びます |
| 2 | Update | クリックして反映します |
動作を確かめる
クライアントのブラウザで Virtual Server(http://www.hirotanoblog.work)を開くと、Web-01 のページが表示されます。何回再読み込みしても Web-01 のままです。
クライアントから curl で10回続けてページのタイトルを取ると、10回とも Web-01 でした。同じ送信元アドレスからのアクセスが、すべて Web-01 に送られています。
クライアント
$ for ((i=0; i<10; i++)); do curl -s www.hirotanoblog.work | grep -o '<title>.*</title>'
| sed 's#<title>\(.*\)</title>#\1#'; done
Web-01 – Web-01
Web-01 – Web-01
Web-01 – Web-01
Web-01 – Web-01
Web-01 – Web-01
Web-01 – Web-01
Web-01 – Web-01
Web-01 – Web-01
Web-01 – Web-01
Web-01 – Web-01
パーシステンスのレコード(show ltm persistence persist-records)
BIG-IP では、show ltm persistence persist-records all-properties でパーシステンスの記録(レコード)を確認できます。クライアントのアドレスは伏せています。
BIG-IP(tmsh)
(tmos)# show ltm persistence persist-records all-properties Sys::Persistent Connections source-address - 10.0.1.100:80 - 10.0.2.24:80 --------------------------------------------- TMM 0 Mode source-address Value 126.xxx.xxx.xxx Age (sec.) 1 Virtual Name /Common/Web-VS Virtual Addr 10.0.1.100:80 Node Addr 10.0.2.24:80 Pool Name /Common/Web-Pool Client Addr 126.xxx.xxx.xxx Owner entry not mirrored
| 表示 | 意味 |
|---|---|
| Mode | パーシステンスの種類。source-address は送信元 IP アドレスパーシステンス |
| Value | 同じクライアントを見分けるキー。ここではクライアントの送信元 IP アドレス |
| Age (sec.) | このレコードが最後に使われてからの経過秒数。Timeout(300 秒)に達するとレコードが消えます |
| Virtual Addr | クライアントが接続した Virtual Server のアドレスとポート |
| Node Addr | 固定した振り分け先(Web-01 の 10.0.2.24:80) |
| Pool Name | 振り分け先の Pool |
| Client Addr | 接続しているクライアントのアドレス |
Timeout でレコードが消える
Age は、同じクライアントから通信があるたびに 0 に戻ります。通信がない間は1秒ずつ増え、Timeout に設定した 300 秒に達するとレコードが消えます。次の出力では、Age が 298、299 と増えたあと、レコードが 0 件になっています。レコードが消えた後のアクセスは、ロードバランシング方式で改めて振り分け先が決まります。
(tmos)# show ltm persistence persist-records all-properties Sys::Persistent Connections source-address - 10.0.1.100:80 - 10.0.2.24:80 --------------------------------------------- TMM 0 Mode source-address Value 126.xxx.xxx.xxx Age (sec.) 298 Virtual Name /Common/Web-VS Virtual Addr 10.0.1.100:80 Node Addr 10.0.2.24:80 Pool Name /Common/Web-Pool Client Addr 126.xxx.xxx.xxx Owner entry not mirrored Total records returned: 1 (tmos)# show ltm persistence persist-records all-properties Sys::Persistent Connections source-address - 10.0.1.100:80 - 10.0.2.24:80 --------------------------------------------- TMM 0 Mode source-address Value 126.xxx.xxx.xxx Age (sec.) 299 Virtual Name /Common/Web-VS Virtual Addr 10.0.1.100:80 Node Addr 10.0.2.24:80 Pool Name /Common/Web-Pool Client Addr 126.xxx.xxx.xxx Owner entry not mirrored Total records returned: 1 (tmos)# show ltm persistence persist-records all-properties Sys::Persistent Connections Total records returned: 0 (tmos)# show ltm persistence persist-records all-properties Sys::Persistent Connections Total records returned: 0
Cookie パーシステンス
Cookie を使って同じクライアントを見分けます。初回アクセスのとき、BIG-IP がサーバからの HTTP レスポンスに Cookie を挿入し、クライアントは2回目以降のリクエストでその Cookie を送ります。BIG-IP は Cookie の値から、初回と同じサーバに転送します。
BIG-IP が HTTP の中身を読み書きするので、使えるのは HTTP の通信だけです。Virtual Server には HTTP プロファイルを適用しておく必要があります。HTTPS の場合は、BIG-IP で SSL を復号する(Client SSL プロファイルを適用する)構成のときに使えます。
プロファイルを作る
送信元 IP アドレスと同じく、Local Traffic ›› Profiles ›› Persistence で Create をクリックします。最初から用意されている cookie(Type が Cookie)をそのまま使っても動作しますが、ここでは Name を custom-cookie、Persistence Type を Cookie にして新しく作ります。
Cookie Method の初期値 HTTP Cookie Insert が、いちばんよく使われる方式です。サーバが Cookie を使っているかどうかに関係なく、BIG-IP が独自の Cookie を HTTP レスポンスに挿入します。今回は値を変えずに Finished をクリックします。
| 1Name | custom-cookie |
| Persistence Type | Cookie |
| Parent Profile | cookie |
| 2Cookie Method | HTTP Cookie Insert |
| Cookie Name | |
| HTTPOnly Attribute | Enabled |
| Secure Attribute | Enabled |
| Always Send Cookie | ☐ |
| Default Cookie Encrypt Pool-Name | ☐ |
| Expiration | ☑ Session Cookie |
| 3Cookie Encryption Use Policy | disabled |
| Encryption Passphrase | |
| Override Connection Limit | ☐ |
| No. | 項目 | 設定内容 |
|---|---|---|
| 1 | Name/Persistence Type | custom-cookie/Cookie |
| 2 | Cookie Method | HTTP Cookie Insert(初期値のまま) |
| 3 | Cookie Encryption Use Policy | この画面では disabled。Cookie の値を暗号化するかどうかの設定です(後述) |
| 4 | Finished | クリックしてプロファイルを作ります |
Virtual Server に適用して確かめる
STEP 2 と同じく Web-VS の Resources タブを開き、Default Persistence Profile で custom-cookie を選んで Update をクリックします。
| Default Pool | Web-Pool |
| 1Default Persistence Profile | custom-cookie |
| Fallback Persistence Profile | None |
ブラウザ(Chrome)で Virtual Server を開くと、今度は Web-02 のページが表示されました。何回再読み込みしても Web-02 のままです。
ブラウザに保存された Cookie
Chrome の 設定 ›› セキュリティとプライバシー ›› Cookie と他のサイトデータ ›› すべての Cookie とサイトデータを表示 で www.hirotanoblog.work の Cookie を見ると、BIG-IP が挿入した Cookie が保存されています。
| 1名前 | BIGipServerWeb-Pool |
| 2コンテンツ | 1191313418.20480.0000 |
| ドメイン | www.hirotanoblog.work |
| パス | / |
| 送信先 | 同一サイトの接続のみ |
| スクリプトにアクセス可能 | いいえ(HTTP のみ) |
| 作成日 | 2022年3月27日日曜日 18:47:38 |
| 3有効期限 | ブラウザ セッションの終了時 |
| No. | 表示 | 意味 |
|---|---|---|
| 1 | 名前 | BIGipServer のあとに Pool 名(Web-Pool)が続く名前。Cookie Name を空欄にしたときの名前です |
| 2 | コンテンツ | 振り分け先のサーバを表す値(読み方は下で説明します) |
| 3 | 有効期限 | Expiration が Session Cookie なので、ブラウザを閉じると消えます |
curl で Set-Cookie を確かめる
curl -I でレスポンスヘッダを見ると、Set-Cookie で Cookie が挿入されていることがわかります。
クライアント
$ curl -I www.hirotanoblog.work
HTTP/1.1 200 OK
Date: Sun, 27 Mar 2022 11:00:19 GMT
Server: Apache
Link: ; rel="https://api.w.org/"
Content-Type: text/html; charset=UTF-8
Set-Cookie: BIGipServerWeb-Pool=1191313418.20480.0000; path=/; Httponly
暗号化していない Cookie の値は、振り分け先の IP アドレスとポートを数値にしたものです。次のように読み解くと、Web-02(10.0.2.71:80)を指していることがわかります。
| 値 | 読み方 | 結果 |
|---|---|---|
| 1191313418 | 16進数にすると 0x4702000A。下位のバイトから順に 0A・00・02・47 と読み、10進数に直す | 10.0.2.71 |
| 20480 | 16進数にすると 0x5000。上下のバイトを入れ替えると 0x0050 | 80 |
暗号化していない Cookie からは、サーバの内部の IP アドレスとポートが読み取れます。外部に公開するサービスでは、Cookie Encryption Use Policy で Cookie の暗号化を検討してください。
STEP 3 のように curl を続けて実行しても、curl は受け取った Cookie を次のリクエストで送らないので、Cookie パーシステンスは効きません(毎回ロードバランシング方式で振り分けられます)。Cookie パーシステンスはブラウザで確かめるか、curl の Cookie を保存・送信するオプションを使って確かめます。
うまくいかないとき
| 状態 | よくある原因 | 確認すること |
|---|---|---|
| 送信元 IP で特定のサーバに偏る | NAT やプロキシの後ろにいる多くのクライアントが、同じ送信元アドレスで来ている | show ltm persistence persist-records の Value。偏りが問題なら Cookie パーシステンスを検討する |
| しばらくすると別のサーバに変わる | Timeout を過ぎてレコードが消えた | プロファイルの Timeout。アプリケーションのセッションの長さに合わせる |
| Cookie のプロファイルを適用できない | Virtual Server に HTTP プロファイルがない | Virtual Server の HTTP Profile の設定 |
| Cookie が挿入されない | HTTPS を BIG-IP で復号していない、またはテスト方法が Cookie を送っていない | Client SSL プロファイルの有無、curl -I の Set-Cookie |
まとめ
| 項目 | 送信元 IP アドレス | Cookie(HTTP Cookie Insert) |
|---|---|---|
| Persistence Type | Source Address Affinity | Cookie |
| 既定のプロファイル | source_addr | cookie |
| この記事のプロファイル | custom-src-persist(Timeout 300 秒) | custom-cookie(初期値のまま) |
| 見分け方 | 送信元 IP アドレス | BIGipServer<Pool 名> の Cookie |
| 確認方法 | show ltm persistence persist-records | ブラウザの Cookie、curl -I の Set-Cookie |
| 注意点 | NAT 配下のクライアントは同じサーバに集まる | HTTP プロファイルが必要。値の暗号化を検討 |
どちらも Persistence プロファイルを作り、Virtual Server の Resources タブにある Default Persistence Profile に指定するだけで動きます。
コメント