Quarkus extension providing integration with Kubernetes clusters through the Fabric8 Kubernetes Client for building cloud-native applications and operators
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
The 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