简单的 Kubernetes Spring-Boot 运算符问题

问题描述 投票:0回答:1

所以我最近的任务是构建一个简单的 k8s 运算符,该运算符的 CRD 只包含一个字符串。每当创建该类型的新资源时,它都会读取该字符串并将其记录到 Pod 日志中。听起来很简单吧?

好吧,考虑到我几乎没有任何使用 k8s 的经验,也没有制作操作符的经验,所以我在网上找到了一些教程,解释了如何使用 spring-boot 构建操作符(我的任务的一部分是我必须使用弹簧启动)。我已按照本教程进行操作,然后尝试出于我的目的更改代码,但我不断收到 ChatGPT 描述为库版本不匹配的错误,并且我不知道如何解决此问题。

2024-03-27T12:10:33.700Z  INFO 1 --- [operator] [           main] d.example.operator.OperatorApplication   : Starting OperatorApplication v0.0.1-SNAPSHOT using Java 17.0.2 with PID 1 (/app.jar started by root in /)
2024-03-27T12:10:33.702Z  INFO 1 --- [operator] [           main] d.example.operator.OperatorApplication   : No active profile set, falling back to 1 default profile: "default"
2024-03-27T12:10:34.241Z  WARN 1 --- [operator] [           main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'kubernetesClient' defined in class path resource [io/javaoperatorsdk/operator/springboot/starter/OperatorAutoConfiguration.class]: Failed to instantiate [io.fabric8.kubernetes.client.KubernetesClient]: Factory method 'kubernetesClient' threw exception with message: class io.fabric8.kubernetes.client.okhttp.OkHttpClientImpl overrides final method io.fabric8.kubernetes.client.http.StandardHttpClient.close()V
2024-03-27T12:10:34.246Z  INFO 1 --- [operator] [           main] .s.b.a.l.ConditionEvaluationReportLogger : 

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2024-03-27T12:10:34.254Z ERROR 1 --- [operator] [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'kubernetesClient' defined in class path resource [io/javaoperatorsdk/operator/springboot/starter/OperatorAutoConfiguration.class]: Failed to instantiate [io.fabric8.kubernetes.client.KubernetesClient]: Factory method 'kubernetesClient' threw exception with message: class io.fabric8.kubernetes.client.okhttp.OkHttpClientImpl overrides final method io.fabric8.kubernetes.client.http.StandardHttpClient.close()V
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:648) ~[spring-beans-6.1.5.jar!/:6.1.5]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:636) ~[spring-beans-6.1.5.jar!/:6.1.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1335) ~[spring-beans-6.1.5.jar!/:6.1.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1165) ~[spring-beans-6.1.5.jar!/:6.1.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562) ~[spring-beans-6.1.5.jar!/:6.1.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.5.jar!/:6.1.5]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.1.5.jar!/:6.1.5]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.5.jar!/:6.1.5]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.1.5.jar!/:6.1.5]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.5.jar!/:6.1.5]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) ~[spring-beans-6.1.5.jar!/:6.1.5]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:962) ~[spring-context-6.1.5.jar!/:6.1.5]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624) ~[spring-context-6.1.5.jar!/:6.1.5]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.2.4.jar!/:3.2.4]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.2.4.jar!/:3.2.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) ~[spring-boot-3.2.4.jar!/:3.2.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354) ~[spring-boot-3.2.4.jar!/:3.2.4]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-3.2.4.jar!/:3.2.4]
    at de.example.operator.OperatorApplication.main(OperatorApplication.java:10) ~[!/:0.0.1-SNAPSHOT]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:91) ~[app.jar:0.0.1-SNAPSHOT]
    at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:53) ~[app.jar:0.0.1-SNAPSHOT]
    at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:58) ~[app.jar:0.0.1-SNAPSHOT]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.fabric8.kubernetes.client.KubernetesClient]: Factory method 'kubernetesClient' threw exception with message: class io.fabric8.kubernetes.client.okhttp.OkHttpClientImpl overrides final method io.fabric8.kubernetes.client.http.StandardHttpClient.close()V
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:177) ~[spring-beans-6.1.5.jar!/:6.1.5]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:644) ~[spring-beans-6.1.5.jar!/:6.1.5]
    ... 25 common frames omitted
