Kubernetes 客户端提供了丰富的 API 来管理和操作 Kubernetes 集群中的资源。以下是一些常见的操作示例,涵盖了指标获取、资源管理、自定义资源定义(CRD)以及类型化和无类型资源 API 的使用。
获取 Metrics
Kubernetes 客户端支持从启用了指标的 API 服务器获取指标。你可以通过 client.top()
访问指标。
获取所有节点的 NodeMetrics
:
NodeMetricsList nodeMetricList = client.top().nodes().metrics();
获取特定节点的 NodeMetrics
:
NodeMetrics nodeMetric = client.top().nodes().withName("minikube").metric();
获取所有命名空间中所有 Pod 的 PodMetrics
:
PodMetricsList podMetricsList = client.top().pods().metrics();
获取某个特定命名空间中所有 Pod 的 PodMetrics
:
PodMetricsList podMetricsList = client.top().pods().inNamespace("default").metrics();
获取特定 Pod 的 PodMetrics
:
PodMetrics podMetrics = client.top().pods().metrics("default", "nginx-pod");
Resource API
Resource 是 Kubernetes 中表示集群中可用计算资源(如 CPU、内存)的抽象概念,用于定义 Pod 的资源请求(requests)和限制(limits)。
Kubernetes 客户端提供了一个通用 API 来处理不同类型的 Kubernetes 资源。大多数 Kubernetes 资源都扩展了 HasMetadata
类。
从 Kubernetes API 服务器获取 Kubernetes 资源:
Pod pod = client.resource(pod1).inNamespace("default").get();
将 Kubernetes 资源应用到 Kubernetes 集群(服务器端应用):
Pod pod1 = new PodBuilder()
.withNewMetadata().withName("resource-pod-" + RandomStringUtils.randomAlphanumeric(6).toLowerCase(Locale.ROOT)).endMetadata()
.withNewSpec()
.addNewContainer().withName("nginx").withImage("nginx").endContainer()
.endSpec()
.build();
client.resource(pod1).inNamespace("default").serverSideApply();
应用 Kubernetes 资源并等待资源准备就绪:
pod1 = client.resource(pod1).serverSideApply();
Pod p = client.pods().resource(pod1).waitUntilReady(10, TimeUnit.SECONDS);
删除 Kubernetes 资源:
client.resource(pod1).inNamespace("default").delete();
Resource List
Kubernetes 客户端还提供了一个通用 API 来处理 Kubernetes 列表。
将 Kubernetes 资源列表应用到 Kubernetes 集群:
Service service = new ServiceBuilder()
.withNewMetadata().withName("my-service").endMetadata()
.withNewSpec()
.addToSelector("app", "Myapp")
.addNewPort().withProtocol("TCP").withPort(80).withTargetPort(new IntOrString(9376)).endPort()
.endSpec()
.build();
ConfigMap configMap = new ConfigMapBuilder()
.withNewMetadata().withName("my-configmap").endMetadata()
.addToData(Collections.singletonMap("app", "Myapp"))
.build();
KubernetesList list = new KubernetesListBuilder().withItems(deployment, service, configMap).build();
// 应用
client.resourceList(list).inNamespace("default").serverSideApply();
删除资源列表:
client.resourceList(new PodListBuilder().withItems(pod1, pod2, pod3).build()).inNamespace("default").delete();
自定义资源定义(CRD)
自定义资源定义(CRD) 是 Kubernetes 中允许用户扩展 API 的机制,用于定义和管理自定义资源(Custom Resource),满足特定应用或业务需求。
CustomResourceDefinition
是 Kubernetes API 中 CustomResource
对象的模板。
从 yaml 文件加载 CustomResourceDefinition
:
CustomResourceDefinition customResourceDefinition = client.apiextensions().v1().customResourceDefinitions().load(new FileInputStream("/sparkapplication-crd.yml")).item();
从 Kubernetes API 服务器获取 CustomResourceDefinition
:
CustomResourceDefinition crd = client.apiextensions().v1().customResourceDefinitions().withName("sparkclusters.radanalytics.io").get();
创建 CustomResourceDefinition
:
CustomResourceDefinition customResourceDefinition = new CustomResourceDefinitionBuilder()
.withApiVersion("apiextensions.k8s.io/v1")
.withNewMetadata().withName("sparkclusters.radanalytics.io")
.endMetadata()
.withNewSpec()
.withNewNames()
.withKind("SparkCluster")
.withPlural("sparkclusters")
.endNames()
.withGroup("radanalytics.io")
.withVersion("v1")
.withScope("Namespaced")
.withNewValidation()
.withNewOpenAPIV3SchemaLike(readSchema())
.endOpenAPIV3Schema()
.endValidation()
.endSpec()
.build();
CustomResourceDefinition crd = client.apiextensions().v1().customResourceDefinitions().resource(customResourceDefinition).create();
应用 CustomResourceDefinition
:
CustomResourceDefinition crd = client.apiextensions().v1().customResourceDefinitions().resource(customResourceDefinition).serverSideApply();
列出 CustomResourceDefinition
:
CustomResourceDefinitionList crdList = client.apiextensions().v1().customResourceDefinitions().list();
删除 CustomResourceDefinition
:
client.apiextensions().v1().customResourceDefinitions().withName("sparkclusters.radanalytics.io").delete();
资源类型化 API
任何资源(无论是自定义资源还是内置资源)都可以通过 client.resources(Class)
方法访问。
获取自定义资源的客户端实例:
MixedOperation<CronTab, KubernetesResourceList<CronTab>, Resource<CronTab>> cronTabClient = client.resources(CronTab.class);
从 Kubernetes API 服务器获取自定义资源:
CronTab ct = cronTabClient.inNamespace("default").withName("my-second-cron-object").get();
创建 CustomResource
:
cronTabClient.inNamespace("default").create(cronTab1);
列出 CustomResource
:
CronTabList cronTabList = cronTabClient.inNamespace("default").list();
删除 CustomResource
:
cronTabClient.inNamespace("default").withName("my-third-cron-object").delete();
替换 CustomResource
的状态:
cronTabClient.inNamespace("default").resource(updatedCronTab).updateStatus();
修补 CustomResource
的状态:
cronTabClient.inNamespace("default").resource(updatedCronTab).patchStatus();
编辑 CustomResource
的状态:
cronTabClient.inNamespace("default").resource(cronTab1).editStatus(cronTab -> updatedCronTab);
监听 CustomResource
:
cronTabClient.inNamespace("default").watch(new Watcher<>() {
@Override
public void eventReceived(Action action, CronTab resource) {
// 根据操作类型执行某些操作
}
@Override
public void onClose(WatcherException cause) {
// 处理关闭事件
}
});
无类型资源
如果你不需要或不想使用强类型的客户端,Kubernetes 客户端还提供了一个无类型/原始 API 来处理资源。
创建 ResourceDefinitionContext
:
ResourceDefinitionContext resourceDefinitionContext = new ResourceDefinitionContext.Builder()
.withGroup("jungle.example.com")
.withVersion("v1")
.withPlural("animals")
.withNamespaced(true)
.build();
从 YAML 文件加载资源:
GenericKubernetesResource customResource = client.genericKubernetesResources(context).load(new FileInputStream("cr.yaml")).item();
从 Kubernetes API 服务器获取资源:
GenericKubernetesResource customResourceObject = client.genericKubernetesResources(resourceDefinitionContext).inNamespace(currentNamespace).withName("otter").get();
创建资源:
GenericKubernetesResource object = client.genericKubernetesResources(resourceDefinitionContext).inNamespace(currentNamespace).load(new FileInputStream("test-rawcustomresource.yml")).create();
列出 CustomResource
:
GenericKubernetesResourceList list = client.genericKubernetesResources(resourceDefinitionContext).inNamespace(currentNamespace).list();
更新 CustomResource
:
GenericKubernetesResource walrus = client.genericKubernetesResources(resourceDefinitionContext).inNamespace(currentNamespace).withName("walrus").get();
Map<String, Object> spec = (Map<String, Object>) walrus.getAdditionalProperties().get("spec");
spec.put("image", "my-updated-awesome-walrus-image");
walrus.getAdditionalProperties().put("spec", spec);
client.genericKubernetesResources(resourceDefinitionContext).inNamespace(currentNamespace).resource(walrus).update();
删除 CustomResource
:
client.genericKubernetesResources(resourceDefinitionContext).inNamespace(currentNamespace).withName("otter").delete();
监听 CustomResource
:
final CountDownLatch closeLatch = new CountDownLatch(1);
client.genericKubernetesResources(crdContext).inNamespace(namespace).watch(new Watcher<>() {
@Override
public void eventReceived(Action action, GenericKubernetesResource resource) {
logger.info("{}: {}", action, resource);
}
@Override
public void onClose(WatcherException e) {
logger.debug("Watcher onClose");
closeLatch.countDown();
if (e != null) {
logger.error(e.getMessage(), e);
}
}
});
closeLatch.await(10, TimeUnit.MINUTES);
Spark Operator
以下示例展示了如何通过 Spark Operator 的示例以两种不同的方式为自定义资源定义相同的上下文。
类型化资源 API:
@Group("sparkoperator.k8s.io")
@Plural("sparkapps")
@Version("v1beta2")
@Kind("SparkApplication")
public class SparkOperatorResource extends GenericKubernetesResource implements Namespaced { ... }
使用类型化资源 API 的 SparkOperatorResource
:
kubernetesClient.resources(SparkOperatorResource.class).inNamespace("myNamespace")...
无类型资源 API:
public static ResourceDefinitionContext getResourceDefinitionContext() {
return new ResourceDefinitionContext.Builder()
.withGroup("sparkoperator.k8s.io")
.withPlural("sparkapps")
.withVersion("v1beta2")
.withKind("SparkApplication")
.withNamespaced(true)
.build();
}
使用无类型资源 API:
kubernetesClient.genericKubernetesResources(getResourceDefinitionContext()).inNamespace("myNamespace")...
通过这些 API,你可以灵活地管理和操作 Kubernetes 集群中的各种资源,无论是内置资源还是自定义资源。
FunTester 原创精华
【免费合集】从 Java 开始性能测试
故障测试与 Web 前端
服务端功能测试
性能测试专题
Java、Groovy、Go
测试开发、自动化、白盒
测试理论、FunTester 风采
视频专题