OpenShiftでNginx Ingress Operatorを導入してTCPをルーティングする

この記事は [セゾンテクノロジー Advent Calendar 2024](https://qiita.com/advent-calendar/2024/saison-tech)の22日の記事です。

シリーズ2は [HULFT10](https://www.hulft.com/software/hulft-10) のエンジニアによる投稿をお届けします。

# はじめに
Openshift上にあるリソースに、Openshift外のネットワークからのTCP通信をルーティングしたい！
ということが最近あったのですが、ネット上に情報が少なくて困りました。。
そんなわけで続く誰かのために書きます！

# 概要

Nginx Ingress Operator(Nginx Ingress Controller)を使用して、OpenShift上にあるリソースにOpenShift外のネットワークからのTCP通信をルーティングしてみます！

今回は以下の構成でやってみます：

- AWS上のOpenShiftにあるMySQLに対して、OpenShiftがあるVPCとは別のVPCのインスタンスからNginx Ingress Controller経由でログインする
![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942124/7eda738a-99df-450f-15cd-2ddd620c5f11.png)

- 別VPCからログインしたいOpenShift上のMySQL
![スクリーンショット 2024-12-21 184056.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942124/9f94e422-5a7f-ba08-5bfb-2bd9b0544996.png)

必要に応じてMySQLを別のシステムに置き換えてください。

さっそく作っていきます！

## Nginx Ingress Operatorを導入する

OperatorHubから「Nginx Ingress Operator」と検索してデフォルト設定でインストールします。
![スクリーンショット 2024-12-21 184211.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942124/f80bc9ec-07f2-4b0e-e593-84acdc5d29b5.png)

## SecurityContextConstraints (SCC) の作成

これを作成しておかないと、後述のNginx Ingress Controllerの作成が失敗します。

以下のコマンドを実行すると必要なSCCが作成されます。

```bash
kubectl apply -f https://raw.githubusercontent.com/nginxinc/nginx-ingress-helm-operator/main/resources/scc.yaml
```

# Nginx Ingress Controllerを作成する

Nginx Ingress Controllerは実際にTCP通信をルーティングしてくれるものです。NginxIngressの作成から進みます。
![スクリーンショット 2024-12-21 184430.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942124/d361a6ba-32ce-b03c-26f5-9acba131dad2.png)

YAMLビューに切り替えてYAMLに手を加えます。
![スクリーンショット 2024-12-21 184455.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942124/acc8d7ec-0959-da73-1063-67148c64c187.png)


### GlobalConfiguration設定

YAML内で`globalConfiguration`と検索すると、GlobalConfigurationの設定箇所があるので以下のように設定してください。
![スクリーンショット 2024-12-21 184527.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942124/2b107323-8a42-72ad-08b8-9e2187ca5899.png)

これによりリスナーを作成することができます。

GlobalConfigurationの詳しい設定値は以下を参照してください。
https://docs.nginx.com/nginx-ingress-controller/configuration/global-configuration/globalconfiguration-resource/

### Service CustomPort設定

YAML内で`customPorts`と検索すると、CustomPortsの設定箇所があるので以下のように設定してください。
![スクリーンショット 2024-12-21 184600.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942124/fe508ef0-fb5a-80f8-e96f-c28d68ba538e.png)


これによりNginx Ingress ControllerにMySQL用のServiceが追加されます。


GlobalConfigurationとService CustomPortの設定をした上で作成ボタンを押すとNginx Ingress Controllerが作成されます。
![スクリーンショット 2024-12-21 191709.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942124/8ecb7713-6611-fabf-3a37-90de2877e096.png)
metadataがデフォルト設定だとnginx-ingressというPJ上に作成されます。

### TransportServerを作成する

CustomResourceDefinitionsで`TransportServer`と検索して進みます。
![ダウンロード2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942124/a7c71c17-9455-cae5-4628-0577b8898a69.png)


インスタンスからTransportServerの作成へと進みます。
YAMLを以下のように設定してください。

![ダウンロード 5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942124/123831b9-7f28-2def-ea87-4524b1ea9a39.png)

namespaceはMySQLがあるところを指定してください。別のnamespaceを設定するとルーティングが失敗します。

これにより先ほど作成したリスナーに来た通信をMySQLにルーティングすることができます。

TransportServerの詳しい設定値は以下を参照してください。
https://docs.nginx.com/nginx-ingress-controller/configuration/transportserver-resource/

### 接続先Serviceの取得

以下のコマンドを実行すると、先ほど作成したNginx Ingress ControllerのExternal IPを取得できます。
```bash
oc get -n nginx-ingress svc
```
External IP例：aaaaaaaaaaaa000000a0a00000000aaa-00000000000.ap-northeast-1.elb.amazonaws.com

### MySQLへの接続
EC2上から先のコマンドで取得したExternal IPに対してMySQLコマンドを実行します。
```bash
mysql -u root -p -h aaaaaaaaaaaa000000a0a00000000aaa-00000000000.ap-northeast-1.elb.amazonaws.com
 -P 3306
 ```

 ![ダウンロード4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942124/9a151a0d-ddec-9f4a-e747-e7dcc9903f4f.png)

ログインできました！
これでOpenShift上にあるリソースに対して、OpenShift外のネットワークからのTCP通信をルーティングできたことになります。


# おわりに
誰かが役立ててくれれば幸いです！