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)