Red Hat OpenShift on IBM Cloud on VPCへのプライベート接続を検証してみた（検証編）

# 目的

過去記事「[Red Hat OpenShift on IBM Cloud on VPCへのプライベート接続方式を検証してみた（設定編）](https://qiita.com/teruq/items/ab85f9443a9594ce34a0)」の続きで、今回は実際に各種オンプレ相当の環境からのアプリケーションへの接続性を検証してみます。

オンプレ相当環境からの接続は、現時点では次の方式が考えられます。

1. Transitゲートウェイ
1. VPNゲートウェイ
1. SSL-VPN（OpenVPN on 仮想サーバ）
1. ~~Direct Link（専用線）~~

Direct Linkは残念ながら気軽に試せる環境がないため実施しません。他の方式について、環境上の考慮点も合わせて検証したいと思います。

# Transitゲートウェイ

TransitゲートウェイはIBM Cloud内でVPC間やVPCとクラシックインフラストラクチャーを相互接続する機能です。クラシックインフラストラクチャーの仮想サーバからROKSのアプリケーションにアクセスします。

## 構成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/5598c592-e6ee-ece5-14f5-5eb3550fed06.png)

## ポイント

NodePort以外のプライベートアクセスでは、結局のところVPCのプライベートロードバランサーを使うことになります。ロードバランサーはマルチゾーンで冗長化されているため、IPアドレスではなくFQDNでアクセスする必要があります。クライアントはDNSを参照し、DNSラウンドロビンで使用するVPCロードバランサーを選定します。IBM Cloudの仮想サーバであれば通常はDNSを参照できますので特に問題はないでしょう。

VPCロードバランサーからワーカーノード#3に線が伸びていませんが、これは過去記事を参照ください。気持ち悪い場合は直すこともできます。

> [Red Hat OpenShift on IBM Cloud on VPCで3台以上のノード構成時にロードバランサーのヘルスチェックに失敗するノードがある場合がある件への対応](https://qiita.com/teruq/items/d9b6686ebcf6d78c3fb1)

## 設定

ポータルからROKSのあるVPCとClassicを接続します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/3791710e-a0f8-4d87-79fc-980099ea6172.png)

## 接続検証

仮想サーバから各パターンでアプリケーションにアクセスします。

```
# プライベートルーター
$ curl -s ruby-ex-teruz.roks-tok-9dfbcfe481bb6d6d7afea007d1a8cafd-i001.jp-tok.containers.appdomain.cloud

# NodePort
$ curl -s 10.244.130.4:31530/
$ curl -s 10.244.2.4:31530/
$ curl -s 10.244.66.4:31530/

# プライベートVPCロードバランサー
$ curl -s 1ff5cf61-jp-tok.lb.appdomain.cloud:8080

# プライベートIngress Controller
$ curl -s ruby-ex-teruz.roks-tok-9dfbcfe481bb6d6d7afea007d1a8cafd-i002.jp-tok.containers.appdomain.cloud
```

結果はいずれも成功しました。

## メリット

* ネットワーク的に疎通できればアプリケーション接続は問題ありません
* VPCのマルチゾーンを気にする必要がありません

## 考慮点

* VPCと同じIBM Cloudアカウント内の仮想サーバからの利用に限定されます
* 本環境はVPC側のサブネットが10.x.x.xなので特に考慮しませんでしたが、もし仮想サーバがパブリックインターフェースを持ち、VPCのサブネットが10.x.x.x以外だった場合は、仮想サーバ側でルーティングテーブルを変更する必要があります
* 何もしないとクラシックインフラストラクチャーとVPC間で通信がほぼ素通しになるので、実運用の際はACLやセキュリティグループで不要な通信を拒否するようきちんと設定する必要があります

# VPNゲートウェイ

VPNゲートウェイはVPCで利用できるIPSec VPNサービスです。

## 構成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/1784e173-e1e9-5a45-42f6-6238c3cda8a4.png)

## ポイント

VPNゲートウェイは残念ながら配置されたゾーン内しか通信できないようです。そのため、VPNゲートウェイをVPCロードバランサーがある全てのゾーンに配置する必要があります。

## 設定

オンプレミス相当の仮想サーバはAWS EC2を利用しました。

### VPNゲートウェイの構成

ポータルからjp-tok-1向けのVPNゲートウェイを構成します。ROKSのあるVPCを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/a92a9134-55bd-e458-6614-f34407baa680.png)

接続先のサブネットを選択します。モードは``ポリシーベース``を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/5ddec08e-8842-71f0-b4d5-b0a69bf83428.png)

接続情報を入力します。

* ピア・ゲートウェイ・アドレス: EC2インスタンスのフローティングIP
* 事前共有鍵: 任意の文字列を設定（十分な強度で）
* ローカル・サブネット: IBM Cloud側でEC2からアクセスさせるアドレスレンジ（ROKSのあるサブネットアドレス）
* ピア・サブネット: EC2インスタンスのプライベートアドレス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/7c6989da-4b27-2aff-db87-40d5714df0c7.png)

