kubernetes-client / java

Official Java client library for kubernetes
http://kubernetes.io/
Apache License 2.0
3.56k stars 1.9k forks source link

Build client from specific KubeConfig #3422

Closed yousefZw closed 4 months ago

yousefZw commented 4 months ago

Describe the bug When attempting to create a client using a specific "KubeConfig", I encounter the following error message:

Exception in thread "main" java.lang.IllegalArgumentException: No server in kubeconfig
    at io.kubernetes.client.util.ClientBuilder.kubeconfig(ClientBuilder.java:281)
    at com.tsystems.Main.main(Main.java:30)

Java Version graalvm-jdk-22.0.1_8.1 **OS Version*** Windows 11

Client Version 20.0.0

Kubernetes Version 1.28+ Server Version: version.Info{Major:"1", Minor:"28+", GitVersion:"v1.28.8-caas"

To Reproduce See Code.

Code

public static void main(String[] args) throws IOException, ApiException {

        final String userHome = System.getProperty("user.home");
        String kubeConfigPath = String.format("%s/.kube/config-files/cXXX.kubeconfig", userHome);

        ApiClient client = ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new InputStreamReader(new FileInputStream(kubeConfigPath), StandardCharsets.UTF_8))).build();
        Configuration.setDefaultApiClient(client);

        CoreV1Api api = new CoreV1Api();
        V1NamespaceList list =  api.listNamespace().execute();
        for (var item : list.getItems()) {
            System.out.println(item.getMetadata().getName());
        }
    }

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.examples</groupId>
    <artifactId>deployment</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>22</maven.compiler.source>
        <maven.compiler.target>22</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>io.kubernetes</groupId>
            <artifactId>client-java-api</artifactId>
            <version>20.0.0</version>
        </dependency>
        <dependency>
            <groupId>io.kubernetes</groupId>
            <artifactId>client-java</artifactId>
            <version>20.0.0</version>
        </dependency>
        <dependency>
            <groupId>io.kubernetes</groupId>
            <artifactId>client-java-extended</artifactId>
            <version>20.0.0</version>
        </dependency>
        <dependency>
            <groupId>io.kubernetes</groupId>
            <artifactId>client-java-spring-integration</artifactId>
            <version>20.0.0</version>
        </dependency>
        <dependency>
            <groupId>io.kubernetes</groupId>
            <artifactId>client-java-proto</artifactId>
            <version>20.0.0</version>
        </dependency>
        <dependency>
            <groupId>commons-cli</groupId>
            <artifactId>commons-cli</artifactId>
            <version>1.7.0</version>
        </dependency>
        <dependency>
            <groupId>io.kubernetes</groupId>
            <artifactId>client-java-cert-manager-models</artifactId>
            <version>10.0.1</version>
        </dependency>
        <dependency>
            <groupId>io.kubernetes</groupId>
            <artifactId>client-java-prometheus-operator-models</artifactId>
            <version>10.0.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <archive>
                                <manifest>
                                    <mainClass>
                                        com.examples.Main
                                    </mainClass>
                                </manifest>
                            </archive>
                            <descriptorRefs>
                                <descriptorRef>jar-with-dependencies</descriptorRef>
                            </descriptorRefs>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

KubeConfig

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: xxxxx
    server: https://xx.xx.xx.xx:6443
  name: cXXX
contexts:
- context:
    cluster: cXXX
    user: cXXX-admin
  name: demo-staging
current-context: cXXX-admin
kind: Config
preferences: {}
users:
- name: cXXX-admin
  user:
    client-certificate-data: xxxxx
    client-key-data: xxxxx

Server (please complete the following information):

Additional context Add any other context about the problem here.

tamilselvan1102 commented 4 months ago

Not sure but check your current-context

tamilselvan1102 commented 4 months ago

you can check by kubectl config view

yousefZw commented 4 months ago

I've managed to resolve the issue through debugging, and it's now working correctly for me:

        final String userHome = System.getProperty("user.home");
        // file path to your KubeConfig
        String kubeConfigPath = String.format("%s/.kube/config-files/cxxxx.kubeconfig", userHome);

        KubeConfig config = KubeConfig.loadKubeConfig(new InputStreamReader(new FileInputStream(kubeConfigPath), StandardCharsets.UTF_8));
// Solution: Refer to the KubeConfig details in the issue description.
// This specifies the context name from the config file.
        config.setContext("demo-staging");

        ApiClient client = ClientBuilder.kubeconfig(config).build();
        Configuration.setDefaultApiClient(client);
yousefZw commented 4 months ago

you can check by kubectl config view

Thank you! I've found the solution, which you can see in my comment. It turns out that 'KubeConfig' requires the context name in order to retrieve the server name. This wasn't being initialized properly in the 'loadKubeConfig' method. I hope I got that right, but it now works after I set the context with the name separately.

tamilselvan1102 commented 4 months ago

Thank you. Please close the issue

yousefZw commented 4 months ago

See solution in comments above.