Skip to content

Unable to interact with cluster through Teleport #3242

@nicolas-goudry

Description

@nicolas-goudry

Describe the bug

Using a cluster with authn via Teleport, it is not possible to interact with the cluster.

This is working fine with kubectl and after testing with the Python client it works too. This seems to only happen with the Java client (I didn’t test other clients though).

Client Version

20

Kubernetes Version

1.28.6

Java Version

17

To Reproduce

  • configure your cluster with Teleport
  • generate a kubeconfig through tsh

Edit the KubeConfigFileClientExample:

diff --git a/examples/examples-release-20/src/main/java/io/kubernetes/client/examples/KubeConfigFileClientExample.java b/examples/examples-release-20/src/main/java/io/kubernetes/client/examples/KubeConfigFileClientExample.java
index 7a0ba4dcf..99a7cc75e 100644
--- a/examples/examples-release-20/src/main/java/io/kubernetes/client/examples/KubeConfigFileClientExample.java
+++ b/examples/examples-release-20/src/main/java/io/kubernetes/client/examples/KubeConfigFileClientExample.java
@@ -16,12 +16,13 @@ import io.kubernetes.client.openapi.ApiClient;
 import io.kubernetes.client.openapi.ApiException;
 import io.kubernetes.client.openapi.Configuration;
 import io.kubernetes.client.openapi.apis.CoreV1Api;
-import io.kubernetes.client.openapi.models.V1Pod;
-import io.kubernetes.client.openapi.models.V1PodList;
+import io.kubernetes.client.openapi.models.V1Namespace;
+import io.kubernetes.client.openapi.models.V1ObjectMeta;
 import io.kubernetes.client.util.ClientBuilder;
 import io.kubernetes.client.util.KubeConfig;
 import java.io.FileReader;
 import java.io.IOException;
+import java.nio.file.Paths;
 
 /**
  * A simple example of how to use the Java API from an application outside a kubernetes cluster
@@ -37,10 +38,12 @@ public class KubeConfigFileClientExample {
     // file path to your KubeConfig
 
     String kubeConfigPath = System.getenv("HOME") + "/.kube/config";
+    KubeConfig kubeconfig = KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath));
+    kubeconfig.setFile(Paths.get(kubeConfigPath).toFile());
 
     // loading the out-of-cluster config, a kubeconfig from file-system
     ApiClient client =
-        ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath))).build();
+        ClientBuilder.kubeconfig(kubeconfig).build();
 
     // set the global default api-client to the in-cluster one from above
     Configuration.setDefaultApiClient(client);
@@ -48,11 +51,11 @@ public class KubeConfigFileClientExample {
     // the CoreV1Api loads default api-client from global configuration.
     CoreV1Api api = new CoreV1Api();
 
-    // invokes the CoreV1Api client
-    V1PodList list =
-        api.listPodForAllNamespaces().execute();
-    for (V1Pod item : list.getItems()) {
-      System.out.println(item.getMetadata().getName());
-    }
+    V1Namespace ns = new V1Namespace();
+    V1ObjectMeta meta = new V1ObjectMeta();
+    meta.setName("test");
+    ns.setMetadata(meta);
+    V1Namespace result = api.createNamespace(ns).pretty("true").execute();
+    System.out.println(result.getMetadata().getName());
   }
 }

Run the example:

cd examples/examples-release-20
mvn -X clean install exec:java -Dexec.mainClass="io.kubernetes.client.examples.KubeConfigFileClientExample"

Expected behavior

The namespace is created.

KubeConfig

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: REDACTED
    server: REDACTED
    tls-server-name: REDACTED
  name: REDACTED
contexts:
- context:
    cluster: REDACTED
    extensions:
    - extension: sandbox
      name: teleport.kube.name
    user: REDACTED
  name: REDACTED
current-context: REDACTED
kind: Config
preferences: {}
users:
- name: REDACTED
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
      - kube
      - credentials
      - --kube-cluster=sandbox
      - --teleport-cluster=REDACTED
      - --proxy=REDACTED
      command: tsh
      env: null
      provideClusterInfo: false

Server (please complete the following information):

  • OS: Linux
  • Environment: system
  • Cloud: Azure/Teleport

Additional context

My user has limited permissions, but I should be able to create a namespace:

$ kubectl auth can-i --list
Resources                                       Non-Resource URLs   Resource Names   Verbs
selfsubjectreviews.authentication.k8s.io        []                  []               [create]
selfsubjectaccessreviews.authorization.k8s.io   []                  []               [create]
selfsubjectrulesreviews.authorization.k8s.io    []                  []               [create]
namespaces.*                                    []                  []               [get list watch create delete]
nodes                                           []                  []               [get list watch]
                                                [/api/*]            []               [get]
                                                [/api]              []               [get]
                                                [/apis/*]           []               [get]
                                                [/apis]             []               [get]
                                                [/healthz]          []               [get]
                                                [/healthz]          []               [get]
                                                [/livez]            []               [get]
                                                [/livez]            []               [get]
                                                [/openapi/*]        []               [get]
                                                [/openapi]          []               [get]
                                                [/readyz]           []               [get]
                                                [/readyz]           []               [get]
                                                [/version/]         []               [get]
                                                [/version/]         []               [get]
                                                [/version]          []               [get]
                                                [/version]          []               [get]

Metadata

Metadata

Assignees

No one assigned

    Labels

    lifecycle/frozenIndicates that an issue or PR should not be auto-closed due to staleness.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions