一、简介
在本教程中,我们将使用其官方Java API 介绍对Kubernetes 资源的CRUD 操作。
我们已经在之前的文章中介绍了此API 使用的基础知识,包括基本的项目设置以及我们可以使用它来获取有关正在运行的集群的信息的各种方法。
一般来说,Kubernetes 部署大多是静态的。我们创建了一些工件(例如YAML 文件)来描述我们想要创建的内容并将它们提交到DevOps 管道。然后我们系统的各个部分保持不变,直到我们添加新组件或升级现有组件。
但是,有些情况下我们需要动态添加资源。常见的一种是运行 作为响应,应用程序将启动后台作业来处理报告并使其可用于以后检索。
这里的关键是,通过使用这些API,我们可以更好地利用可用的基础设施,因为我们可以仅在需要时消耗资源,然后再释放它们。
2. 创建新资源
在这个例子中,我们将在Kubernetes 集群中创建一个Job 资源。作业是一种Kubernetes 工作负载,与其他类型不同,它会一直运行到完成。也就是说,一旦在其pod 中运行的程序终止,作业本身就会终止。它的YAML 表示与其他资源没有什么不同:
apiVersion: batch/v1 kind: Job metadata: namespace: jobs name: report-job labels: app: reports spec: template: metadata: name: payroll-report spec: containers: - name: main image: report-runner command: - payroll args: - --date - 2021-05-01 restartPolicy: Never
Kubernetes API 提供了两种创建等效Java 对象的方法:
new
创建POJOS 并通过setter 填充所有必需的属性使用fluent API 构建Java 资源表示
使用哪种方法主要是个人喜好。在这里,我们将使用fluent 方法来创建V1Job
ApiClient client = Config.defaultClient(); BatchV1Api api = new BatchV1Api(client); V1Job body = new V1JobBuilder() .withNewMetadata() .withNamespace("report-jobs") .withName("payroll-report-job") .endMetadata() .withNewSpec() .withNewTemplate() .withNewMetadata() .addToLabels("name", "payroll-report") .endMetadata() .editOrNewSpec() .addNewContainer() .withName("main") .withImage("report-runner") .addNewCommand("payroll") .addNewArg("--date") .addNewArg("2021-05-01") .endContainer() .withRestartPolicy("Never") .endSpec() .endTemplate() .endSpec() .build(); V1Job createdJob = api.createNamespacedJob("report-jobs", body, null, null, null);
我们首先创建 资源是ApiClient
Job
Batch API,
BatchV1Api
接下来,我们实例化一个 注意嵌套构建器的使用:要“关闭”嵌套构建器,我们必须调用其V1JobBuilder
endXXX()
或者,也可以使用 当我们想要重用一组通用属性(例如元数据、标签和注释)时,这很有用。withXXX
最后一步只是调用API 存根。这将序列化我们的资源对象和POST 对服务器的请求。正如预期的那样,API 有同步(上面使用)和异步版本。
返回的对象将包含与创建的作业相关的元数据和状态字段。的情况下,我们可以使用它的status 字段来检查它何时完成。我们还可以使用我们关于监控资源的文章中介绍的一种技术来接收此通知。Job
3. 更新现有资源
更新现有资源包括向Kubernetes API 服务器发送PATCH 请求,其中包含我们要修改的字段。从Kubernetes 1.16 版开始,有四种方法可以指定这些字段:
JSON 补丁(RFC 6092)
JSON 合并补丁(RFC 7396)
战略合并补丁
应用YAML
其中,最后一个是最容易使用的,因为它将所有合并和冲突解决留给服务器:我们所要做的就是发送一个包含我们要修改的字段的YAML 文档。
不幸的是,Java API 没有提供构建这个部分YAML 文档的简单方法。相反,我们必须求助于 对象提供的内置JSON 序列化程序来获取它:PatchUtil
ApiClient
V1Job patchedJob = new V1JobBuilder(createdJob) .withNewMetadata() .withName(createdJob.getMetadata().getName()) .withNamespace(createdJob.getMetadata().getNamespace()) .endMetadata() .editSpec() .withParallelism(2) .endSpec() .build(); String patchedJobJSON = client.getJSON().serialize(patchedJob); PatchUtils.patch( V1Job.class, () -> api.patchNamespacedJobCall( createdJob.getMetadata().getName(), createdJob.getMetadata().getNamespace(), new V1Patch(patchedJobJSON), null, null, "baeldung", true, null), V1Patch.PATCH_FORMAT_APPLY_YAML, api.getApiClient());
在这里,我们使用从 在这种情况下,我们只是将 这里重要的一点是,当我们构建修改后的资源时,我们必须使用 有关托管字段的完整说明以及它们在Kubernetes 中的使用方式,请参阅createNamespacedJob()
parallelism
withNewMetadata().
一旦我们使用修改后的字段构建了一个对象,我们就可以使用 然后我们使用这个序列化版本来构造一个 方法还需要一个额外的参数,我们通知请求中存在的数据类型。在我们的例子中,这是serialize
V1Patch
patch
PATCH_FORMAT_APPLY_YAML
Content-Type
传递给 当两个或多个客户端尝试修改同一资源时,Kubernetes 在内部使用此值来解决最终冲突。我们还在fieldManager
“baeldung”
force
true
4. 删除资源
与之前的操作相比,删除资源非常简单:
V1Status response = api.deleteNamespacedJob( createdJob.getMetadata().getName(), createdJob.getMetadata().getNamespace(), null, null, null, null, null, null ) ;
在这里,我们只是使用 如果需要,我们可以使用最后一个参数来控制删除过程的细节。这采用deleteNamespacedJob
V1DeleteOptions
0 评论