はじめに
L4とL7のロードバランサーの違いを説明できるようになるために学習したことをまとめます。
クラウドにも以下のようなサービスが展開されていることはご存じの人も多いでしょう。
これらのサービスの違いを説明できるようになるためのベースとなる知識を付けていきます。
-
Azure
-
AWS
今回は一般的なL4とL7のロードバランサーを理解したの後、Nginxで実際に実装してみます。
ロードバランサーとは?
- 負荷分散装置
- 受診したトラフィックを複数のサーバーに振り分ける(サーバーダウンを防ぐ)
- ダウンしたサーバーには振り分けない(死活監視的な機能)
参考図:https://www.ntt.com/bizon/glossary/j-r/load-balancer.html
より詳細を知りたい方は以下を参照。
OSI基本参照モデル
そもそもL4とL7とは何なのか考えましょう。
OSI参照モデルとは、コンピュータ間通信を行う際に必要とされる機能を整理したものです。 1977年3月にISO(国際標準化機構)の委員会が設置され、策定が始まりました。 当時コンピュータ間通信はメーカー独自仕様が乱立していて、 互いに通信することが難しかったため、 標準的なネットワークとしてOSI(Open Systems Interconnection)を作成する気運が高まりました。 そこで開発に先立って必要な機能を整理するため、OSI参照モデルが策定されたというわけです。 最終的にISO 7498(*1)として規格化されています。
引用:https://www.nic.ad.jp/ja/basics/terms/osi.html
特徴としては、以下のように機能を7階層に整理したことです。
参考図:https://www.itmanage.co.jp/column/osi-reference-model/
1~4層を下位層、5~7層を上位層と呼び、下位層はシステム側に近い機能、上位層は人間に近い機能を規定しています。
L4とL7というのは、OSI基本参照モデルの4層(トランスポート層)、7層(アプリケーション層)を指します。
L4(トランスポート層)の役割は、
ノード間の通信制御に関して規定しています。
送信元から送られたデータは様々な機器を経由して宛先に届き、経由している中でデータが欠けてしまうと宛先でデータを正しく処理をできなくなってしまいます。
そのようなことにならないように、データが欠けることなく届けるといった通信の信頼性に関する機能が提供されています。
引用:https://qiita.com/nakamura_slj/items/0c827de1dab6ebc722d2
L7(アプリケーション層)の役割は、
ユーザーが利用するアプリケーション間での通信に関して規定をしています。
WebブラウザであればWeb用のプロトコルとなり、ユーザーが利用するアプリケーションで使用するプロトコルが規定されます。
引用:https://qiita.com/nakamura_slj/items/0c827de1dab6ebc722d2
L4とL7のロードバランサーの違い
OSI基本参照モデルを踏まえて、結局どのように振分けを行うのかというと、
-
L4ロードバランサーの特徴
- IPアドレスやポートを利用して振り分ける(レイヤー4の負荷分散)
-
L7ロードバランサーの特徴
- URLパスやHTTPヘッダーを利用して振り分ける(レイヤー7の負荷分散)
また、Nginxの記事も引用しておく。
レイヤー4ロードバランシングは、中間のトランスポートレイヤーで動作します。このレイヤーは、メッセージの内容に関係なくメッセージのデリバリーを処理します。TCP(Transmission Control Protocol)は、インターネット上のHTTP(Hypertext Transfer Protocol)トラフィック向けのレイヤー4プロトコルです。レイヤー4のロードバランサーは、パケットの内容は検査せず、上流のサーバとの間で単純にネットワークパケットの転送を実行します。また、TCPストリームの最初の数パケットを検査し、限定的にルーティングを決定できます。
レイヤー7ロードバランシングは、さらに上位のアプリケーションレイヤーで動作します。このレイヤーでは、各メッセージの実際の内容が処理されます。HTTPは、インターネット上のWebサイトのトラフィックに使用される主要なレイヤー7プロトコルです。レイヤー7のロードバランサーは、レイヤー4のロードバランサーに比べて、はるかに高度な方法でネットワークトラフィックをルーティングします。特に、HTTPなどのTCPベースのトラフィックを対象とします。レイヤー7のロードバランサーは、ネットワークトラフィックを終端し、中のメッセージを読み取ります。メッセージの内容(URLやCookieなど)に基づいて、ロードバランシングの判断を行うことができます。続いて、選択した上流サーバに新しいTCP接続を実行(または、HTTPキープアライブによって既存の接続を再利用)して、サーバにリクエストを書き込みます。
引用:https://www.nginx.co.jp/resources/glossary/layer-7-load-balancing/
要するに。。
トランスポート層はTCP/UDPプロトコルが使われていて、これらはクライアントとサーバー間での通信チャネル(ポート)の提供、通信管理を行う。したがって、L4ロードバランサーはポートで振分けができるようになっている。
また、IPアドレスによる振り分けは3層のネットワーク層のIPプロトコルから取得して実現しているとのこと。
アプリケーション層の特徴は、HTTPプロトコルが使われており、URL、Cookie、HTTPヘッダーなどが取得できる。したがって、L7のロードバランサーではメッセージの内容(URLやCookie)に基づいて、負荷分散することができる。
クラウドサービスを振り返る
最初に述べたクラウドのロードバランサーを振り返ると、
-
Azure
- Azure Load Balancer ⇒ L4
- Azure Application Gatewy ⇒ L7
-
AWS
に対応します。
ロードバランサーを体験する
NginxによるL4ロードバランサーの実装
services:
lb:
container_name: lb
hostname: lb
image: nginx:latest
ports:
- '80:80'
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
web1:
container_name: web1
hostname: web1
image: nginx:latest
volumes:
- ./html/web1.html:/usr/share/nginx/html/index.html
web2:
container_name: web2
hostname: web2
image: nginx:latest
volumes:
- ./html/web2.html:/usr/share/nginx/html/index.html
web3:
container_name: web3
hostname: web3
image: nginx:latest
volumes:
- ./html/web3.html:/usr/share/nginx/html/index.html
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
stream {
upstream backend {
# コンテナサービス名を指定
server web1:80;
server web2:80;
server web3:80;
}
server {
# リッスンポート
listen 80;
proxy_pass backend;
# allow {許可IP};
# deny all;
}
}
web1
web2
web3
コンテナ構築後、以下を実行する。
for i in `seq 1 20` ; do
curl http://localhost/
done
振り分けられていることが分かる。
web3
web1
web2
web3
web1
web2
web3
web1
web2
web3
web1
web2
web3
web1
web2
web2
web3
web1
web2
web3
NginxによるL7ロードバランサーの実装
compose.yaml
は上記と同様。nginx.conf
を以下に書き換える。
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
upstream backend {
server web1:80;
server web2:80;
server web3:80;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}
コンテナ実行後、アクセス確認を行う。
for i in `seq 1 20` ; do
curl http://localhost/
done
メッセージが均等に表示されたらOK。
参考