もう迷わない！TypeScriptでKubernetes PodのIP・ステータスを簡単取得する方法

# はじめに

本記事では、**リモート環境**から**Kubernetes上のPod情報を取得するクラス**をTypeScriptで作成した例を紹介します。

Node.jsとTypeScriptを使って、kubectlコマンドをリモート実行し、Podの名前・ステータス・IPアドレスをまとめて取得・加工する仕組みを実装します。

# 構造図
```plaintext
Pod クラス
├── execRemote(cmd)               // リモート実行
├── searchPods(search)            // Podを検索して一覧取得
│   └── getPodIp(podName)          // PodのIP取得
├── getPodxxx()                // 環境別のxxxPod取得
└── getRunningPod(search)          // Running状態のPodのみ取得
```

# インポート
```typescript:Pod.ts
import { PodTable } from "@utils/types/internal/data";
import Logger from "../common/Logger";
import SessionDB from "@class/db/SessionDB";
import settings from "@utils/constants/settings";
import Remote from "./Remote";
```
- 必要な**型定義**（PodTable）や**ロガー**（Logger）、**セッション管理**（SessionDB）、**定数**（settings）、**リモート操作クラス**（Remote）を読み込んでいます。


# `Pod` クラス全体
```typescript
class Pod { ... }
```
- Kubernetes上のPodに対する**検索**や**状態確認**などの機能を持ったクラスです。
- 主にkubectlコマンドをリモート実行してPod情報を取得します。

# Pod検索 (`searchPods`)
```typescript:Pod.ts
public async searchPods(search: string): Promise<Array<PodTable>> {
  const cmd = `kubectl get pods | grep ${search}`;
  const searchResult = (await Remote.execRemote(cmd)) as string;
  const podLines = searchResult.trim().split("\n");
  const podObjects = await Promise.all(
    podLines.map(async (line) => {
      const splitLine = line.split(/\s+/);
      const podName = splitLine[0] || "";
      const podIP = await this.getPodIp(podName);

      return {
        name: podName,
        status: splitLine[2] || "",
        ip: podIP || "",
      };
    })
  );

  Logger.info(`These are the search results for ${search}`);
  console.table(podObjects);

  return podObjects;
}
```
- 指定文字列を含むPodを**リスト形式**で探し、**Pod名・ステータス・IPアドレス**をまとめます。
- 検索結果を`console.table`で表示してくれます。

# 5. PodのIPアドレス取得 (`getPodIp`)
```typescript:Pod.ts
private async getPodIp(podName: string): Promise<string> {
  const cmd = `kubectl get pod ${podName} -o jsonpath='{.status.podIP}'`;
  const podIP = (await this.execRemote(cmd)) as string;
  return podIP;
}
```
- 指定したPodの**IPアドレス**を取得する小さいメソッドです。

## 6. billdocgenserviceのPod取得 (`getPodBillDocGenService`)
```typescript:Pod.ts
public async getPodBillDocGenService(): Promise<string[]> {
  const podMap = await this.getRunningPod("billdocgenservice");
  return podMap.map((pod) => pod.name);
}
```
- `billdocgenservice` というサービス名で**Running状態のPod**を探して名前だけ返します。

# Running中のPodを取得する (`getRunningPod`)
```typescript:Pod.ts
private async getRunningPod(search: string): Promise<PodTable[]> {
  const podObjects = await this.searchPods(search);
  const runningPods = podObjects.filter((pod) => pod.status === "Running");

  if (runningPods.length > 0) {
    Logger.success(`Found running pod(s)`);
    return runningPods;
  } else {
    throw new Error(`Couldn't find running pod for ${search}`);
  }
}
```
- 検索結果のうち、**ステータスが"Running"のPodだけ**を抽出。
- 見つからなければ**エラー**を投げます。

# xxx用Pod取得 (`getPodUtility`)
```typescript:Pod.ts
public async getPodxxx(): Promise<string[]> {
  const env = SessionDB.getEnv();
  let podMap;

  switch (env) {
    case "prod":
      podMap = await this.getRunningPod("xxx");
      break;
    case "stg1":
    case "stg2":
    case "stg3":
      podMap = await this.getRunningPod("xxx");
      break;
  }

  return podMap.map((pod) => pod.name);
}
```
- 環境（本番 or ステージング）によって**探す対象Pod名**を切り替えて取得します。

# 最後に、インスタンス化してエクスポート
```typescript:Pod.ts
export default new Pod();
```
- クラス`Pod`をインスタンス化して、そのままエクスポートします。
- **シングルトン的な使い方**ですね。

# まとめ

- Node.jsとTypeScriptで、Kubernetes上のPodをリモート取得する仕組みを作りました。
- コマンドをシンプルにまとめ、拡張しやすい構成にできたと思います。
- 今後の改善案として、
  - Podのリソース使用率や、ログ取得機能も組み込む
  - PodのRestart回数などヘルスチェック情報も取り扱う
などを検討したいです。