IBM Cloud: ALBとVPEを使ってICOSにDirect Link経由でアクセスする方法

#1. はじめに

オンプレミスやPower Systems Virtual ServerからIBM Cloud上のICOS(IBM Cloud Object Storage)にDirect Link経由でアクセスしたいという需要は多くあります。しかし、ICOSはIBM Cloud上のサービスネットワーク上に存在し、そのサービスネットワークへの経路はBGPでオンプレミスやPower Systems Virtual Serverに広告されません。結果、Reverse Proxyで中継することでICOSにアクセスを行う方法が挙げられていました。ただし、このやり方はProxy Serverを利用者自身で構築・運用する必要があります。

:::note warn
Service Networkにアクセスするために、Reverse Proxyを構築する代わりにNATを利用することも可能です。ただし、ICOSのIPアドレスが明示的に公開されているわけではないので、IPアドレスが変更された場合にNATの設定も変更する必要があるという考慮点があります。
:::

https://cloud.ibm.com/docs/direct-link?topic=direct-link-using-ibm-cloud-direct-link-to-connect-to-ibm-cloud-object-storage
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/fe19d879-ce1d-f7c3-04d9-d368d0f2d3f8.png)


VPCには、IBM CloudのサービスをVPC内部の自身のIPアドレス経由で利用可能とするVPE(Virtual Private Endpoint)という機能があります。VPC内部のIPアドレスであれば、Direct Link経由で直接アクセス出来そうなものですが、残念ながら本記事執筆時点ではVPEにはDirect Link経由で直接アクセスできないという制限が存在します（近い将来改善予定です）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/414b43db-35a6-4cf5-8ff5-a0d45995d23c.png)

ただし、VPEの前段にALB(Application Load Balancer)を配置し、ALBの割り振り先としてVPEを選択すればICOSにアクセスすることが可能になります。本記事ではこのやり方をStep by Stepで検証したいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/ad3d058f-b3a8-25a7-0ab6-b93130ad3f2c.png)

:::note warn
VPCにアクセスする必要があるため、Direct Link 2.0が必要になります。またALBはデータ転送量に応じて課金が発生するため、データ量によっては従来のReverse Proxy形式の方が安価になる可能性があります。
https://www.ibm.com/cloud/vpc/pricing


また、ALB自身の性能がボトルネックになる可能性があります。ALBにはHorizontal scalingの機能がありますが、1つのICOS Clientで利用できるALBのIPは１つのままでしょうから、別端末からアクセスしない限りはHorizontal scalingは性能向上には寄与しないでしょう。
:::


参考情報
https://cloud.ibm.com/docs/vpc?topic=vpc-end-to-end-private-connectivity&interface=cli


#2. 前提

- VPC及び、VPE用のsubnetやALB用のsubnetを作成済みであること。
    - １つのsubnetで構成することも可能ですが、複数に分けておくことでSecurity Groupを個別に設定することができます。
- ICOSが既にセットアップされており、bucket作成済みであること。
- Direct Link 2.0でオンプレミスもしくはPower Systems Virtual ServerがVPCと接続されていること。本記事では、Power Systems Virtual Server(AIX)を利用。
- ICOSにアクセスするクライアントツールが導入・設定済みであること（今回はawscliを利用）
    - AIXへのawscliの導入方法は（既にpython2がdeprecatedなので）python3を導入してvenvを構成する[こちら](https://qiita.com/testnin2/items/5fe4f97f3a3a748f10ea#%E5%8F%82%E8%80%83-python3%E5%8F%8A%E3%81%B3awscli%E3%81%AE%E5%B0%8E%E5%85%A5%E4%BE%8B)を参考。
    - python2.7系での導入方法は[こちら](https://qiita.com/khayama/items/5bd9101c32f2d3381291#aws-cli)にも記載あり。


#3. ICOSに対するVPEを作成

- Create<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/96f9b176-1a65-a2a5-d797-9035e842afb0.png)
- 名前およびリージョンを選択<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/0d883c95-66b5-4707-f4ef-df4d7c59790e.png)
- Direct Link接続済みでVPEを作成するVPC、Cloud Object Storage、及び適切なendpointを指定。今回は東京リージョンのRegionalのICOSを指定したいため、`s3.direct.jp-tok.cloud-object-storage.appdomain.cloud`を指定する。<br> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/3897a30a-5e18-606f-11ca-db2e9079601e.png)

