Перейти к основному содержимому

Использование пространств имен и селекторов с Java API Kubernetes

· 5 мин. чтения

1. Введение

В этом руководстве мы рассмотрим различные способы фильтрации ресурсов с помощью Java API Kubernetes.

В наших предыдущих статьях, посвященных Kubernetes Java API, мы сосредоточились на доступных методах запроса, управления и мониторинга ресурсов кластера.

В этих примерах предполагалось, что мы либо искали ресурсы определенного типа, либо нацеливались на один ресурс. На практике, однако, большинству приложений требуется способ обнаружения ресурсов на основе некоторых критериев.

API Kubernetes поддерживает три способа ограничения области поиска:

  • Пространства имен: область действия ограничена данным пространством имен Kubernetes.
  • Селекторы полей: область ограничена ресурсами, имеющими совпадающие значения полей
  • Селекторы меток: область ограничена ресурсами, имеющими совпадающие метки.

Более того, мы можем объединить эти методы в одном запросе . Это дает нам большую гибкость для удовлетворения даже сложных требований.

Теперь давайте рассмотрим каждый метод более подробно.

2. Использование пространств имен

Использование пространств имен — самый простой способ ограничить область запроса. Как следует из названия, запрос пространства имен возвращает элементы только в указанном пространстве имен.

В Java API методы запросов с именами следуют шаблону listNamespacedXXX(). Например, чтобы перечислить модули в определенном пространстве имен, мы использовали бы 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 в качестве пространства имен для фильтрации ресурсов. Мы также используем остальные аргументы, аналогичные тем, что используются в методе без пространства имен.

Как и ожидалось, запросы с пространством имен также имеют варианты вызова , что позволяет нам создавать Watch с использованием тех же методов, которые были описаны ранее . Асинхронные вызовы и пейджинг также работают так же, как и их версии без пространства имен.

3. Использование селекторов полей

Вызовы API с пространством имен просты в использовании, но имеют некоторые ограничения:

  • Это все или ничего, то есть мы не можем выбрать более одного (но не всех) пространств имен.
  • Нет возможности фильтровать по свойствам ресурса
  • Использование разных методов для каждого сценария приводит к более сложному/подробному клиентскому коду.

Селекторы полей предоставляют способ выбора ресурсов на основе значения одного из его полей . Поле на языке Kubernetes — это просто путь JSON, связанный с заданным значением в документе YAML или JSON ресурса. Например, это типичный YAML-код Kubernetes для модуля, на котором запущен HTTP-сервер Apache:

apiVersion: v1
kind: Pod
metadata:
labels:
app: httpd
name: httpd-6976bbc66c-4lbdp
namespace: ns1
spec:
... fields omitted
status:
... fields omitted
phase: Running

Поле status.phase содержит статус существующего пода. Соответствующее выражение селектора поля — это просто имя поля, за которым следуют оператор и значение. Теперь давайте напишем запрос, который возвращает все запущенные модули во всех пространствах имен:

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, мы можем легко создать приложение для мониторинга, которое получает уведомление, когда модули прекращают работу.

4. Использование селекторов ярлыков

Метки — это специальные поля, содержащие произвольные пары ключ/значение, которые мы можем добавить к любому ресурсу Kubernetes в процессе его создания. Селекторы меток аналогичны селекторам полей, поскольку они позволяют фильтровать список ресурсов на основе его значений, но обеспечивают большую гибкость:

  • Поддержка дополнительных операторов: in/notin/exists/not exists
  • Согласованное использование для разных типов ресурсов по сравнению с селекторами полей

Возвращаясь к Java API, мы используем селекторы меток, создавая строку с нужными критериями и передавая ее в качестве аргумента для вызова listXXX API желаемого ресурса . Фильтрация определенного значения метки с использованием равенства и/или неравенства использует тот же синтаксис, что и селекторы полей.

Давайте посмотрим на код, который ищет все модули, имеющие метку «приложение» со значением «httpd»:

String ls = "app=httpd";        
V1PodList items = api.listPodForAllNamespaces(null, null, null, ls, null, null, null, null, 10, false);
// ... process items

Оператор in похож на своего аналога в SQL и позволяет нам создавать некоторую логику ИЛИ в запросах:

String ls = "app in ( httpd, test )";        
V1PodList items = api.listPodForAllNamespaces(null, null, null, ls, null, null, null, null, 10, false);

Кроме того, мы можем проверить наличие или отсутствие поля, используя имя метки или ! Синтаксис имени метки:

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 .