IBM Cloud: private-only環境のROKS(Red Hat OpenShift on IBM Cloud)にClient-to-Server VPNを使ってアクセスする方法

#1. はじめに

IBM CloudのROKS(Red Hat OpenShift on IBM Cloud)におけるprivate only環境は、API endpointなどがVPC内部からしかアクセスできないように構成されており、Web ConsoleやocコマンドもInternet上から直接実行できない。
本記事では、そもそもどういう通信要件があるのかを改めて確認した上で、Clinet-to-Server VPNでの設定方法をまとめてみた。

#2. 通信要件まとめ

IBM CloudのROKS(Red Hat OpenShift on IBM Cloud)におけるprivate only環境は、API endpointなどがVPC内部からしかアクセスできないように構成されておりInternetから直接アクセスできない。
確かにこの構成はSecureなのだが、実際に利用しようとすると非常に面倒である。特にOpenShiftのWeb Consoleについては、以下の３つにWeb Consoleがアクセスする端末は同時にアクセスできないといけないという条件があるからである。

##2.1  Web ConsoleのURLに割り当てられているURL

- Web Consoleアクセスの時に必要。
- VPC内部のユーザー定義のsubnetから割り当てられる。
- インターネットからは直接アクセスできない(Private IPなので）。
- 対象IPアドレスには、VPC提供のVPNサービス経由でもDirect Link経由でもVPC内部からでもアクセス可能。
- FQDNの名前解決は、端末がインターネット上のドメインの名前解決できれば問題なし。


```shell:OpenShiftのWebConsole用URLの取得
$ oc whoami --show-console
https://console-openshift-console.privonly-syasuda-roksvpc-c82dcc5867b41450588f49284670f9a8-i000.jp-tok.containers.appdomain.cloud

$ host console-openshift-console.privonly-syasuda-roksvpc-c82dcc5867b41450588f49284670f9a8-i000.jp-tok.containers.appdomain.cloud
console-openshift-console.privonly-syasuda-roksvpc-c82dcc5867b41450588f49284670f9a8-i000.jp-tok.containers.appdomain.cloud is an alias for privonly-syasuda-roksvpc-c82dcc5867b41450588f49284670f9a8-i000.jp-tok.containers.appdomain.cloud.
privonly-syasuda-roksvpc-c82dcc5867b41450588f49284670f9a8-i000.jp-tok.containers.appdomain.cloud is an alias for 30202eed-jp-tok.lb.appdomain.cloud.
30202eed-jp-tok.lb.appdomain.cloud has address 10.0.0.8
30202eed-jp-tok.lb.appdomain.cloud has address 10.1.0.5
```

##2.2  API EndpointおよびOauth認証用のendpointに割り当てられるURL

- Web Consoleアクセスの時も、ocコマンドでのアクセス時にも必要。
- `166.8.0.0/14`などの[IBM Cloud管理のサービス用subnet](https://cloud.ibm.com/docs/vpc?topic=vpc-build-se-connectivity-using-vpn)から割り当てられる。
- インターネットからは直接アクセスできない(Private endpointなので）。
- **Direct Link経由でも直接はアクセスできない。**
- **ポート番号が30000-32767のいずれかである（クラスターをデプロイするまで割り当てられる番号はわからない）。**
- 対象IPアドレスには、VPC提供のVPNサービス経由もしくはVPC内部からアクセスする必要がある。(VPC内部にNATサーバーを構築するとかProxyを構築するのも代替手段）。
- FQDNの名前解決は、端末がインターネット上のドメインの名前解決できれば問題なし。

```shell:APIEndpoint用URL
$ oc whoami --show-server
https://c100.private.jp-tok.containers.cloud.ibm.com:31811
```

```shell:OAuth認証用のURLを取得
$ curl -sk -X GET -H "X-Csrf-Token: 1" $(oc whoami --show-server)/.well-known/oauth-authorization-server | jq -r '.issuer'
https://c100-e.private.jp-tok.containers.cloud.ibm.com:30701
```

```shell:IPアドレスの確認
$ host c100-e.private.jp-tok.containers.cloud.ibm.com
c100-e.private.jp-tok.containers.cloud.ibm.com is an alias for c100.private.jp-tok.containers.cloud.ibm.com.
c100.private.jp-tok.containers.cloud.ibm.com is an alias for prod-jp-tok-tugboat1.jp-tok.serviceendpoint.cloud.ibm.com.
prod-jp-tok-tugboat1.jp-tok.serviceendpoint.cloud.ibm.com has address 166.9.44.16
prod-jp-tok-tugboat1.jp-tok.serviceendpoint.cloud.ibm.com has address 166.9.40.22
prod-jp-tok-tugboat1.jp-tok.serviceendpoint.cloud.ibm.com has address 166.9.42.24
```


```shell:ocコマンド実施時のアクセス例
$ oc login -u apikey -p <API Key> --loglevel=10 2>&1 | grep curl
I0922 14:47:28.179203    7604 round_trippers.go:423] curl -k -v -XHEAD  'https://c100.private.jp-tok.containers.cloud.ibm.com:31811/'
I0922 14:47:28.248909    7604 round_trippers.go:423] curl -k -v -XHEAD  'https://c100.private.jp-tok.containers.cloud.ibm.com:31811/'
I0922 14:47:28.293115    7604 round_trippers.go:423] curl -k -v -XGET  -H "X-Csrf-Token: 1" 'https://c100.private.jp-tok.containers.cloud.ibm.com:31811/.well-known/oauth-authorization-server'
I0922 14:47:28.371399    7604 round_trippers.go:423] curl -k -v -XGET  -H "X-Csrf-Token: 1" 'https://c100-e.private.jp-tok.containers.cloud.ibm.com:30701/oauth/authorize?client_id=openshift-challenging-client&code_challenge=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&code_challenge_method=S256&redirect_uri=https%3A%2F%2Fc100-e.private.jp-tok.containers.cloud.ibm.com%3A30701%2Foauth%2Ftoken%2Fimplicit&response_type=code'
I0922 14:47:28.449470    7604 round_trippers.go:423] curl -k -v -XGET  -H "Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -H "X-Csrf-Token: 1" 'https://c100-e.private.jp-tok.containers.cloud.ibm.com:30701/oauth/authorize?client_id=openshift-challenging-client&code_challenge=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&code_challenge_method=S256&redirect_uri=https%3A%2F%2Fc100-e.private.jp-tok.containers.cloud.ibm.com%3A30701%2Foauth%2Ftoken%2Fimplicit&response_type=code'
I0922 14:47:30.300030    7604 round_trippers.go:423] curl -k -v -XPOST  -H "Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -H "Content-Type: application/x-www-form-urlencoded" -H "Accept: application/json" 'https://c100-e.private.jp-tok.containers.cloud.ibm.com:30701/oauth/token'
I0922 14:47:30.583034    7604 round_trippers.go:423] curl -k -v -XGET  -H "Accept: application/json, */*" -H "User-Agent: oc/4.6.0 (linux/amd64) kubernetes/c3dc785" -H "Authorization: Bearer sha256~xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 'https://c100.private.jp-tok.containers.cloud.ibm.com:31811/apis/user.openshift.io/v1/users/~'
I0922 14:47:30.663199    7604 round_trippers.go:423] curl -k -v -XGET  -H "Accept: application/json, */*" -H "User-Agent: oc/4.6.0 (linux/amd64) kubernetes/c3dc785" -H "Authorization: Bearer sha256~xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 'https://c100.private.jp-tok.containers.cloud.ibm.com:31811/apis/project.openshift.io/v1/projects'
I0922 14:47:30.726508    7604 round_trippers.go:423] curl -k -v -XGET  -H "Accept: application/json, */*" -H "User-Agent: oc/4.6.0 (linux/amd64) kubernetes/c3dc785" -H "Authorization: Bearer sha256~xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 'https://c100.private.jp-tok.containers.cloud.ibm.com:31811/apis/project.openshift.io/v1/projects/syasuda1'
I0922 14:47:30.781911    7604 round_trippers.go:423] curl -k -v -XGET  -H "Accept: application/json, */*" -H "User-Agent: oc/4.6.0 (linux/amd64) kubernetes/c3dc785" -H "Authorization: Bearer sha256~xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 'https://c100.private.jp-tok.containers.cloud.ibm.com:31811/api/v1/namespaces/openshift/configmaps/motd'
```



##2.3 IAMの認証のためのURLなど

- WebConsoleを利用してアクセスする時に必要。

`https://iam.cloud.ibm.com`
`https://identity-2.ap-north.iam.cloud.ibm.com`
`https://login.ibm.com`
など（SSO認証などをしている場合は、他にもアクセスが必要になる）

インターネットに接続できる必要がある。

#3. Client-to-Server VPNを利用した接続方法

VPCのClient-to-Server VPNで通信できれば、2.1および2.2の問題はVPN経由で通信することで解決できる。2.3については、端末がInternetにアクセスできれば問題ない。


1. Client-to-Server VPNの設定をする。セットアップ方法は[こちらの記事](https://qiita.com/y_tama/items/16987e07842262cd9068)を参照。
2. `VPN Server routes`で以下のように構成する。

- Web Console用のURLのIPアドレスが配置されるsubnetを追加（下図では`vpc-tok1`や`vpc-tok2`)。Actionは`Deliver`でも`Translate`でもどちらでも良い。
- Cloud Service Endpointsへのsubnetを追加（下図では`cloudservieendpoints`）。このActionは必ず`Translate`にすること。
- （オプション:今回の構成では必須ではない）IaaS Endpointsへのsubnetを追加。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/ba953ae3-0fb5-4ac7-f004-be4315f04edc.png)


これでVPNを接続したあと、web console用URLに接続すれば、ROKSのweb consoleにアクセスできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/1093232a-67e4-4f7b-43aa-bdd69d9a9010.png)