作成後、ゲートウェイIPが付与されますので控えておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/1a139c20-14e9-ed15-d82b-5412c36d842b.png)

同様に、jp-tok-2のVPNゲートウェイも作成します。IBM Cloud側のサブネットのみ、jp-tok-2固有の値になります。ゲートウエイIPも控えておきます。

### EC2インスタンス側の設定

この例ではCensOS 8を使用しています。まずstrongSwanをインストールします。

```
$ sudo dnf -y install epel-release
$ sudo dnf -y install strongswan
```

先ほど決めた事前共有鍵をipsec.secresファイルに記述します。xx.xx.xx.xxはIBM Cloud側のゲートウェイIP、********は事前共有鍵です。

```/etc/strongswan/ipsec.secrets
xx.xx.xx.xx : PSK "********"  # jp-tok-1のゲートウェイIP
xx.xx.xx.xx : PSK "********"  # jp-tok-2のゲートウェイIP
```

接続情報をipsec.confに記述します。

```/etc/strongswan/ipsec.conf
conn vpn-gw-bastion-tok1
  left={{ EC2インスタンスのプライベートIP }}
  leftid={{ EC2インスタンスのフローティングIP }}
  leftsubnet={{ EC2インスタンスのプライベートIP }}/32
  right={{ VPNゲートウェイのゲートウェイIP }}
  rightid={{ VPNゲートウェイのゲートウェイIP }}
  rightsubnet=10.244.2.0/24
  auto=start
  authby=secret

conn vpn-gw-bastion-tok2
  left={{ EC2インスタンスのプライベートIP }}
  leftid={{ EC2インスタンスのフローティングIP }}
  leftsubnet={{ EC2インスタンスのプライベートIP }}/32
  right={{ VPNゲートウェイのゲートウェイIP }}
  rightid={{ VPNゲートウェイのゲートウェイIP }}
  rightsubnet=10.244.66.0/24
  auto=start
  authby=secret
```

strongSwanを起動します。

```
$ sudo strongswan start
$ sudo strongswan status
Security Associations (2 up, 0 connecting):
...
```

## 接続検証

プライベートルーターと同様の手順で検証します。結果、いずれのパターンも正常にアプリケーションにアクセスできました。

## メリット

* 今回はHost to Siteで構成しましたが、IPSec VPNに対応したルーターを利用するか、strongSwanの設定を頑張ればSite to Siteでの接続も可能です

## 考慮点

* 本環境ではたまたまtok-1とtok-2にVPCロードバランサーがありますが、これは利用者がコントロールすることができないので、実運用の際は全ゾーンに配置しておくのがよいです
* 設定・運用ともにIPSec VPNの知識が必要です

# OpenVPN

OpenVPNサーバをVPC内に立てます。設定方法は過去記事を参照ください。

> [IBM Cloud VPCの仮想サーバにOpenVPNで接続する](https://qiita.com/teruq/items/b19e575f7e106215658c)

## 構成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/c755d2d7-2a58-97d3-eaa3-e36b0d590a5b.png)

## ポイント

OpenVPNを自力で立ち上げ、VPNサーバからROKSはNATでルーティングさせます。

## 設定

OpenVPNサーバの今回固有の設定は下記のとおりです。この4つのサブネットがクライアントからアクセス可能になります。一番上の10.244.0.0（踏み台サブネット）はアプリケーションとの通信には不要ですが、これがないとクライアントからVPNサーバにpingやsshができないので、メンテナンス性の観点で追加しています。

```/etc/openvpn/server/server.conf
push "route 10.244.0.0 255.255.255.0"
push "route 10.244.2.0 255.255.255.0"
push "route 10.244.66.0 255.255.255.0"
push "route 10.244.130.0 255.255.255.0"
```

## 接続検証

プライベートルーターと同様の手順で検証します。結果、いずれのパターンも正常にアプリケーションにアクセスできました。

## メリット

* サーバ間だけでなくPCからの接続でも利用できます

## 考慮点

* 基本的にはSite to SiteではなくHost to Siteの接続になります
* 実運用では、OpenVPNサーバ自体の冗長化を考える必要があります
* 実運用ではOpenVPN自体のアクセス制御（パスワード、証明書等）と運用を考慮する必要があります

# まとめ

アプリケーションへの接続はいずれも問題ありませんでしたが、接続方式にはそれぞれ一長一短あり、どれがベストというのはないという印象でした。接続元とのトポロジーに応じて検討するのがよいかもしれません。

* IBM Cloud内からのアクセスである → Transit Gateway
* サイト間ではなくユーザーのPCからのアクセスである → OpenVPN
* サイト間のアクセスであり、IPSec VPN対応ハードウェアまたはソフトウェアを用意できる → VPNゲートウェイ


ただ、真にベストなのは、アプリケーションにプライベートアクセスさせるのではなく、普通にパブリックでアクセスさせることだと思います。クラウドなので。