OCIのOKEのOCI Native Ingress ControllerでIngressにNSGをアタッチする

## はじめに
OCIのOKEのOCI Native Ingress Controllerで、Ingress（ロードバランサー）にネットワーク・セキュリティ・グループ（以下NSG）をアタッチする方法を紹介します。

私は、セキュリティリストを極力使わずに、NSGでロードバランサーの通信制御を設定したかったです。公式もドキュメントのどこかでそれを推奨していました。しかし、NSGをアタッチする方法がすぐにわからなかったので記事にしました。

## 注意点
**2024年11月23日時点で、以下の理由で公式リポジトリのドキュメントから一度消えている内容です。** 詳細は後述します。そのため動作は保証しません！（ただし、私は期待通りに動きました）

> Reverting doc update made to GettingStarted.md in #99, for features that are not yet released as part of NIC v1.3.9

また、OKEやOCI Native Ingress Controllerについては説明しないので、以下のチュートリアルや公式ドキュメントを読みつつ設定してください。

OKEやkubectlの基本的な部分が参考になります。

https://oracle-japan.github.io/ocitutorials/cloud-native/oke-for-beginners/

ドキュメント

https://docs.oracle.com/ja-jp/iaas/Content/ContEng/Tasks/contengsettingupnativeingresscontroller.htm


## やり方
IngressClassのmanifestファイルに `metadata.annotations.ingressclass.kubernetes.io/is-default-class` を追加して、アタッチしたいNSGのOCIDをカンマ区切りで記載するだけです。

以下サンプルのmanifestファイルです。関連リソースも作成しています。

```yaml
# 公式ドキュメント
# https://docs.oracle.com/ja-jp/iaas/Content/ContEng/Tasks/contengsettingupnativeingresscontroller-createresources.htm
# リポジトリのドキュメント
# https://github.com/oracle/oci-native-ingress-controller/blob/main/GettingStarted.md

# ほぼドキュメント通りに記載しています。

apiVersion: "ingress.oraclecloud.com/v1beta1"
kind: IngressClassParameters
metadata:
  name: native-ic-params
spec:
  compartmentId: "<xxxxx>" # 各自の環境に合わせてください
  subnetId: "<xxxxx>" # 各自の環境に合わせてください
  loadBalancerName: "native-ic-lb"
  isPrivate: false
  maxBandwidthMbps: 100 # サンプルなのでかなり低い値を設定しています
  minBandwidthMbps: 10 # サンプルなのでかなり低い値を設定しています

# 本記事の要点
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: native-ic-ingress-class
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true"
    # NSGの設定方法は2024/11/23時点で、このPRでしか確認できない
    # https://github.com/oracle/oci-native-ingress-controller/pull/99/files
    # 複数の場合は、リストではなくカンマ区切りで指定する
    oci-native-ingress.oraclecloud.com/network-security-group-ids: "<nsg_id_1>, <nsg_id_2>"
spec:
  controller: oci.oraclecloud.com/native-ingress-controller
  parameters:
    scope: Namespace
    namespace: default
    apiGroup: ingress.oraclecloud.com
    kind: ingressclassparameters
    name: native-ic-params

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: native-ic-ingress
  annotations:
    oci-native-ingress.oraclecloud.com/healthcheck-protocol: "HTTP"
    oci-native-ingress.oraclecloud.com/healthcheck-port: "80"
    oci-native-ingress.oraclecloud.com/healthcheck-path: "/"
spec:
  ingressClassName: native-ic-ingress-class
  rules:
    - host: "xxx.jp" # ドメインがあるなら設定する
      http:
        paths:
          - pathType: Prefix
            path: "/"
            backend:
              service:
                name: nginx-service # リクエストを流すserviceを指定する
                port:
                  number: 80

# リクエスト確認用のnginxのserviceとdeployment
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP
```

このようなコードで `kubectl apply -f path/to/xxx.yaml` で変更を適用して少し待てば、InngressのロードバランサーのNSGに、このコードだと `nsg_id_1` と `nsg_id_2` のNSGがアタッチされています。

これで、セキュリティリストを使わずに、ロードバランサーの通信制御をすることができます！

もちろん、Pod通信のNSGのインバウンドで、ロードバランサーにアタッチしたNSGを許可しておけば、Pod通信はロードバランサーからのリクエストしか受け付けなくなります（やっってると思いますが、NodeやAPIエンドポイントからのインバウンドは許可しておいてください）。

## この設定を知るまでに至った経緯
「はじめに」に書いたとおり、NSGで通信制御をしたかったです。

公式ドキュメントやリポジトリのドキュメントを読んだりAIに聞いてもすぐわからず、検索したら以下のissueが出てきました。

https://github.com/oracle/oci-native-ingress-controller/issues/58

上記issueの最後に以下のPRのリンクがあったので、PRのdiffを見たらドキュメントにNSGを設定する方法が追記されていました。

https://github.com/oracle/oci-native-ingress-controller/pull/99

が、mainブランチのドキュメントには、追記された内容がありません。

https://github.com/oracle/oci-native-ingress-controller/blob/main/GettingStarted.md

調べると、以下のPRでドキュメントの追記部分は消えていました（実装は残ったまま）。

> Reverting doc update made to GettingStarted.md in #99, for features that are not yet released as part of NIC v1.3.9

PRにはこう書かれていたので、ドキュメントの追記が早まったのだと思います。

https://github.com/oracle/oci-native-ingress-controller/pull/100

ただし、私が試した限りはNSGのアタッチは問題なく機能しています。

## おわり
ニーズは高そうなので、OCIには早くNICのバージョンアップ？して、公式リポジトリのドキュメントに記載してほしい内容ですね。