Caused by: java.lang.IncompatibleClassChangeError: class io.fabric8.kubernetes.client.okhttp.OkHttpClientImpl overrides final method io.fabric8.kubernetes.client.http.StandardHttpClient.close()V
    at java.base/java.lang.ClassLoader.defineClass1(Native Method) ~[na:na]
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012) ~[na:na]
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150) ~[na:na]
    at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:524) ~[na:na]
    at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:427) ~[na:na]
    at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:421) ~[na:na]
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:712) ~[na:na]
    at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:420) ~[na:na]
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:587) ~[na:na]
    at org.springframework.boot.loader.net.protocol.jar.JarUrlClassLoader.loadClass(JarUrlClassLoader.java:104) ~[app.jar:0.0.1-SNAPSHOT]
    at org.springframework.boot.loader.launch.LaunchedClassLoader.loadClass(LaunchedClassLoader.java:91) ~[app.jar:0.0.1-SNAPSHOT]
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[na:na]
    at io.fabric8.kubernetes.client.okhttp.OkHttpClientBuilderImpl.completeBuild(OkHttpClientBuilderImpl.java:122) ~[kubernetes-httpclient-okhttp-6.9.2.jar!/:na]
    at io.fabric8.kubernetes.client.okhttp.OkHttpClientBuilderImpl.initialBuild(OkHttpClientBuilderImpl.java:94) ~[kubernetes-httpclient-okhttp-6.9.2.jar!/:na]
    at io.fabric8.kubernetes.client.okhttp.OkHttpClientBuilderImpl.build(OkHttpClientBuilderImpl.java:55) ~[kubernetes-httpclient-okhttp-6.9.2.jar!/:na]
    at io.fabric8.kubernetes.client.okhttp.OkHttpClientBuilderImpl.build(OkHttpClientBuilderImpl.java:36) ~[kubernetes-httpclient-okhttp-6.9.2.jar!/:na]
    at io.fabric8.kubernetes.client.KubernetesClientBuilder.getHttpClient(KubernetesClientBuilder.java:93) ~[kubernetes-client-api-6.11.0.jar!/:na]
    at io.fabric8.kubernetes.client.KubernetesClientBuilder.build(KubernetesClientBuilder.java:78) ~[kubernetes-client-api-6.11.0.jar!/:na]
    at io.javaoperatorsdk.operator.springboot.starter.OperatorAutoConfiguration.lambda$kubernetesClient$3(OperatorAutoConfiguration.java:61) ~[operator-framework-spring-boot-starter-5.4.1.jar!/:na]
    at java.base/java.util.Optional.orElseGet(Optional.java:364) ~[na:na]
    at io.javaoperatorsdk.operator.springboot.starter.OperatorAutoConfiguration.kubernetesClient(OperatorAutoConfiguration.java:60) ~[operator-framework-spring-boot-starter-5.4.1.jar!/:na]
    at io.javaoperatorsdk.operator.springboot.starter.OperatorAutoConfiguration$$SpringCGLIB$$0.CGLIB$kubernetesClient$3(<generated>) ~[operator-framework-spring-boot-starter-5.4.1.jar!/:na]
    at io.javaoperatorsdk.operator.springboot.starter.OperatorAutoConfiguration$$SpringCGLIB$$FastClass$$1.invoke(<generated>) ~[operator-framework-spring-boot-starter-5.4.1.jar!/:na]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:258) ~[spring-core-6.1.5.jar!/:6.1.5]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-6.1.5.jar!/:6.1.5]
    at io.javaoperatorsdk.operator.springboot.starter.OperatorAutoConfiguration$$SpringCGLIB$$0.kubernetesClient(<generated>) ~[operator-framework-spring-boot-starter-5.4.1.jar!/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:140) ~[spring-beans-6.1.5.jar!/:6.1.5]
    ... 26 common frames omitted

我的 spring-boot 项目中目前有以下代码。

MyCustomResource.java

package de.example.operator;

import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.api.model.Namespaced;
import io.javaoperatorsdk.operator.api.ObservedGenerationAwareStatus;
import io.fabric8.kubernetes.model.annotation.Group;
import io.fabric8.kubernetes.model.annotation.Version;

@Group("de.example")
@Version("v1")
public class MyCustomResource extends CustomResource<MyCustomSpec, ObservedGenerationAwareStatus> implements Namespaced {
}

MyCustomResourceReconciler.java

package de.example.operator;

import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration;
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;

@Component
@ControllerConfiguration
public class MyCustomResourceReconciler implements Reconciler<MyCustomResource> {
    
    private static final Logger log = LoggerFactory.getLogger(MyCustomResourceReconciler.class);

    @Override
    public UpdateControl<MyCustomResource> reconcile(MyCustomResource resource, Context<MyCustomResource> context) {
        String message = resource.getSpec().getMessage();
        log.info("Message from CR {}: {}", resource.getMetadata().getName(), message);
        return UpdateControl.noUpdate();
    }
}

MyCustomSpec.java

package de.example.operator;

public class MyCustomSpec {
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

OperatorApplication.java

package de.example.operator;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class OperatorApplication {

    public static void main(String[] args) {
        SpringApplication.run(OperatorApplication.class, args);
    }

}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>de.example</groupId>
    <artifactId>operator</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>operator</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.javaoperatorsdk</groupId>
            <artifactId>operator-framework-spring-boot-starter</artifactId>
            <version>5.4.1</version>
        </dependency>

        <dependency>
            <groupId>io.javaoperatorsdk</groupId>
            <artifactId>operator-framework-spring-boot-starter-test</artifactId>
            <version>5.4.1</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>log4j-slf4j2-impl</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>io.fabric8</groupId>
            <artifactId>crd-generator-apt</artifactId>
            <version>6.11.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk18on</artifactId>
            <version>1.77</version>
        </dependency>

        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcpkix-jdk18on</artifactId>
            <version>1.77</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

也许有人能看出问题出在哪里?

java spring-boot kubernetes operator-sdk
1个回答
0
投票

问题是最新版本的operatorsdk没有使用最新版本的fabric8。将我的 crd 生成器的依赖项版本更改为 6.9.2(如操作员 SDK 的依赖项树中所示)后,代码运行完美。

© www.soinside.com 2019 - 2024. All rights reserved.