Fabric8 Kubernetes Client の実践ガイド:Java によるクラスタ操作の高度な活用

Fabric8 Kubernetes Client は、Kubernetes クラスタとプログラムから対話するための成熟した Java ライブラリです。ネイティブリソース(Pod、Deployment、ConfigMap など)だけでなく、カスタムリソース定義(CRD)への柔軟な対応、イベント駆動型の Watch 機能、非同期処理、および拡張可能なアーキテクチャを備えています。

内部構造と通信モデル

クライアントは、HTTP/HTTPS を通じて Kubernetes API Server と直接通信します。基盤となる HTTP エンジンとして OkHttp を採用し、SSL 証明書検証やプロキシ設定も標準でサポートされます。JSON 形式の API 応答は Jackson を用いて Java オブジェクトにマッピングされ、Kubernetes の OpenAPI スキーマに基づく厳密な型定義が保証されます。認証情報は実行環境に応じて自動判別され、ローカル開発では ~/.kube/config、クラスタ内 Pod 側では ServiceAccount トークンと CA 証明書が利用されます。

プログラミングスタイルの特徴

  • メソッドチェーンによる宣言的記述:リソース操作を自然な英語風フローで記述可能(例:client.deployments().inNamespace("staging").withLabel("tier", "backend").list()
  • ライフサイクル管理の自動化AutoCloseable 実装により、try-with-resources 文で接続・リソース解放を安全に保証
  • 状態依存操作の抽象化createOrReplace()patch() で宣言的な更新戦略を実現
  • 動的リソース対応:CRD を事前にクラス生成せず、Map<String, Object> や YAML 文字列でも操作可能

初期設定と最小限の実行例

Maven 依存関係には、最新安定版(例:6.12.1)を指定します。Java 11 以降が必要です。
<dependency>
  <groupId>io.fabric8</groupId>
  <artifactId>kubernetes-client</artifactId>
  <version>6.12.1</version>
</dependency>
以下は、デフォルト名前空間の Deployment を一覧表示し、新しい名前空間を確立するサンプルです:
import io.fabric8.kubernetes.api.model.Namespace;
import io.fabric8.kubernetes.api.model.apps.DeploymentList;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;

public class ClusterOperator {
  public static void main(String[] args) {
    try (KubernetesClient kube = new DefaultKubernetesClient()) {
      // Deployment の取得
      DeploymentList deployments = kube.apps()
          .deployments()
          .inNamespace("default")
          .list();
      deployments.getItems().forEach(d -> 
          System.out.println("Deployment: " + d.getMetadata().getName())
      );

      // 名前空間作成(存在しない場合のみ)
      Namespace ns = new NamespaceBuilder()
          .withNewMetadata()
            .withName("automation-ns")
          .endMetadata()
          .build();
      kube.namespaces().resource(ns).createOrReplace();
    }
  }
}

リソース操作のパターン

操作タイプコードスニペット
単一リソース取得kube.pods().inNamespace("prod").withName("api-v2").get()
ラベルフィルタ付き一覧kube.services().withLabel("app", "gateway").list()
条件付き更新kube.configMaps().inNamespace("config").withName("app-config").edit(cm -> cm.getData().put("version", "2.1"))
パッチ適用(JSON Merge Patch)kube.pods().withName("worker").patch("{\"spec\":{\"replicas\":3}}")

リアルタイム監視(Watch)の実装

Watch は長時間接続を維持し、Kubernetes のイベントストリームを受信します。再接続ロジックを組み込むことで耐障害性を向上させます。
Watch watchHandle = kube.pods()
    .inNamespace("monitoring")
    .watch(new Watcher<Pod>() {
      public void eventReceived(Action action, Pod pod) {
        switch (action) {
          case ADDED:
            System.out.println("[+]" + pod.getMetadata().getName());
            break;
          case MODIFIED:
            System.out.println("[*]" + pod.getMetadata().getName());
            break;
          case DELETED:
            System.out.println("[-]" + pod.getMetadata().getName());
            break;
        }
      }

      public void onClose(WatcherException e) {
        if (e != null) {
          System.err.println("Watch terminated unexpectedly: " + e.getMessage());
        }
      }
    });

カスタムリソース(CRD)の扱い方

CRD の操作には二つのアプローチがあります。 動的アプローチ(スキーマ不要):
Map<String, Object> crInstance = Map.of(
    "apiVersion", "batch.example.com/v1alpha1",
    "kind", "JobQueue",
    "metadata", Map.of("name", "daily-backup"),
    "spec", Map.of("schedule", "0 2 * * *", "timeoutSeconds", 3600)
);
kube.resource(crInstance).inNamespace("jobs").create();
静的アプローチ(型安全性向上):
@Group("batch.example.com")
@Version("v1alpha1")
public class JobQueue extends CustomResource<JobQueueSpec, JobQueueStatus> {}

// 使用時
JobQueue job = new JobQueueBuilder()
    .withNewMetadata().withName("nightly-cleanup").endMetadata()
    .withNewSpec().withSchedule("0 3 * * *").endSpec()
    .build();
kube.resources(JobQueue.class).create(job);

コンテナとのインタラクション

Pod 内の実行時情報を取得する機能も提供されています。
  • ログ取得kube.pods().withName("logger").getLog()
  • コマンド実行kube.pods().withName("debug-pod").exec("ls", "-l", "/tmp")
  • ポート転送kube.pods().withName("db").portForward(5432, 9001)(ローカル 9001 → Pod の 5432)

高度な運用機能

  • 非同期処理getAsync(), listAsync() で CompletableFuture を返却
  • リクエストフック:SPI を用いたカスタムインターセプター(トレーシングヘッダー挿入など)
  • フレームワーク統合:Spring Boot の @Bean 宣言や Quarkus の CDI 統合に対応

運用上の留意点

  • 複数スレッド間で KubernetesClient インスタンスを共有可能(スレッドセーフ)
  • RBAC による最小権限付与を必須とし、ServiceAccount を通じたアクセスを推奨
  • 大量リソース取得時は .limit(n).continueToken(token) を用いたページネーションを実施
  • デバッグ用途で HTTP 通信内容を確認したい場合は ConfigBuilder.withRequestLogging(true)

タグ: fabric8 kubernetes-client Java crd watch

7月11日 23:26 投稿