Quarkus extension providing integration with Kubernetes clusters through the Fabric8 Kubernetes Client for building cloud-native applications and operators
npx @tessl/cli install tessl/maven-io-quarkus--quarkus-kubernetes-client@3.26.0The Quarkus Kubernetes Client extension provides seamless integration with Kubernetes clusters through the Fabric8 Kubernetes Client. It enables developers to build cloud-native applications that interact with Kubernetes APIs, create operators, watch resources, and manage complex distributed systems with full CDI integration and native compilation support.
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-kubernetes-client</artifactId>
</dependency>import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.Config;
import io.quarkus.kubernetes.client.KubernetesConfigCustomizer;
import io.quarkus.kubernetes.client.KubernetesClientObjectMapperCustomizer;
import jakarta.inject.Inject;import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.Watcher;
import io.fabric8.kubernetes.client.WatcherException;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.PodList;
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
import jakarta.inject.Inject;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class KubernetesService {
@Inject
KubernetesClient kubernetesClient;
public void listPods() {
// List all pods in the default namespace
PodList pods = kubernetesClient.pods().list();
for (Pod pod : pods.getItems()) {
System.out.println("Pod: " + pod.getMetadata().getName());
}
}
public void createConfigMap() {
// Create a ConfigMap
kubernetesClient.configMaps()
.create(new ConfigMapBuilder()
.withNewMetadata()
.withName("my-config")
.withNamespace("default")
.endMetadata()
.addToData("key", "value")
.build());
}
public void watchPods() {
// Watch for pod changes
kubernetesClient.pods().watch(new Watcher<Pod>() {
@Override
public void eventReceived(Action action, Pod pod) {
System.out.println("Pod " + action + ": " + pod.getMetadata().getName());
}
@Override
public void onClose(WatcherException cause) {
// Handle close
}
});
}
}The Quarkus Kubernetes Client extension bridges the Fabric8 Kubernetes Client with Quarkus's CDI container and native compilation capabilities:
Configure the Kubernetes client using application.properties:
# Connection settings
quarkus.kubernetes-client.api-server-url=https://kubernetes.example.com:6443
# Deprecated: Use api-server-url instead
quarkus.kubernetes-client.master-url=https://kubernetes.example.com:6443
quarkus.kubernetes-client.namespace=my-namespace
quarkus.kubernetes-client.trust-certs=true
# Authentication
quarkus.kubernetes-client.token=${KUBERNETES_TOKEN}
quarkus.kubernetes-client.ca-cert-file=/path/to/ca.crt
quarkus.kubernetes-client.client-cert-file=/path/to/client.crt
quarkus.kubernetes-client.client-key-file=/path/to/client.key
# Timeouts and retries
quarkus.kubernetes-client.connection-timeout=PT10S
quarkus.kubernetes-client.request-timeout=PT30S
quarkus.kubernetes-client.request-retry-backoff-limit=5
quarkus.kubernetes-client.request-retry-backoff-interval=PT1S
# Watch settings
quarkus.kubernetes-client.watch-reconnect-interval=PT30S
quarkus.kubernetes-client.watch-reconnect-limit=10
# Proxy settings
quarkus.kubernetes-client.http-proxy=http://proxy.example.com:8080
quarkus.kubernetes-client.https-proxy=https://proxy.example.com:8443
quarkus.kubernetes-client.proxy-username=proxyuser
quarkus.kubernetes-client.proxy-password=proxypass
quarkus.kubernetes-client.no-proxy=localhost,127.0.0.1
# RBAC generation
quarkus.kubernetes-client.generate-rbac=true
# DevServices (for testing)
quarkus.kubernetes-client.devservices.enabled=true
quarkus.kubernetes-client.devservices.api-version=v1.28.0
quarkus.kubernetes-client.devservices.image-name=kindest/node:v1.28.0
quarkus.kubernetes-client.devservices.flavor=kind
quarkus.kubernetes-client.devservices.override-kubeconfig=false
quarkus.kubernetes-client.devservices.manifests=/path/to/manifest1.yaml,/path/to/manifest2.yaml
quarkus.kubernetes-client.devservices.shared=true
quarkus.kubernetes-client.devservices.service-name=kubernetes
quarkus.kubernetes-client.devservices.container-env.ENV_VAR=valueDirect injection of fully configured KubernetesClient instances via CDI.
@Inject
KubernetesClient kubernetesClient;The KubernetesClient is produced by:
@Singleton
public class KubernetesClientProducer {
@DefaultBean
@Singleton
@Produces
public KubernetesClient kubernetesClient(KubernetesSerialization kubernetesSerialization, Config config);
}Customize the Kubernetes client configuration by implementing the KubernetesConfigCustomizer interface.
public interface KubernetesConfigCustomizer {
/**
* Customize the Kubernetes client configuration.
* Called during Config bean creation before the KubernetesClient is built.
*
* @param config the Config instance to customize
*/
void customize(Config config);
}Usage Example:
import io.fabric8.kubernetes.client.Config;
import io.quarkus.kubernetes.client.KubernetesConfigCustomizer;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.Map;
@ApplicationScoped
public class MyConfigCustomizer implements KubernetesConfigCustomizer {
@Override
public void customize(Config config) {
// Add custom headers
config.setCustomHeaders(Map.of("X-Custom-Header", "value"));
// Override specific settings
config.setMaxConcurrentRequests(100);
config.setMaxConcurrentRequestsPerHost(50);
}
}Customize the Jackson ObjectMapper used for Kubernetes resource serialization and deserialization.
public interface KubernetesClientObjectMapperCustomizer {
/**
* Customize the ObjectMapper used by the KubernetesClient.
* Called during ObjectMapper creation to configure JSON handling.
*
* @param objectMapper the ObjectMapper instance to customize
*/
void customize(ObjectMapper objectMapper);
}Usage Example:
import com.fasterxml.jackson.databind.ObjectMapper;
import io.quarkus.kubernetes.client.KubernetesClientObjectMapperCustomizer;
import jakarta.enterprise.context.ApplicationScoped;
import java.text.SimpleDateFormat;
import java.util.Locale;
@ApplicationScoped
public class MyObjectMapperCustomizer implements KubernetesClientObjectMapperCustomizer {
@Override
public void customize(ObjectMapper objectMapper) {
// Set locale for consistent serialization
objectMapper.setLocale(Locale.ROOT);
// Configure date formatting
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"));
}
}Specialized CDI qualifiers for injection of specific Kubernetes-related beans.
@Qualifier
@Retention(RUNTIME)
@Target({ METHOD, FIELD, PARAMETER, TYPE })
@Documented
public @interface KubernetesClientObjectMapper {
final class Literal extends AnnotationLiteral<KubernetesClientObjectMapper>
implements KubernetesClientObjectMapper {
public static final Literal INSTANCE = new Literal();
}
}
@Qualifier
@Retention(RUNTIME)
@Target({ METHOD, FIELD, PARAMETER, TYPE })
public @interface KubernetesResources {
}Usage Example:
import com.fasterxml.jackson.databind.ObjectMapper;
import io.quarkus.kubernetes.client.KubernetesClientObjectMapper;
import jakarta.inject.Inject;
@ApplicationScoped
public class MyService {
@Inject
@KubernetesClientObjectMapper
ObjectMapper kubernetesObjectMapper;
public void processKubernetesJson(String json) {
// Use the Kubernetes-specific ObjectMapper
Pod pod = kubernetesObjectMapper.readValue(json, Pod.class);
}
}Build-time API for other Quarkus extensions to integrate with the Kubernetes client.
public final class KubernetesClientBuildItem extends SimpleBuildItem {
public KubernetesClientBuildItem(Config config, HttpClient.Factory httpClientFactory);
/**
* Get the Kubernetes client configuration.
* @return the Config instance
*/
public Config getConfig();
/**
* Get the HTTP client factory used by the Kubernetes client.
* @return the HttpClient.Factory instance
*/
public HttpClient.Factory getHttpClientFactory();
/**
* Build a KubernetesClient instance for build-time use.
* @return a configured KubernetesClient instance
*/
public KubernetesClient buildClient();
}
public final class KubernetesResourcesBuildItem extends SimpleBuildItem {
public KubernetesResourcesBuildItem(String[] resourceClasses);
/**
* Get the array of Kubernetes resource class names to register.
* @return array of resource class names
*/
public String[] getResourceClasses();
}
public final class KubernetesClientCapabilityBuildItem extends SimpleBuildItem {
public KubernetesClientCapabilityBuildItem(boolean generateRbac);
/**
* Check if RBAC generation is enabled.
* @return true if RBAC generation is enabled
*/
public boolean isGenerateRbac();
}Build items for DevServices test container integration.
public final class KubernetesDevServiceInfoBuildItem extends SimpleBuildItem {
public KubernetesDevServiceInfoBuildItem(String kubeConfig, String containerId);
/**
* Get the KubeConfig as YAML string for the test container.
* @return the KubeConfig as YAML string
*/
public String getKubeConfig();
/**
* Get the container ID of the running kind test container.
* @return the containerId of the running test container
*/
public String getContainerId();
}
public final class KubernetesDevServiceRequestBuildItem extends SimpleBuildItem {
public KubernetesDevServiceRequestBuildItem(String flavor);
/**
* Get the flavor of the kubernetes cluster to start.
* @return the flavor of the kubernetes cluster (kind, k3s, etc)
*/
public String getFlavor();
}All configuration properties use the quarkus.kubernetes-client prefix:
@ConfigMapping(prefix = "quarkus.kubernetes-client")
@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED)
public interface KubernetesClientBuildConfig {
/** Whether the client should trust a self-signed certificate if so presented by the API server */
Optional<Boolean> trustCerts();
/** URL of the Kubernetes API server */
Optional<String> apiServerUrl();
/** @deprecated Use api-server-url instead */
@Deprecated(forRemoval = true)
Optional<String> masterUrl();
/** Default namespace to use */
Optional<String> namespace();
/** CA certificate file */
Optional<String> caCertFile();
/** CA certificate data */
Optional<String> caCertData();
/** Client certificate file */
Optional<String> clientCertFile();
/** Client certificate data */
Optional<String> clientCertData();
/** Client key file */
Optional<String> clientKeyFile();
/** Client key data */
Optional<String> clientKeyData();
/** Client key algorithm */
Optional<String> clientKeyAlgo();
/** Client key passphrase */
Optional<String> clientKeyPassphrase();
/** Kubernetes auth username */
Optional<String> username();
/** Kubernetes auth password */
Optional<String> password();
/** Kubernetes oauth token */
Optional<String> token();
/** Watch reconnect interval */
Optional<Duration> watchReconnectInterval();
/** Maximum reconnect attempts in case of watch failure */
OptionalInt watchReconnectLimit();
/** Maximum amount of time to wait for a connection with the API server to be established */
Optional<Duration> connectionTimeout();
/** Maximum amount of time to wait for a request to the API server to be completed */
Optional<Duration> requestTimeout();
/** Maximum number of retry attempts for API requests that fail with an HTTP code of >= 500 */
OptionalInt requestRetryBackoffLimit();
/** Time interval between retry attempts for API requests that fail with an HTTP code of >= 500 */
Optional<Duration> requestRetryBackoffInterval();
/** HTTP proxy used to access the Kubernetes API server */
Optional<String> httpProxy();
/** HTTPS proxy used to access the Kubernetes API server */
Optional<String> httpsProxy();
/** Proxy username */
Optional<String> proxyUsername();
/** Proxy password */
Optional<String> proxyPassword();
/** IP addresses or hosts to exclude from proxying */
Optional<List<String>> noProxy();
/** Enable the generation of the RBAC manifests */
@WithDefault("true")
boolean generateRbac();
/** DevServices configuration for testing */
KubernetesDevServicesBuildTimeConfig devservices();
}
@ConfigMapping(prefix = "quarkus.kubernetes-client.devservices")
public interface KubernetesDevServicesBuildTimeConfig {
/** If Dev Services for Kubernetes should be used (default: true) */
@WithDefault("true")
boolean enabled();
/** The kubernetes api server version to use */
Optional<String> apiVersion();
/** The kubernetes image to use */
Optional<String> imageName();
/** The flavor to use (kind, k3s or api-only). Default: api-only */
Optional<Flavor> flavor();
/** Override kubeconfig config if found. Default: false */
@WithDefault("false")
boolean overrideKubeconfig();
/** List of manifest file paths to apply on startup */
Optional<List<String>> manifests();
/** Whether the Kubernetes cluster is shared. Default: true */
@WithDefault("true")
boolean shared();
/** Service name for shared clusters. Default: kubernetes */
@WithDefault("kubernetes")
String serviceName();
/** Environment variables passed to the container */
Map<String, String> containerEnv();
enum Flavor {
kind, // needs privileged docker
k3s, // needs privileged docker
api_only // api only
}
}The extension provides several CDI producers that create the necessary beans:
@Singleton
public class KubernetesConfigProducer {
@DefaultBean
@Singleton
@Produces
public Config config(KubernetesClientBuildConfig buildConfig,
@All List<KubernetesConfigCustomizer> customizers);
}
@Singleton
public class KubernetesClientObjectMapperProducer {
@KubernetesClientObjectMapper
@DefaultBean
@Priority(Integer.MIN_VALUE)
@Singleton
@Produces
public ObjectMapper kubernetesClientObjectMapper(@All List<KubernetesClientObjectMapperCustomizer> customizers);
}
@Singleton
public class KubernetesSerializationProducer {
@DefaultBean
@Singleton
@Produces
public KubernetesSerialization kubernetesSerialization(
@KubernetesClientObjectMapper ObjectMapper objectMapper,
@KubernetesResources Class[] kubernetesResources);
}The extension integrates with these key Fabric8 Kubernetes Client classes:
io.fabric8.kubernetes.client.KubernetesClient - Main client interface for Kubernetes operationsio.fabric8.kubernetes.client.Config - Configuration for the Kubernetes clientio.fabric8.kubernetes.client.utils.KubernetesSerialization - Serialization utilities for Kubernetes resourcescom.fasterxml.jackson.databind.ObjectMapper - JSON serialization/deserializationio.fabric8.kubernetes.client.http.HttpClient - HTTP client abstraction for Kubernetes API callsThe extension provides automatic DevServices integration for testing:
// DevServices automatically starts a kind cluster for tests
@QuarkusTest
public class KubernetesClientTest {
@Inject
KubernetesClient client;
@Test
public void testKubernetesOperations() {
// Test against the automatically started cluster
PodList pods = client.pods().list();
assertThat(pods).isNotNull();
}
}Configuration for DevServices:
# Enable DevServices (default: true in test mode)
quarkus.kubernetes-client.devservices.enabled=true
# Choose cluster flavor
quarkus.kubernetes-client.devservices.flavor=kind
# Or use k3s
quarkus.kubernetes-client.devservices.flavor=k3s
# Or use api-only (for minimal testing)
quarkus.kubernetes-client.devservices.flavor=api-only