IBM Cloud: VPCのVirtual Private Endpoint機能について試してみた

#1. はじめに

IBM Cloudのサービスは、Public endpointとPrivate endpointを持ちます。Virtual Private Endpoints (VPE) とは、

1. 指定したVPCからのみ
2. Private endpointへ
3. VPC内で定義されるPrivate IPを使って

アクセスするための機能です。
https://cloud.ibm.com/docs/vpc?topic=vpc-about-vpe&locale=en

従来もClassic InfrastructureやVPCからPrivate endpointにアクセスする機能（Service endpoint）自体は提供されていました。しかし、Private NWに接続可能な環境からはどこからでもアクセス可能であり、そのIPアドレスは`161.26.x.x`や`166.9.x.x`などの共通のアドレス帯が利用されていました。これらの制約を取り除かれたものがVPEだと言えるでしょう。
https://qiita.com/testnin2/items/b3f3a112cb21ad8c07e9
https://cloud.ibm.com/docs/vpc?topic=vpc-service-endpoints-for-vpc#cloud-service-endpoints
https://cloud.ibm.com/docs/account?topic=account-vrf-service-endpoint#use-service-endpoint

#2. 仕組みと制約

- VPEの構成要素
    - Endpoint Gateway: 一般的にサービスインスタンスごとに作成される。仮想化されており、負荷に応じて水平方向にスケールする。VPC内の全てのAZにまたがって構成されており、冗長化されている。https://cloud.ibm.com/docs/vpc?topic=vpc-about-vpe&locale=en
    - Reserved IP: 各サービスインスタンスにアクセスするためのIPアドレスとしてVPC内のNWから予約・構成されるIPアドレス。このIPアドレスは別Zoneからもアクセスもできるので単一Zoneのみに作成することも可能だが、各ZoneごとにReserved IPを構成するのがBest Practiceのようだ。https://cloud.ibm.com/docs/vpc?topic=vpc-about-vpe#vpe-connectivity&locale=en <br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/269eccec-df3e-3659-ed95-5e2f9f9f94f9.png)
- 利用可能なIBM Cloudのサービス一覧は以下の通り（どのサービスもVPEに対応できているわけではない） <br> https://cloud.ibm.com/docs/vpc?topic=vpc-vpe-supported-services&locale=en
- VPEに対するSecurity Groupを使ったアクセス制御はできない。サーバー側のSecurity Groupを利用するか、Network ACLを使った制御は可能。VPEを使うのであれば、Service Endpoint経由で直接アクセスしないように、Network ACLでOutboundをブロックすることがセキュリティーの観点からは推奨。
- Reserved IPのIPアドレスを明示的に指定して作成することはできない。
- 1つのendpoint gatewayには、１つのAZにつき１つのReserved IPしか割り当てられない。
- 同じサーバーから同時にVPEおよびService Endpointを使ってIBM Cloudのサービスにアクセスすることはサポートしない（セッションとかの問題があるから？）https://cloud.ibm.com/docs/vpc?topic=vpc-planning-considerations&locale=en


#3. NTPサービスのVPEを注文してみる

- VPCより`Virtual private endpoint gateways`を選択<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/c7b31aca-7a7f-34a4-fdb2-d34471522b4f.png)
- `Create`を選択<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/3f5805a8-c302-1dd0-3dbf-1fe2affcc632.png)
- VPE Gatewayの名称などを選択<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/d0f82d44-0a99-f203-e7cc-3a0f16e11895.png)
- NTPを選択。NTPはどこのリージョンからも利用できるGlobal Service扱い。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/0708bab7-9484-dd22-9de2-e0d1b8765c40.png)

- 初めてサービスを作成するときにはReserved IPは存在していないので、`Select one for me`から新規に作成する。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/dcd6f33f-2743-7d4f-c4bf-cc1123261881.png)
- VPE Gatewayが作成された<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/49d00739-6f06-e3e0-7e7a-7019ebc1fdcc.png)
- 詳細画面を見ると、Reserved IPが作成されている。別ZoneのReserved IPを作成したい場合は、この画面から追加可能。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/d85cd44f-0ab1-42cd-0d7c-53b58e46ab70.png)
- Tokyo2に対してReserved IPを追加。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/251ab534-a438-97ee-b28e-25ec3c501619.png)
- 最終的にTokyo1/Tokyo2/Tokyo3にReserved IPを作成した結果。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/afcc63f2-5cf4-0571-6cdc-6bfe595929ec.png)

