Skip to main content

Java 客户端

概述

我们提供了 k8s/java 仓库,其中包含 Agents 资源的 CRD Java 模型定义,基于 Fabric8 Kubernetes Client 生成。

依赖导入

Maven 仓库:该包未发布到官方 Maven 仓库,你需要手动下载项目并打包成 JAR 文件使用。

可用的 CRD 模型

所有模型位于包 io.openkruise.agents.client.v2.models

CRDJava 类说明
SandboxSandbox单个 sandbox 实例
SandboxSetSandboxSet可扩缩的 sandbox 集合
SandboxClaimSandboxClaimsandbox 资源申领
SandboxTemplateSandboxTemplate可复用的 sandbox 模板
SandboxUpdateOpsSandboxUpdateOpssandbox 更新操作
CheckpointCheckpointsandbox 检查点/快照
TrafficPolicyTrafficPolicy流量路由策略
GlobalTrafficPolicyGlobalTrafficPolicy集群级流量策略
SecurityProfileSecurityProfile安全配置定义

使用示例

创建 Sandbox

import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
import io.fabric8.kubernetes.api.model.*;
import io.openkruise.agents.client.v2.models.Sandbox;
import io.openkruise.agents.client.v2.models.SandboxSpec;

public class SandboxExample {

public static void main(String[] args) {
try (KubernetesClient client = new KubernetesClientBuilder().build()) {
String namespace = "default";

// 构建 Sandbox
Sandbox sandbox = new Sandbox();
sandbox.setMetadata(new ObjectMetaBuilder()
.withName("my-sandbox")
.withNamespace(namespace)
.addToLabels("app", "sandbox-example")
.build());

// 构建 Spec
SandboxSpec spec = new SandboxSpec();

// 方式一:使用内联模板
PodTemplateSpec template = new PodTemplateSpecBuilder()
.withNewMetadata()
.addToLabels("app", "sandbox-container")
.endMetadata()
.withNewSpec()
.withRestartPolicy("Never")
.addNewContainer()
.withName("sandbox")
.withImage("nginx:latest")
.addNewPort()
.withName("http")
.withContainerPort(80)
.endPort()
.endContainer()
.endSpec()
.build();
spec.setTemplate(template);

// 方式二:使用 templateRef(与 template 互斥)
// TemplateRef ref = new TemplateRef();
// ref.setName("my-template");
// spec.setTemplateRef(ref);

sandbox.setSpec(spec);

// 创建 Sandbox
Sandbox created = client.resources(Sandbox.class)
.inNamespace(namespace)
.resource(sandbox)
.create();

System.out.println("Created sandbox: " + created.getMetadata().getName());
}
}
}

通过 SandboxClaim 批量创建

SandboxClaim 允许你从模板批量申领多个 sandbox。

import io.openkruise.agents.client.v2.models.SandboxClaim;
import io.openkruise.agents.client.v2.models.SandboxClaimSpec;
import io.fabric8.kubernetes.api.model.KubernetesResourceList;

try (KubernetesClient client = new KubernetesClientBuilder().build()) {
String namespace = "default";
String claimName = "demo-claim";

// 构建 SandboxClaim
SandboxClaim claim = new SandboxClaim();
claim.setMetadata(new ObjectMetaBuilder()
.withName(claimName)
.withNamespace(namespace)
.build());

SandboxClaimSpec spec = new SandboxClaimSpec();
spec.setReplicas(2);
spec.setTemplateName("demo-template");
claim.setSpec(spec);

// 创建 SandboxClaim
SandboxClaim created = client.resources(SandboxClaim.class)
.inNamespace(namespace)
.resource(claim)
.create();

System.out.println("Created sandboxclaim: " + created.getMetadata().getName());

// 等待申领完成(轮询)
long startTime = System.currentTimeMillis();
long timeout = 60000; // 1 分钟
boolean completed = false;

while (System.currentTimeMillis() - startTime < timeout) {
SandboxClaim updated = client.resources(SandboxClaim.class)
.inNamespace(namespace)
.withName(claimName)
.get();

if (updated != null && updated.getStatus() != null) {
String phase = updated.getStatus().getPhase();
if ("Completed".equals(phase)) {
Integer claimedReplicas = updated.getStatus().getClaimedReplicas();
if (claimedReplicas != null && claimedReplicas.equals(spec.getReplicas())) {
completed = true;
System.out.println("Claim completed successfully with " + claimedReplicas + " sandboxes");
break;
} else if (claimedReplicas != null && claimedReplicas > 0) {
System.out.println("Claim partially completed: " + claimedReplicas + "/" + spec.getReplicas());
break;
} else {
System.err.println("Claim failed: no sandboxes claimed");
break;
}
}
}

Thread.sleep(1000); // 等待 1 秒后再次检查
}

if (!completed) {
System.err.println("Claim did not complete within timeout");
}

// 列出已申领的 sandbox
System.out.println("Listing claimed sandboxes:");
KubernetesResourceList<Sandbox> sandboxList = client.resources(Sandbox.class)
.inNamespace(namespace)
.withLabel("agents.kruise.io/claim-name", claimName)
.list();

for (Sandbox sb : sandboxList.getItems()) {
System.out.printf(" %s/%s%n", sb.getMetadata().getNamespace(), sb.getMetadata().getName());
}
}

列出 Sandbox

import io.fabric8.kubernetes.api.model.KubernetesResourceList;

try (KubernetesClient client = new KubernetesClientBuilder().build()) {
KubernetesResourceList<Sandbox> sandboxList = client.resources(Sandbox.class)
.inNamespace("default")
.list();

for (Sandbox sb : sandboxList.getItems()) {
System.out.printf("Sandbox: %s, State: %s%n",
sb.getMetadata().getName(),
sb.getStatus() != null ? sb.getStatus().getPhase() : "Unknown");
}
}

删除 Sandbox

try (KubernetesClient client = new KubernetesClientBuilder().build()) {
client.resources(Sandbox.class)
.inNamespace("default")
.withName("my-sandbox")
.delete();

System.out.println("Sandbox deleted");
}

监听 Sandbox 变更

try (KubernetesClient client = new KubernetesClientBuilder().build()) {
client.resources(Sandbox.class)
.inNamespace("default")
.watch(new Watcher<Sandbox>() {
@Override
public void eventReceived(Action action, Sandbox sandbox) {
System.out.printf("Event: %s, Sandbox: %s%n",
action, sandbox.getMetadata().getName());
}

@Override
public void onClose(WatcherException cause) {
if (cause != null) {
System.err.println("Watch closed: " + cause.getMessage());
}
}
});
}

旧版模型(已废弃)

io.openkruise.agents.client.models 中的旧版模型已废弃,不再维护。请迁移到 io.openkruise.agents.client.v2.models,它使用 Fabric8 Kubernetes Client 注解,提供更好的类型安全性。