IBM Cloud: VPCのNetwork Load Balancer(NLB) とALB(Application Load Balancer)を比較してみた

# 1. はじめに
IBM CloudのVPC環境で従来提供されていたVPC Load BalancerにL4レベルでのトラフィックを割り振るNLB(Network Load Balancer)が提供開始されました。
これにより、従来のVPC Load Balancer(proxyタイプ）はALB(Application Load Balancer)と呼ばれることになりました。この記事では、ALBとNLBの違いおよびNLBを実際に動かした結果について説明したいと思います。

こちらも参考に。
https://cloud.ibm.com/docs/vpc?topic=vpc-nlb-vs-elb&interface=ui&locale=en

## 2023/10/25 追記
NLBでSecurity Groupがサポートされるようになりました。
https://cloud.ibm.com/docs/vpc?topic=vpc-release-notes&locale=en
https://cloud.ibm.com/docs/vpc?topic=vpc-nlb-integration-with-security-groups&locale=en

## 2022/7/1 追記
NLBが同一Zone内のサーバーだけでなく、同一リージョン内の別Zoneのサーバーにも割り振り可能になりました。
（ただし、[route mode](https://qiita.com/testnin2/items/d4897b3d292282a25aae)は依然としてNLBと同一Zoneである必要があります）

## 2022/4/1 追記
- CLIだけでなくUIからも、ALBで任意のIPアドレスをBackend Poolに追加できるようになりました（ヘルスチェックも当然実施されます。FQDN指定はできません）。
- [NLBでUDPがサポートされるようになりました。](https://cloud.ibm.com/docs/vpc?topic=vpc-nlb-udp&interface=ui&locale=en)

## 2022/3/1 追記

- [public NLBでListner Portを範囲で指定できるようになりました。](https://cloud.ibm.com/docs/vpc?topic=vpc-nlb-port-ranges&interface=ui&locale=en)

## 2021/3/30 追記

- [privateタイプのNLBがサポートされるようになりました。](https://cloud.ibm.com/docs/vpc?topic=vpc-release-notes#march-25-2021&locale=en)

## 2021/3/1 追記

- [ALBにSecurity Group機能が追加されました。](https://cloud.ibm.com/docs/vpc?topic=vpc-alb-integration-with-security-groups&locale=en#alb-traffic)



# 2. ALBとNLBの比較
ALBとNLBの比較は、公式docsとしては[ここ](https://cloud.ibm.com/docs/vpc?topic=vpc-nlb-vs-elb&locale=en)に記載がありますが、もう少し私なりの解説と補足を入れて比較表を記載したいと思います。

|  | NLB(Network Load Balancer)| ALB(Application Load Balancer) |
|:-----------|:-----------|:------------|
| トランスポートレイヤー  | Layer-4   | Layer-4, Layer-7   ||
| サポートされるプロトコル| TCP, UDP  | TCP, HTTP, HTTPS ||
| ネットワーク構成| Direct Server Return(DSR)方式<br><br>- Client -> NLB -> Server -> Clientという通信。<br><br>- ClientからNLB宛のパケットは、NLBでServer宛のアドレスに変換されてされてServerに届く。ServerからはNLBを経由せずに直接Clientに返る（パケットがServerから戻る際には、HypervisorでSource IPがNLBのIPに置き換えられる）。<br> - ClientとServerの間でTCPのセッションが張られる。|Reverse Proxy方式<br><br>- Client -> ALB -> Server -> ALB -> Clientという通信。<br><br> - いったんClientとALBでTCPのセッションが張られたあと、別途ALBとServer間でTCPセッションが張られる。そのため、サーバーからは必ずALBにいったん戻される。<br>|
| パケットレベルでのClient IPの保存 |保存される（NLBではL4レベルでDNATしかしていない） 。| （Serverから見た接続元はあくまでALBなので）保存されないが、代替策あり。<br><br>HTTP/HTTPS通信であれば、ALBでHTTPヘッダの"X-Forwarded-For"にClient IPを含んでいるので、この情報で接続元を確認できる。<br>TCPアクセスの場合でも、バックエンドサーバーがProxy Protocolに対応していればClient IPを取得可能。 https://cloud.ibm.com/docs/vpc?topic=vpc-advanced-traffic-management&locale=en#proxy-protocol-enablement|
|アクセス制御| NLB自身にもSecurity Groupが実装されるようになった。クライアントのSource IPが保持されたままサーバーにパケットが到達するため、NLBもしくはサーバーのSecurity Groupで制御することが可能（2023/10/25)。|ALBのNetwork ACL/Security Groupを利用するか、サーバー側で制御(X-Forwaded-ForやProxy Protocolで取得したIPアドレスをアプリ側で制御）する。|
| SSL offload | できない（SSL通信が必要であれば、サーバー側でSSL処理をする必要がある）  | できる(Frotnend ListenerがHTTPSの場合） |
| アクセス方式| FQDNもしくはIPアドレス<br><br>FQDNの名前解決先IPアドレスは一意に決まるので、必ずしもFQDNでアクセスする必要もない。| FQDN<br><br>複数のALBインスタンスが作成され、負荷や障害に応じてIPアドレスが変わるため、IPアドレスベースでのアクセスは推奨されない。|
|Listener ポートおよびBackend ポート|public NLB: 単一ポート（バックエンドポートには別のポートを利用可能）もしくは、範囲で指定可能（バックエンドポートにはそのまま同じ範囲のポートが使用される）。<br> private NLB: 単一ポート（バックエンドポートには別のポートを利用可能）|単一ポートでのみ指定可能（バックエンドポートには別のポートを利用可能）。|
| HAの実現方式| １つのVIPをActive/Standbyで保護する。  | 複数のALBインスタンスがActive/Activeで稼働（利用されるIアドレスPも複数） |
| MZRサポート | NLBインスタンスは単一Zoneに作成される。MZRで構成したい場合は、ZoneごとにNLBを作成した後に、NLBに割り振るGlobal Load Balancerが必要。     | ALBインスタンスは複数のZoneにまたがって作成される。 |
|Front-end listenerにおけるL7ポリシー制御|不可（そもそもHTTP/HTTPSが使えないので）|可能(HTTP/HTTPSの場合）|
| Back-end poolで指定可能なターゲットのサーバー| 同一リージョン内の複数ZoneのVSIや物理サーバーに割り振り可能。ただし、（ターゲットサーバーが複数interfaceを持っていたとしても）primary interfaceにしか割り振れない。<br><br>CLI(ibmcloud is load-balancer-pool-member-create)では、ターゲットのインスタンスIDを指定する(IPアドレスを指定するのではない）。そのため、CLIでもターゲットとして同一VPC内のサーバーしか指定できない。これは、上述の通りNLBがDSRを実現する上で、戻りのパケットのSource IPをHypervisor上でNLBのIPに置き換える必要があるためであり、任意のアドレスを指定させてしまうとこのような実装を実現できないからだと思われる。| 同一Region内の複数ZoneのVSIおよび任意のIPアドレス（例えば物理サーバーや、Direct Link先にあるPowre Systems Virtual Serverや、Transit Gatewayの先のリソース）に対して割り振り可能。 |
|割り振りポリシー|Least Connections/Round robin/Weighted round robin|Least Connections/Round robin/Weighted round robin|
| Back-end poolのヘルスチェック| TCP/HTTP| TCP/HTTP/HTTPS |
|Session Stickiness|可能(Source IP)|可能(Source IP, [HTTP Cookie, APP Cookie](https://qiita.com/testnin2/items/1b35b26f3ba431c4eb8a))|
| load balancerの種類 | Public/Private | Public/Private |
| Sysdigによるモニタリング| 可能     | 可能      |
|AutoScale連携|不可|可能|


# 3. 注文方法
特定のZoneおよびsubnetを指定しているのが特徴です。ALBと違って複数Zoneにまたがって配置されることはありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/b5bb2790-415b-84b0-79f2-72f9935fe0fa.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/5fdce8c4-d007-a95b-8bdc-09f7842d4c1e.png)

# 4. 設定
ALBと大差ないので、特に悩むところはないと思います。

## 4-1. Backend-pools(NLB -> Serverの部分を設定）
- ヘルスチェック自体はTCPもHTTPも選択できる。
- 別Zoneのサーバーは選択できなかった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/1b9e63ab-f5ae-a85d-44d3-940ef1b67d4a.png)

## 4-2. Front-end Listener(Client -> NLBの部分を設定）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/af2b371e-d27f-5e13-189f-707a7bbeb9d1.png)

## 4-3. Security Group
往々に忘れてしまうところですが、サーバーにとっての通信元はALBの場合にはALBインスタンス（つまりVPC内で定義したPrivate IP)ですが、NLBの場合はSource IPが保持されるためクライアントのIPになります。よって、クライアントからのアクセスを受けれるようにSecurity Groupで解放しておく必要があります。

# 5. テスト

```
$ curl -I  http://xxxxx.lb.appdomain.cloud:8081
HTTP/1.1 200 OK
Date: Tue, 01 Sep 2020 07:03:39 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips
Last-Modified: Sun, 30 Aug 2020 11:26:42 GMT
ETag: "153-5ae168f69f628"
Accept-Ranges: bytes
Content-Length: 339
Content-Type: text/html; charset=UTF-8
```