#4. テスト

##4.1 VPEのReserved IPにping

```txt:VSI@tokyo1からReservedIP@tokyo1へのping
[root@syasuda-tok1-vpc1 ~]# ping 10.0.0.16 -c 3
PING 10.0.0.16 (10.0.0.16) 56(84) bytes of data.
64 bytes from 10.0.0.16: icmp_seq=1 ttl=62 time=0.282 ms
64 bytes from 10.0.0.16: icmp_seq=2 ttl=62 time=0.300 ms
64 bytes from 10.0.0.16: icmp_seq=3 ttl=62 time=0.254 ms

--- 10.0.0.16 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.254/0.278/0.300/0.027 ms
```

```txt:VSI@tokyo1からReservedIP@tokyo2へのping
[root@syasuda-tok1-vpc1 ~]# ping 10.1.0.36 -c 3
PING 10.1.0.36 (10.1.0.36) 56(84) bytes of data.
64 bytes from 10.1.0.36: icmp_seq=1 ttl=62 time=0.288 ms
64 bytes from 10.1.0.36: icmp_seq=2 ttl=62 time=0.314 ms
64 bytes from 10.1.0.36: icmp_seq=3 ttl=62 time=0.297 ms

--- 10.1.0.36 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.288/0.299/0.314/0.022 ms
```


```txt:VSI@tokyo1からReservedIP@tokyo3へのping
[root@syasuda-tok1-vpc1 ~]# ping 10.2.0.9 -c 3
PING 10.2.0.9 (10.2.0.9) 56(84) bytes of data.
64 bytes from 10.2.0.9: icmp_seq=1 ttl=62 time=0.252 ms
64 bytes from 10.2.0.9: icmp_seq=2 ttl=62 time=0.292 ms
64 bytes from 10.2.0.9: icmp_seq=3 ttl=62 time=0.245 ms

--- 10.2.0.9 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.245/0.263/0.292/0.020 ms
```

別Zoneに割り当てたReserved IPなのにpingの応答が速い！？（本来だったら、別Zoneへのpingならば、1.7msecぐらいかかっているはずだが・・・）。
想像だが、

- Tokyo1 -> Tokyo2 -> VPE Gateway(10.1.0.36)
- Tokyo1 -> Tokyo3 -> VPE Gateway(10.2.0.9)

という迂回をしてVPE Gatewayにアクセスしているのではなく、

- Tokyo1 -> VPE Gateway(10.0.0.16, 10.1.0.36, 10.2.0.9)

とVPE Gatewayへの優先経路を利用してアクセスしているように見える。


##4.2 VPEのReserved IPを使ってNTPを構成

[このやり方](https://qiita.com/testnin2/items/93fc0fe085ac252d977c)に従って実際に設定してみる。

Classic InfrastructureにおけるNTPのendpointアドレスは

- 10.0.77.54(Classic Infrastructure): servertime.service.softlayer.com/time.service.softlayer.com/time.service.networklayer.com 
- 161.26.0.6(Service Endpoint) time.adn.networklayer.com/mirrors.adn.networklayer.com

だったが、VPEでは10.0.0.16, 10.1.0.36, 10.2.0.9などが使えるようになっているはず。

```
[root@webapp1-tok1-8x2hoq6oid-htiyf ~]# timedatectl
      Local time: 月 2020-11-09 04:44:16 JST
  Universal time: 日 2020-11-08 19:44:16 UTC
        RTC time: 日 2020-11-08 19:45:44
       Time zone: Asia/Tokyo (JST, +0900)
     NTP enabled: yes
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a

[root@webapp1-tok1-8x2hoq6oid-htiyf ~]# chronyc sources
210 Number of sources = 1
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^* 10.0.0.16                     3   6    17    53    +18us[+4329ns] +/-  144ms
```