Безопасное обновление этикеток с помощью kubernetes-клиента - PullRequest
2 голосов
/ 03 апреля 2020

У меня есть набор модулей в моей среде kubernetes, которые действуют как «буферизованные ресурсы» (определяемые отсутствием определенной метки).

В моем приложении (использующем kubernetes-client) мне нравится проверьте, доступен ли буферизованный ресурс, и если да, добавьте метку, чтобы он больше не рассматривался для других запросов.

Однако, учитывая параллелизм, модуль, помеченный как буферизованный ресурс, может быть зарезервирован одновременное использование нескольких потоков, что приводит к возникновению всевозможных проблем в приложении.

Без блокировки запросов, отправляемых к kubernetes, существует безопасный способ добавить метку, только если ее ключ еще не существует ( и потерпеть неудачу в противном случае)?

Я использую io.fabric8.kubernetes.client, и код для обновления меток более или менее:

kubernetesClient.services().inNamespace(namespace).withName(resourceName).edit() //
        .editMetadata()
        /**/.addToLabels(Collections.unmodifiableMap(labels)) //
        .endMetadata() //
        .done();

Каков наилучший подход для обработки параллелизма при обращении к kubernetes api?

Редактировать: Я вижу, что k8s имеет ResourceVersion, но из моих первых тестов это не работает, как ожидалось:

Следующий запрос НЕ терпит неудачу, но успешно и даже назначает новую версию ресурса:

kubernetesClient.services().inNamespace(namespace).withName(resourceName).edit() //
        .editMetadata()
        .withResourceVersion("13213414141") // definitely does not match existing one
        /**/.addToLabels(Collections.unmodifiableMap(labels)) //
        .endMetadata() //
        .done();

Edit2: эквивалент kubectl - что-то вроде:

kubectl label pods mypod foo=bar --namespace my-name --resource-version="313"

, который будет правильно выдавать ошибку "объект был изменен; пожалуйста, примените ваши изменения к последней версии и попробуйте снова "

...