Исключение JsonMappingException при загрузке конфигурации yaml Kafka через Fabric8io kubernetes-клиент

#java #kubernetes #fabric8

Вопрос:

У меня проблема с использованием fabric8io kubernetes-клиента.

Что я хочу: Создать кластер Кафки с оператором Стримзи в Кубернетесе. Если я сделаю все шаги из руководства по быстрому запуску Strimzi с помощью CLI и kubectl, все будет хорошо.

Но когда я загружаю ресурсы yaml с kubernetes-client:5.2.1 библиотекой из кода Java, возникает исключение:

 io.fabric8.kubernetes.client.KubernetesClientException: An error has occurred.
  at io.fabric8.kubernetes.client.KubernetesClientException.launderThrowable(KubernetesClientException.java:64)
  at io.fabric8.kubernetes.client.KubernetesClientException.launderThrowable(KubernetesClientException.java:53)
  at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:140)
  at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:101)
  at io.fabric8.kubernetes.client.dsl.internal.NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl.<init>(NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl.java:272)
  at io.fabric8.kubernetes.client.dsl.internal.NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl.<init>(NamespaceVisitFromServerGetWatchDeleteRecreateWaitApplicableListImpl.java:252)
  at io.fabric8.kubernetes.client.DefaultKubernetesClient$1.<init>(DefaultKubernetesClient.java:175)
  at io.fabric8.kubernetes.client.DefaultKubernetesClient.load(DefaultKubernetesClient.java:175)
  at app.test.main(test.java:38)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: No resource type found for:kafka.strimzi.io/v1#Kafka
 at [Source: (String)"{"apiVersion":"kafka.strimzi.io/v1","kind":"Kafka","metadata":{"name":"my-cluster"},"spec":{"kafka":{"replicas":1,"listeners":[{"name":"plain","port":9092,"type":"internal","tls":false},{"name":"tls","port":9093,"type":"internal","tls":true,"authentication":{"type":"tls"}},{"name":"external","port":9094,"type":"nodeport","tls":false}],"storage":{"type":"jbod","volumes":[{"id":0,"type":"persistent-claim","size":"1Gi","deleteClaim":false}]},"config":{"offsets.topic.replication.factor":1,"transacti"[truncated 226 chars]; line: 1, column: 726]
 

Проблема возникает при загрузке этого файла: конфигурация yaml.

Я загружаю ресурс, как:

  KubernetesClient client = new DefaultKubernetesClient();
InputStream is = ...;
client.load(is).inNamespace("my_namespace").createOrReplace();
 

Пожалуйста, помогите мне!

P. S: И извините за мой английский.

Комментарии:

1. Здравствуйте, Kafka это пользовательский ресурс. Пожалуйста, взгляните на API пользовательских ресурсов клиента Fabric8 Kubernetes: github.com/fabric8io/kubernetes-client/blob/master/doc/…

Ответ №1:

Я из команды Fabric8. Kafka является пользовательским ресурсом, что означает, что его модель не зарегистрирована в KubernetesClient, поэтому именно по этой причине вы столкнулись No resource type found for:kafka.strimzi.io/v1#Kafka с ошибкой KubenetesClient. KubernetesClient предоставляет два метода работы с пользовательскими ресурсами:

  1. API без типов — Использование пользовательских ресурсов в качестве необработанных хэш-карт
  2. Типизированный API — Предоставляет POJO для пользовательских типов ресурсов

Я приведу примеры использования обоих API для загрузки вашего фрагмента Kafka yaml.

API без типов:

Для API без типов вам нужно будет предоставить CustomResourceDefinitionContext объект с подробной информацией о группе пользовательских ресурсов, версии, виде, множественном числе и т.д. Вот как это будет выглядеть: KafkaLoadTypeless.java

 try (KubernetesClient client = new DefaultKubernetesClient()) {
    CustomResourceDefinitionContext context = new CustomResourceDefinitionContext.Builder()
            .withScope("Namespaced")
            .withVersion("v1beta2")
            .withGroup("kafka.strimzi.io")
            .withPlural("kafkas")
            .build();

    InputStream is = KafkaLoadTypeles.class.getResourceAsStream("/test-kafka.yml");

    Map<String, Object> createdKafka = client.customResource(context).inNamespace("default").createOrReplace(is);
} catch (IOException ioException) {
    ioException.printStackTrace();
}
 

Типизированный API:

Для типизированного API вам потребуется указать типы Kafka ресурсов. Вы можете найти эти типы в зависимости API Strimzi. Мне пришлось добавить эту зависимость в свой проект, чтобы использовать Kafka классы:

         <dependency>
            <groupId>io.strimzi</groupId>
            <artifactId>api</artifactId>
            <version>0.22.0</version>
            <exclusions>
                <exclusion>
                    <groupId>io.fabric8</groupId>
                    <artifactId>kubernetes-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
 

После добавления этого я смог использовать типизированный API следующим образом:
KafkaLoadTyped.java

 try (KubernetesClient client = new DefaultKubernetesClient()) {
    MixedOperation<Kafka, KafkaList, Resource<Kafka>> kafkaClient = client.customResources(Kafka.class, KafkaList.class);

    InputStream is = KafkaLoadTyped.class.getResourceAsStream("/test-kafka.yml");
    Kafka myClusterkafka = kafkaClient.load(is).get();
    kafkaClient.inNamespace("default").createOrReplace(myClusterkafka);
}
 

Комментарии:

1. Потрясающий ответ, спасибо!

2. Нп, рад помочь 🙂 !