:::note
s3.direct.jp-tok.cloud-object-storage.appdomain.cloudがRegional環境でのTokyo用Endpointです。
s3.direct.tok.ap.cloud-object-storage.appdomain.cloudはCross Region環境でのTokyo用Endpointです。紛らわしいですが、間違って選択しないようにしましょう。
:::

- Reserved IP(=VPEに割り当てられるIPアドレス）の作成 <br> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/a0b58343-af0e-6803-6efd-de44f972f1ef.png)


これで作成すると、VPEアドレスとして、10.1.0.11が割り当てられました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/95e277c1-e69e-b42c-5cc2-de0ca23f4ff1.png)


#4. VPEに対するアクセス確認(VPC内のVSIから）

- `--endpoint-url`によってEndpointを明示的に指定する。
- `--no-verify-ssl`を使うことで証明書の検証をSkipする。

```shell:バケット一覧の取得
(python368) [root@myvpc ~]# aws --endpoint-url https://10.1.0.11 --no-verify-ssl s3 ls
/root/python368/lib64/python3.6/site-packages/urllib3/connectionpool.py:1020: InsecureRequestWarning: Unverified HTTPS request is being made to host '10.1.0.11'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
2019-04-11 13:14:02 mybucket104
2019-06-27 09:00:19 mybucket105
2019-10-02 11:39:06 mybucket106
2020-06-20 15:49:17 mybucket107
```

```shell:bucket内のファイル一覧を取得
(python368) [root@myvpc ~]# aws --endpoint-url https://10.1.0.11 --no-verify-ssl s3 ls mybucket105
/root/python368/lib64/python3.6/site-packages/urllib3/connectionpool.py:1020: InsecureRequestWarning: Unverified HTTPS request is being made to host '10.1.0.11'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
2021-09-03 09:03:41     196283 test.txt
```


#5. ALB(Application Load Balancer)の作成
- Create <br> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/3724f542-d879-1ce3-478a-1a3312f949fa.png)
- Application Load Balancerを選択 <br> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/98672f8b-f62c-4023-9140-64efc6dfc0a9.png)
- 対象のリージョン、VPCを選択。Direct Linkからのアクセスなので、`Private`タイプを選択。<br> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/490ce91e-0244-8175-8a9d-77a6243b83c2.png)
- Backend poolの作成。Protocolは`TCP`を選択。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/f87b9177-31de-b876-6282-c87c30f0b2ce.png)


Back-end poolのメンバーはUIからはVPEを指定できません。また、Front-end listenersは後で作成するので、これで注文します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/a2668f16-9366-313a-983a-72838416be48.png)


#6. ALBにBackend MemberとしてVPEを登録


```shell:ロードバランサー一覧を取得
$ ibmcloud is load-balancers
Listing load balancers in all resource groups and region jp-tok under account xxx as user xxxxxxx@xx.xxx.xxx...
ID                                          Name                                                         Family        Subnets                                                   Is public   Provision status   Operating status   Resource group
r022-21e91dc6-62f5-44db-979c-cace0d1819ce   alb-icos-tokyo-regional                                      Application   sub-10-5-0-0-24                                           false       active             online             Default
（以下省略）
```

```shell:対象のロードバランサーに存在するbackendpoolを取得
$ ibmcloud is load-balancer-pools r022-21e91dc6-62f5-44db-979c-cace0d1819ce
Listing pools of load balancer r022-21e91dc6-62f5-44db-979c-cace0d1819ce under account xxx as user xxxxxxx@xx.xxx.xxx...
ID                                          Name       Algorithm     Protocol   Type   Provision status   Instance group   Proxy protocol
r022-5b328f49-4982-4dc5-b083-f62f4fecabde   icospool   round_robin   tcp        -      active             -                disabled
```

```shell:backendpoolにVPE(今回は10.1.0.11）のアドレスを登録
$ ibmcloud is load-balancer-pool-member-create r022-21e91dc6-62f5-44db-979c-cace0d1819ce r022-5b328f49-4982-4dc5-b083-f62f4fecabde 443 10.1.0.11 --weight 60
Creating member of pool r022-5b328f49-4982-4dc5-b083-f62f4fecabde under account xxx as user xxxxxxx@xx.xxx.xxx...

ID                 r022-862ff4c5-8627-4f30-810c-4923c1762c40
Port               443
Target             10.1.0.11
Weight             60
Health             unknown
Created            2021-09-02T10:43:38.484+09:00
Provision status   create_pending
```


