OCIでサブネットで利用されているIPアドレス一覧を取得するOCI CLIコマンドと活用例

この記事は、[Oracle Cloud Infrastructure Advent Calender 2023](https://qiita.com/advent-calendar/2023/oci) Day 19 の記事として書かれています。

OCIのコンソールではできないけど、CLIを使うと実は簡単にできてしまう便利コマンドというものがいくつかあります。今回はその中の一つ、サブネットで利用されているIPアドレスをリストするコマンドを使ってみよう、というエントリです。


# サブネットの中のIPアドレスを調べたい、けどどうやって?

OCIのサービスのうち、多くのサービスは、仮想NICにアサインされたプライベートIPアドレスの情報がコンソールから表示されます。例えばコンピュート・インスタンスが持つプライマリのIPアドレスは、インスタンスの概要画面に出てきますし(図1)、仮想NICにアサインされたセカンダリIPアドレスなども、仮想NICの画面をドリルダウンしていけば見ることができます。(図2)

図1
![スクリーンショット 2023-12-19 23.06.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117710/58caa50c-59df-098e-d406-5406cae6ce4a.png)

図2
![スクリーンショット 2023-12-19 23.09.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117710/6e0608e8-b68f-897c-0ca3-b913949693d4.png)


他にも、Oracle Base Databaseサービス・インスタンスのノード一覧の画面には、ノードに振られたプライベートIPアドレスが表示されています。

![スクリーンショット 2023-12-19 16.18.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117710/3e166743-39ac-6aee-36d7-825e6b85036a.png)


ただ、ネットワーク観点から見ると、サブネットの中で使われているIPアドレスを一覧表示してみたい、という場合がありますよね? しかし、残念ながらOCIのネットワークのコンソール画面にはそんな要望に応えられるような便利な画面は用意されていないのです。そうなると、インスタンスの画面を一つ一つ開きながら使っているIPアドレスをメモしていく。。。なんて作業に時間を費やすことになるので、もう少しなんとかならないの? とお問い合わせをいただくことがあります。

そこで出てくるのがOCI CLI。そう、実はCLIには知る人ぞ知る「サブネットの中のIPアドレスの一覧をリストする」という便利なコマンドがあるのです。


# OCI CLIの便利コマンドの使い方

ではそのコマンドを使っていきましょう。
OCI CLIを使う方法はいくつもありますが、今回は一番簡単なCloud Shellを使う方法をご案内していきます。


1. 使われているIPアドレスを調べたいサブネットの画面を開く (メニュー→ネットワーキング→仮想クラウド・ネットワーク→サブネット)

1. サブネットのOCIDをコピーする (OCIDという欄にある Copy リンクを押すとOK)

![スクリーンショット 2023-12-19 16.43.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117710/6951aebe-d564-8276-6ecb-a94d794a9d33.png)


1. OCIコンソール右上の「開発者ツール」アイコンを押し、「Cloud Shell」を選択する

![スクリーンショット 2023-12-19 16.32.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117710/e1e43080-a94f-b6e4-1fc9-903a8bcd3752.png)

1. 開いたコンソールで `oci network private-ip list --subnet-id ` とタイプし、続いて先ほどコピーしたサブネットのOCID (ocid...で始まる文字列)を貼り付けし、ENTERを押す


以上です、とても簡単ですね。
結果はこのような感じで表示されます。(OCIDは加工済)

```
mmarukaw@cloudshell:~ (ap-tokyo-1)$ oci network private-ip list --subnet-id ocid1.subnet.oc1.ap-tokyo-1.aaabbbcccxxxyyyzzz
{
  "data": [
    {
      "availability-domain": "TGjA:AP-TOKYO-1-AD-1",
      "compartment-id": "ocid1.compartment.oc1..aaabbbcccxxxyyyzzz",
      "defined-tags": {},
      "display-name": "ocid1.bastion.oc1.ap-tokyo-1.aaabbbcccxxxyyyzzz",
      "freeform-tags": {},
      "hostname-label": "host-10-0-0-143",
      "id": "ocid1.privateip.oc1.ap-tokyo-1.aaabbbcccxxxyyyzzz",
      "ip-address": "10.0.0.143",
      "is-primary": true,
      "subnet-id": "ocid1.subnet.oc1.ap-tokyo-1.aaabbbcccxxxyyyzzz",
      "time-created": "2021-05-27T02:24:42.407000+00:00",
      "vlan-id": null,
      "vnic-id": "ocid1.vnic.oc1.ap-tokyo-1.aaabbbcccxxxyyyzzz"
    },
    {
      "availability-domain": "TGjA:AP-TOKYO-1-AD-1",
      "compartment-id": "ocid1.compartment.oc1..aaabbbcccxxxyyyzzz",
      "defined-tags": {},
      "display-name": "test-vm",
      "freeform-tags": {},
      "hostname-label": "test-vm",
      "id": "ocid1.privateip.oc1.ap-tokyo-1.aaabbbcccxxxyyyzzz",
      "ip-address": "10.0.0.197",
      "is-primary": true,
      "subnet-id": "ocid1.subnet.oc1.ap-tokyo-1.aaabbbcccxxxyyyzzz",
      "time-created": "2023-12-19T08:13:07.382000+00:00",
      "vlan-id": null,
      "vnic-id": "ocid1.vnic.oc1.ap-tokyo-1.aaabbbcccxxxyyyzzz"
    }
  ]
}
```

JSON形式が読みにくい場合は、--output table をつけると表形式になります。ついでにJMESPathでカラムを絞り込んで、display-name、ip-address、time-created の3列だけを表示してみます。コマンドはこんな感じです。

`
oci network private-ip list --output table --query 'data[].{"display-name":"display-name","ip-address":"ip-address","time-created":"time-created"}'  --subnet-id <サブネットのOCID>
`

結果はこちら

```
mmarukaw@cloudshell:~ (ap-tokyo-1)$ oci network private-ip list --output table --query 'data[].{"display-name":"display-name","ip-address":"ip-address","time-created":"time-created"}' --subnet-id ocid1.subnet.oc1.ap-tokyo-1.aaabbbcccxxxyyyzzz
+------------------------------------------------------------------+------------+----------------------------------+
| display-name                                                     | ip-address | time-created                     |
+------------------------------------------------------------------+------------+----------------------------------+
| ocid1.bastion.oc1.ap-tokyo-1.aaabbbcccxxxyyyzzz                  | 10.0.0.143 | 2021-05-27T02:24:42.407000+00:00 |
| test-vm                                                          | 10.0.0.197 | 2023-12-19T08:13:07.382000+00:00 |
+------------------------------------------------------------------+------------+----------------------------------+
```

このサブネットには、bastionサービスのプライベートIPがひとつと、test-vmという名前のおそらくコンピュート・インスタンスがひとつあることがわかります。


# 見えないプライベートIPアドレスを見てみよう

さて、コマンドの紹介自体は以上、で、へー便利だねぇという感じなのですが、せっかくのAdvent Calendarなので、このコマンドを使ってもう少し遊んでみてみようと思います。
OCIのサービスのうち、プライベートIPアドレスがアサインされているのにそのアドレスがわからない、または探しにくい、というサービスが時々ありますが、そんな時にこの便利コマンドを使って「見えない」プライベートIPアドレスを見ることができますので、いくつか試してみようと思います。

## ロード・バランサのプライベートIPを見てみる

フレキシブル・ロード・バランサ・サービスのドキュメントには、「1つのサブネットで作成されたプライベート・ロード・バランサは、ホスト・サブネットの3つのプライベートIPアドレスを使用します。」と書かれています。ただ、ロード・バランサのコンソール画面に出てくるのは、クライアントからのエンドポイントのプライベート1つだけで、もう他のアドレスは隠れていて知ることができません。

そこで、サブネットの中にプライベート・ロード・バランサを一つ作ってこのコマンドを打ってみた結果がこちら。

```
+------------------------------------------------------------------------------------------------+------------+----------------------------------+
| display-name                                                                                   | ip-address | time-created                     |
+------------------------------------------------------------------------------------------------+------------+----------------------------------+
| Floating IP for VIP private-vip on LB ocid1.loadbalancer.oc1.eu-frankfurt-1.aaabbbcccxxxyyyzzz | 10.5.0.135 | 2023-12-01T07:11:42.938000+00:00 |
| VNIC for LB ocid1.loadbalancer.oc1.eu-frankfurt-1.aaabbbcccxxxyyyzzz                           | 10.5.0.252 | 2023-12-01T07:11:41.058000+00:00 |
+------------------------------------------------------------------------------------------------+------------+----------------------------------+
```

あれれ、アドレスは2つしか表示されませんね。
`Floating IP for VIP...` という.135のアドレスが、コンソールにも表示されているフロントのIPアドレスで、もうひとつの`VNIC for LB ...` という.252のアドレスがバックエンドの実行ノードに割り当てられた隠れたIPアドレスのようです。
ちょっと調べてみたところ、ロード・バランサは以前に仕様変更が入っており、今までActive-Standbyで稼働されていた実行ノードが現在ではActive-Activeで稼働するようになっているようで、おそらくそのタイミングで、アサインされるIPアドレスが3つから2つに変わった、のではないかと推測されます。そしてドキュメントの表記は古いままなのでしょうね。


## ファイル・ストレージ・サービスのマウント・ターゲットのプライベートIPを見てみる

ファイル・ストレージ・サービスのマウント・ターゲットも、プライベートを指定することができない、そして裏側に隠されたIPアドレスが存在するサービスです。というわけで、こちらも同じコマンドを打ってみます。

```
+-------------------------+------------+----------------------------------+
| display-name            | ip-address | time-created                     |
+-------------------------+------------+----------------------------------+
| fss-2000000085133786    | 10.4.1.14  | 2023-12-19T13:36:01.264000+00:00 |
| fss-2000000085133786    | 10.4.1.36  | 2023-12-19T13:36:14.215000+00:00 |
| privateip20231219133613 | 10.4.1.130 | 2023-12-19T13:36:13.547000+00:00 |
+-------------------------+------------+----------------------------------+
```

`.130`のアドレスが、OCIコンソールにも表示されている、NFSのアクセスポイントとして機能するプライベートIPアドレスです。
そしてその他に、`fss-`で始まるIPアドレスが2つ使われていることがわかります。これはマウント・ターゲットの実行ノードとしてのプライベートIPアドレスで、コンソールからはみることができませんが、マウント・ターゲット作成時に作られるものです。この結果から、マウント・ターゲットは合計3つのアドレスが使うことがわかります。


## VCNのDNSリゾルバの転送エンドポイントのプライベートIPを見てみる

最後に、少し珍しめのサービスについてもやってみます。VCNのDNSリゾルバに作成できる転送エンドポイントです。
転送エンドポイントはVCN内のリゾルバが外部のDNSサーバからのDNSクエリの転送を受け付けるリスニング・エンドポイントと、VCN内のリゾルバが外部のDNSサーバに対してDNSクエリの転送を送るフォワーディング・エンドポイントの2種類があります。
このどちらも、DNSのクエリを受ける/送るためのIPアドレスを持ちますので、アドレスを作るとサブネットの中のIPアドレスを消費して、アサインされます。

ではまず、リスニング・エンドポイントから。

```
+-------------------------+------------+----------------------------------+
| display-name            | ip-address | time-created                     |
+-------------------------+------------+----------------------------------+
| test_listening_endpoint | 10.3.1.229 | 2023-12-19T13:50:05.947000+00:00 |
+-------------------------+------------+----------------------------------+
```

一つだけIPアドレスがアサインされていますね。このアドレスは、OCIコンソールにも表示されるものと一致しています。どうやらリスニング・エンドポイントはIPアドレスは1つだけしか使わないようです。

では、フォワーディング・エンドポイントを作って、同じコマンドを打ってみましょう。結果はこちら。

```
+--------------------------+------------+----------------------------------+
| display-name             | ip-address | time-created                     |
+--------------------------+------------+----------------------------------+
| ReverseConnectionIp      | 10.3.1.156 | 2023-12-19T13:54:26.722000+00:00 |
| test_forwarding_endpoint | 10.3.1.158 | 2023-12-19T13:54:00.100000+00:00 |
+--------------------------+------------+----------------------------------+
```

おおっと、今度はIPアドレスが2つ表示されました。
`test_forwading_endpoint`という表示名は、私が作ったフォワーディング・エンドポイントと同じです。ただ、実はこちらにアサインされている`.158`というアドレスはOCIコンソールに表示されているアドレスとは異なります。

OCIコンソールの状態はこちら。

![スクリーンショット 2023-12-19 22.57.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117710/4c6c6160-017c-0be6-8d24-53619d31b4b5.png)

OCIコンソールからは、転送アドレスとして設定されているのは、`.156`というアドレスで、こちらは先ほどのコマンドの結果では、`ReverseConnectionIp`という名前のIPアドレスの方にアサインされていることがわかります。

さてこれはどういうことでしょう? 実はこの`ReverceConnectionIp`というのは、プライベート・エンドポイント機能とセットで使われる、VCNからVCNの外部の発信の際に送信元IPアドレスとして使用されるリバース・コネクション・エンドポイント(通称RCE)という機能に使われるIPアドレスになります。RCE自体はあまり表に出てくる機能ではないですので馴染みがないかもしれませんが、このDNSの転送エンドポイントにおいては、外部のDNSサーバーに対してDNSクエリを転送する際の送信元IPアドレスとして割り振られているので、用途としてはぴったりということになります。

ではなぜもう一つのIPアドレス、`.158`が割り振られるのでしょう? 真相は謎ですが、RCEはプライベート・エンドポイントとセットで使われる機能のようですので、ひょっとしたら使用上単独では利用できず、プライベート・エンドポイントとしてVCNに入ってくる用のIPアドレスもアサインされてしまう(が、DNSの転送エンドポイントでは使っていない)みたいなことがあるのかも。。。なんて想像してみるのでした。


# 終わりに

というわけで、`oci network ip-address list...` というCLIコマンド、便利ですのでぜひ使ってください。
そして、このコマンドを使って「隠された」IPアドレスを探ることで、普段は隠されているサービスの作りや中身がちょっとだけ覗けて色々と楽しく想像できたり(?)します。皆さんもぜひ色々なサービスで試して遊んでみてください。

では、皆さん良いクリスマス&年末を！！