一、简介
在本教程中,我们将探索使用 Kubernetes Java API 过滤资源的不同方法。
在之前介绍 Kubernetes Java API 的文章中,我们重点介绍了查询、操作和监控集群资源的可用方法。
这些示例假设我们要么正在寻找特定类型的资源,要么针对单一资源。 然而,在实践中,大多数应用程序需要一种基于某些标准来定位资源的方法。
Kubernetes 的 API 支持三种方法来限制这些搜索的范围:
- 命名空间:范围仅限于给定的 Kubernetes命名空间
- 字段选择器:范围仅限于具有匹配字段值的资源
- 标签选择器:范围仅限于具有匹配标签的资源
此外,我们可以将这些方法组合到一个查询中 。这为我们提供了很大的灵活性来满足复杂的需求。
现在,让我们更详细地了解每种方法。
2. 使用命名空间
使用命名空间是限制查询范围的最基本方法。 顾名思义,命名空间查询仅返回指定命名空间内的项目。
在 Java API 中,命名空间查询方法遵循 listNamespacedXXX() 模式。 例如,要列出特定命名空间中的pod ,我们可以使用 listNamespacedPod() :
ApiClient client = Config.defaultClient();
CoreV1Api api = new CoreV1Api(client);
String ns = "ns1";
V1PodList items = api.listNamespacedPod(ns,null, null, null, null, null, null, null, null, 10, false);
items.getItems()
.stream()
.map((pod) -> pod.getMetadata().getName() )
.forEach((name) -> System.out.println("name=" + name));
这里使用 ApliClient 和 CoreV1Api 来进行对Kubernetes API服务器的实际访问。我们使用 ns1 作为命名空间来过滤资源。我们还使用与非命名空间方法中类似的其余参数。
正如预期的那样,命名空间查询也有 调用 变体,因此允许我们使用前面描述的相同技术创建 监视 。异步调用和分页的工作方式也与其非命名空间版本相同。
3. 使用字段选择器
命名空间 API 调用使用起来很简单,但有一些限制:
- 这是要么全有要么全无的情况,这意味着我们不能选择多个(但不是全部)命名空间
- 无法根据资源属性进行过滤
- 对每个场景使用不同的方法会导致更复杂/冗长的客户端代码
字段选择器提供了一种根据其中一个 字段 的值来选择资源的方法 。 Kubernetes 术语中的 字段 只是与资源的 YAML 或 JSON 文档中给定值关联的 JSON 路径。例如,这是运行 Apache HTTP 服务器的 pod 的典型 Kubernetes YAML:
apiVersion: v1
kind: Pod
metadata:
labels:
app: httpd
name: httpd-6976bbc66c-4lbdp
namespace: ns1
spec:
... fields omitted
status:
... fields omitted
phase: Running
status.phase 字段 包含现有 Pod 的状态。 相应的 字段选择器 表达式只是字段名称后跟运算符和值。现在,让我们编写一个查询,返回所有命名空间中所有正在运行的 pod:
String fs = "status.phase=Running";
V1PodList items = api.listPodForAllNamespaces(null, null, fs, null, null, null, null, null, 10, false);
// ... process items
字段选择器表达式仅支持相等(“=”或“==”)和不等(“!=”)运算符。此外,我们可以在同一个调用中传递多个逗号分隔的表达式。 在这种情况下,最终效果是它们将被组合在一起以产生最终结果:
String fs = "metadata.namespace=ns1,status.phase=Running";
V1PodList items = api.listPodForAllNamespaces(null, null, fs, null, null, null, null, null, 10, false);
// ... process items
请注意:字段值区分大小写! 在前面的查询中,使用“running”而不是“Running”(大写“R”)将产生空结果集。
字段选择器的一个重要限制是它们依赖于资源。所有资源类型仅支持 metadata.name 和 metadata.namespace 字段。
尽管如此,字段选择器在与动态字段一起使用时特别有用。上一个示例中的 status.phase 就是一个示例。将字段选择器与 Watch 结合使用, 我们可以轻松创建一个监控应用程序,该应用程序会在 pod 终止时收到通知。
4. 使用标签选择器
标签是包含任意键/值对的特殊字段,我们可以将其添加到任何 Kubernetes 资源作为其创建的一部分。标签选择器与字段选择器类似,因为它们本质上允许根据资源列表的值过滤资源列表,但提供了更大的灵活性:
- 支持其他运算符: in/notin/exists/not contains
- 与字段选择器相比,跨资源类型的使用保持一致
回到 Java API,我们通过使用所需条件构造字符串并将其作为参数传递给所需资源 API listXXX 调用来使用标签选择器。使用相等和/或不等式过滤特定标签值使用与字段选择器使用的相同语法。
让我们看看查找所有标签为“app”且值为“httpd”的 pod 的代码:
String ls = "app=httpd";
V1PodList items = api.listPodForAllNamespaces(null, null, null, ls, null, null, null, null, 10, false);
// ... process items
in 运算符类似于 SQL 对应项,允许我们在查询中创建一些 OR 逻辑:
String ls = "app in ( httpd, test )";
V1PodList items = api.listPodForAllNamespaces(null, null, null, ls, null, null, null, null, 10, false);
此外,我们可以使用 labelname 或 *!*labelname 语法检查字段是否存在:
String ls = "app";
V1PodList items = api.listPodForAllNamespaces(null, null, null, ls, null, null, null, null, 10, false);
最后,我们可以在单个 API 调用中链接多个表达式。生成的项目列表仅包含满足所有表达式的资源:
String ls = "app in ( httpd, test ),version=1,foo";
V1PodList items = api.listPodForAllNamespaces(null, null, null, ls, null, null, null, null, 10, false);
5. 结论
在本文中,我们介绍了使用 Java Kubernetes API 客户端过滤资源的不同方法。与往常一样,示例的完整源代码可以在 GitHub 上找到。