backend poolのメンバーへのVPEの登録はCLI/API経由でしか行えませんが、登録されたVPE自体はCustomer Portalからも確認できます。しばらく待っていると、Health Statusも`Passing`になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/d733f6b5-9622-26de-08d3-e3f14ca4e47d.png)



#7. ALBにFrontend Listenerを作成

- Protocolは`TCP`で登録する。<br> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/af175272-0bcf-43e5-cb5e-aa7712e08ddc.png)

これで全ての作業は完了です。

#8. ALBに対するアクセス確認(VPC内のVSIから）

```shell:バケット一覧の取得
(python368) [root@myvpc ~]# aws --endpoint-url https://21e91dc6-jp-tok.lb.appdomain.cloud --no-verify-ssl s3 ls
/root/python368/lib64/python3.6/site-packages/urllib3/connectionpool.py:1020: InsecureRequestWarning: Unverified HTTPS request is being made to host '21e91dc6-jp-tok.lb.appdomain.cloud'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
2019-04-11 13:14:02 mybucket104
2019-06-27 09:00:19 mybucket105
2019-10-02 11:39:06 mybucket106
2020-06-20 15:49:17 mybucket107
```

```shell:bucket内のファイル一覧を取得
(python368) [root@myvpc ~]# aws --endpoint-url https://21e91dc6-jp-tok.lb.appdomain.cloud --no-verify-ssl s3 ls mybucket105
/root/python368/lib64/python3.6/site-packages/urllib3/connectionpool.py:1020: InsecureRequestWarning: Unverified HTTPS request is being made to host '21e91dc6-jp-tok.lb.appdomain.cloud'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
2021-09-03 09:03:41     196283 test.txt
```

#9. Direct Link越しでテスト

今回は、Power Systems Virtual Server上のAIXからアクセスします。

```shell:バケット一覧の取得
(python3710) # oslevel
7.2.0.0

(python3710) # aws --endpoint-url https://21e91dc6-jp-tok.lb.appdomain.cloud --no-verify-ssl s3 ls
/python3710/lib64/python3.7/site-packages/urllib3/connectionpool.py:1020: InsecureRequestWarning: Unverified HTTPS request is being made to host '21e91dc6-jp-tok.lb.appdomain.cloud'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
2019-04-11 13:14:02 mybucket104
2019-06-27 09:00:19 mybucket105
2019-10-02 11:39:06 mybucket106
2020-06-20 15:49:17 mybucket107
```

```shell:bucket内のファイル一覧を取得
(python3710) # aws --endpoint-url https://21e91dc6-jp-tok.lb.appdomain.cloud --no-verify-ssl s3 ls mybucket105
/python3710/lib64/python3.7/site-packages/urllib3/connectionpool.py:1020: InsecureRequestWarning: Unverified HTTPS request is being made to host '21e91dc6-jp-tok.lb.appdomain.cloud'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
2021-09-03 09:03:41     196283 test.txt
```

#10. おまけ（FQDNのカスタマイズ）
DNSでCNAMEの構成をしておけば、好きなFQDNでICOSにアクセスできる。
例えば、`mydomain.local`というドメインを所有しており、`icos.mydomain.local` -> `21e91dc6-jp-tok.lb.appdomain.cloud`となるようなCNAME設定をしておけば、以下のように自分の所持しているドメイン配下のFQDNでICOSにアクセス可能になる。


```shell:バケット一覧の取得
(python3710) # aws --endpoint-url https://icos.mydomain.local --no-verify-ssl s3 ls
/python3710/lib64/python3.7/site-packages/urllib3/connectionpool.py:1020: InsecureRequestWarning: Unverified HTTPS request is being made to host 'icos.mydomain.local'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
2019-04-11 13:14:02 mybucket104
2019-06-27 09:00:19 mybucket105
2019-10-02 11:39:06 mybucket106
2020-06-20 15:49:17 mybucket107
```

```shell:bucket内のファイル一覧を取得
(python3710) # aws --endpoint-url https://icos.mydomain.local --no-verify-ssl s3 ls mybucket105
/python3710/lib64/python3.7/site-packages/urllib3/connectionpool.py:1020: InsecureRequestWarning: Unverified HTTPS request is being made to host 'icos.mydomain.local'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
  InsecureRequestWarning,
2021-09-03 09:03:41     196283 test.txt
```