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.00
# Quarkus Kubernetes Client Extension
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: quarkus-kubernetes-client
7
- **Package Type**: maven
8
- **Group ID**: io.quarkus
9
- **Artifact ID**: quarkus-kubernetes-client
10
- **Language**: Java
11
- **Installation**: Add dependency to Maven pom.xml
12
- **Maven Dependency**:
13
```xml
14
<dependency>
15
<groupId>io.quarkus</groupId>
16
<artifactId>quarkus-kubernetes-client</artifactId>
17
</dependency>
18
```
19
20
## Core Imports
21
22
```java
23
import io.fabric8.kubernetes.client.KubernetesClient;
24
import io.fabric8.kubernetes.client.Config;
25
import io.quarkus.kubernetes.client.KubernetesConfigCustomizer;
26
import io.quarkus.kubernetes.client.KubernetesClientObjectMapperCustomizer;
27
import jakarta.inject.Inject;
28
```
29
30
## Basic Usage
31
32
```java
33
import io.fabric8.kubernetes.client.KubernetesClient;
34
import io.fabric8.kubernetes.client.Watcher;
35
import io.fabric8.kubernetes.client.WatcherException;
36
import io.fabric8.kubernetes.api.model.Pod;
37
import io.fabric8.kubernetes.api.model.PodList;
38
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
39
import jakarta.inject.Inject;
40
import jakarta.enterprise.context.ApplicationScoped;
41
42
@ApplicationScoped
43
public class KubernetesService {
44
45
@Inject
46
KubernetesClient kubernetesClient;
47
48
public void listPods() {
49
// List all pods in the default namespace
50
PodList pods = kubernetesClient.pods().list();
51
for (Pod pod : pods.getItems()) {
52
System.out.println("Pod: " + pod.getMetadata().getName());
53
}
54
}
55
56
public void createConfigMap() {
57
// Create a ConfigMap
58
kubernetesClient.configMaps()
59
.create(new ConfigMapBuilder()
60
.withNewMetadata()
61
.withName("my-config")
62
.withNamespace("default")
63
.endMetadata()
64
.addToData("key", "value")
65
.build());
66
}
67
68
public void watchPods() {
69
// Watch for pod changes
70
kubernetesClient.pods().watch(new Watcher<Pod>() {
71
@Override
72
public void eventReceived(Action action, Pod pod) {
73
System.out.println("Pod " + action + ": " + pod.getMetadata().getName());
74
}
75
76
@Override
77
public void onClose(WatcherException cause) {
78
// Handle close
79
}
80
});
81
}
82
}
83
```
84
85
## Architecture
86
87
The Quarkus Kubernetes Client extension bridges the Fabric8 Kubernetes Client with Quarkus's CDI container and native compilation capabilities:
88
89
- **CDI Integration**: Automatic injection of KubernetesClient beans with customizable configuration
90
- **Configuration Management**: Properties-based configuration with customization hooks
91
- **Serialization Layer**: Jackson ObjectMapper integration for Kubernetes resource handling
92
- **Build-time Processing**: SPI for extension developers to integrate at build time
93
- **Native Support**: GraalVM native image compatibility with reflection configuration
94
- **DevServices Integration**: Automatic test cluster setup for development
95
96
## Configuration
97
98
Configure the Kubernetes client using `application.properties`:
99
100
```properties
101
# Connection settings
102
quarkus.kubernetes-client.api-server-url=https://kubernetes.example.com:6443
103
# Deprecated: Use api-server-url instead
104
quarkus.kubernetes-client.master-url=https://kubernetes.example.com:6443
105
quarkus.kubernetes-client.namespace=my-namespace
106
quarkus.kubernetes-client.trust-certs=true
107
108
# Authentication
109
quarkus.kubernetes-client.token=${KUBERNETES_TOKEN}
110
quarkus.kubernetes-client.ca-cert-file=/path/to/ca.crt
111
quarkus.kubernetes-client.client-cert-file=/path/to/client.crt
112
quarkus.kubernetes-client.client-key-file=/path/to/client.key
113
114
# Timeouts and retries
115
quarkus.kubernetes-client.connection-timeout=PT10S
116
quarkus.kubernetes-client.request-timeout=PT30S
117
quarkus.kubernetes-client.request-retry-backoff-limit=5
118
quarkus.kubernetes-client.request-retry-backoff-interval=PT1S
119
120
# Watch settings
121
quarkus.kubernetes-client.watch-reconnect-interval=PT30S
122
quarkus.kubernetes-client.watch-reconnect-limit=10
123
124
# Proxy settings
125
quarkus.kubernetes-client.http-proxy=http://proxy.example.com:8080
126
quarkus.kubernetes-client.https-proxy=https://proxy.example.com:8443
127
quarkus.kubernetes-client.proxy-username=proxyuser
128
quarkus.kubernetes-client.proxy-password=proxypass
129
quarkus.kubernetes-client.no-proxy=localhost,127.0.0.1
130
131
# RBAC generation
132
quarkus.kubernetes-client.generate-rbac=true
133
134
# DevServices (for testing)
135
quarkus.kubernetes-client.devservices.enabled=true
136
quarkus.kubernetes-client.devservices.api-version=v1.28.0
137
quarkus.kubernetes-client.devservices.image-name=kindest/node:v1.28.0
138
quarkus.kubernetes-client.devservices.flavor=kind
139
quarkus.kubernetes-client.devservices.override-kubeconfig=false
140
quarkus.kubernetes-client.devservices.manifests=/path/to/manifest1.yaml,/path/to/manifest2.yaml
141
quarkus.kubernetes-client.devservices.shared=true
142
quarkus.kubernetes-client.devservices.service-name=kubernetes
143
quarkus.kubernetes-client.devservices.container-env.ENV_VAR=value
144
```
145
146
## Capabilities
147
148
### CDI Kubernetes Client Injection
149
150
Direct injection of fully configured KubernetesClient instances via CDI.
151
152
```java { .api }
153
@Inject
154
KubernetesClient kubernetesClient;
155
```
156
157
The KubernetesClient is produced by:
158
159
```java { .api }
160
@Singleton
161
public class KubernetesClientProducer {
162
@DefaultBean
163
@Singleton
164
@Produces
165
public KubernetesClient kubernetesClient(KubernetesSerialization kubernetesSerialization, Config config);
166
}
167
```
168
169
### Kubernetes Configuration Customization
170
171
Customize the Kubernetes client configuration by implementing the KubernetesConfigCustomizer interface.
172
173
```java { .api }
174
public interface KubernetesConfigCustomizer {
175
/**
176
* Customize the Kubernetes client configuration.
177
* Called during Config bean creation before the KubernetesClient is built.
178
*
179
* @param config the Config instance to customize
180
*/
181
void customize(Config config);
182
}
183
```
184
185
**Usage Example:**
186
187
```java
188
import io.fabric8.kubernetes.client.Config;
189
import io.quarkus.kubernetes.client.KubernetesConfigCustomizer;
190
import jakarta.enterprise.context.ApplicationScoped;
191
import java.util.Map;
192
193
@ApplicationScoped
194
public class MyConfigCustomizer implements KubernetesConfigCustomizer {
195
@Override
196
public void customize(Config config) {
197
// Add custom headers
198
config.setCustomHeaders(Map.of("X-Custom-Header", "value"));
199
200
// Override specific settings
201
config.setMaxConcurrentRequests(100);
202
config.setMaxConcurrentRequestsPerHost(50);
203
}
204
}
205
```
206
207
### ObjectMapper Customization
208
209
Customize the Jackson ObjectMapper used for Kubernetes resource serialization and deserialization.
210
211
```java { .api }
212
public interface KubernetesClientObjectMapperCustomizer {
213
/**
214
* Customize the ObjectMapper used by the KubernetesClient.
215
* Called during ObjectMapper creation to configure JSON handling.
216
*
217
* @param objectMapper the ObjectMapper instance to customize
218
*/
219
void customize(ObjectMapper objectMapper);
220
}
221
```
222
223
**Usage Example:**
224
225
```java
226
import com.fasterxml.jackson.databind.ObjectMapper;
227
import io.quarkus.kubernetes.client.KubernetesClientObjectMapperCustomizer;
228
import jakarta.enterprise.context.ApplicationScoped;
229
import java.text.SimpleDateFormat;
230
import java.util.Locale;
231
232
@ApplicationScoped
233
public class MyObjectMapperCustomizer implements KubernetesClientObjectMapperCustomizer {
234
@Override
235
public void customize(ObjectMapper objectMapper) {
236
// Set locale for consistent serialization
237
objectMapper.setLocale(Locale.ROOT);
238
239
// Configure date formatting
240
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"));
241
}
242
}
243
```
244
245
### CDI Qualifiers
246
247
Specialized CDI qualifiers for injection of specific Kubernetes-related beans.
248
249
```java { .api }
250
@Qualifier
251
@Retention(RUNTIME)
252
@Target({ METHOD, FIELD, PARAMETER, TYPE })
253
@Documented
254
public @interface KubernetesClientObjectMapper {
255
final class Literal extends AnnotationLiteral<KubernetesClientObjectMapper>
256
implements KubernetesClientObjectMapper {
257
public static final Literal INSTANCE = new Literal();
258
}
259
}
260
261
@Qualifier
262
@Retention(RUNTIME)
263
@Target({ METHOD, FIELD, PARAMETER, TYPE })
264
public @interface KubernetesResources {
265
}
266
```
267
268
**Usage Example:**
269
270
```java
271
import com.fasterxml.jackson.databind.ObjectMapper;
272
import io.quarkus.kubernetes.client.KubernetesClientObjectMapper;
273
import jakarta.inject.Inject;
274
275
@ApplicationScoped
276
public class MyService {
277
278
@Inject
279
@KubernetesClientObjectMapper
280
ObjectMapper kubernetesObjectMapper;
281
282
public void processKubernetesJson(String json) {
283
// Use the Kubernetes-specific ObjectMapper
284
Pod pod = kubernetesObjectMapper.readValue(json, Pod.class);
285
}
286
}
287
```
288
289
### SPI Build Items for Extension Development
290
291
Build-time API for other Quarkus extensions to integrate with the Kubernetes client.
292
293
```java { .api }
294
public final class KubernetesClientBuildItem extends SimpleBuildItem {
295
public KubernetesClientBuildItem(Config config, HttpClient.Factory httpClientFactory);
296
297
/**
298
* Get the Kubernetes client configuration.
299
* @return the Config instance
300
*/
301
public Config getConfig();
302
303
/**
304
* Get the HTTP client factory used by the Kubernetes client.
305
* @return the HttpClient.Factory instance
306
*/
307
public HttpClient.Factory getHttpClientFactory();
308
309
/**
310
* Build a KubernetesClient instance for build-time use.
311
* @return a configured KubernetesClient instance
312
*/
313
public KubernetesClient buildClient();
314
}
315
316
public final class KubernetesResourcesBuildItem extends SimpleBuildItem {
317
public KubernetesResourcesBuildItem(String[] resourceClasses);
318
319
/**
320
* Get the array of Kubernetes resource class names to register.
321
* @return array of resource class names
322
*/
323
public String[] getResourceClasses();
324
}
325
326
public final class KubernetesClientCapabilityBuildItem extends SimpleBuildItem {
327
public KubernetesClientCapabilityBuildItem(boolean generateRbac);
328
329
/**
330
* Check if RBAC generation is enabled.
331
* @return true if RBAC generation is enabled
332
*/
333
public boolean isGenerateRbac();
334
}
335
```
336
337
### DevServices Integration
338
339
Build items for DevServices test container integration.
340
341
```java { .api }
342
public final class KubernetesDevServiceInfoBuildItem extends SimpleBuildItem {
343
public KubernetesDevServiceInfoBuildItem(String kubeConfig, String containerId);
344
345
/**
346
* Get the KubeConfig as YAML string for the test container.
347
* @return the KubeConfig as YAML string
348
*/
349
public String getKubeConfig();
350
351
/**
352
* Get the container ID of the running kind test container.
353
* @return the containerId of the running test container
354
*/
355
public String getContainerId();
356
}
357
358
public final class KubernetesDevServiceRequestBuildItem extends SimpleBuildItem {
359
public KubernetesDevServiceRequestBuildItem(String flavor);
360
361
/**
362
* Get the flavor of the kubernetes cluster to start.
363
* @return the flavor of the kubernetes cluster (kind, k3s, etc)
364
*/
365
public String getFlavor();
366
}
367
```
368
369
## Configuration Properties
370
371
All configuration properties use the `quarkus.kubernetes-client` prefix:
372
373
```java { .api }
374
@ConfigMapping(prefix = "quarkus.kubernetes-client")
375
@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED)
376
public interface KubernetesClientBuildConfig {
377
378
/** Whether the client should trust a self-signed certificate if so presented by the API server */
379
Optional<Boolean> trustCerts();
380
381
/** URL of the Kubernetes API server */
382
Optional<String> apiServerUrl();
383
384
/** @deprecated Use api-server-url instead */
385
@Deprecated(forRemoval = true)
386
Optional<String> masterUrl();
387
388
/** Default namespace to use */
389
Optional<String> namespace();
390
391
/** CA certificate file */
392
Optional<String> caCertFile();
393
394
/** CA certificate data */
395
Optional<String> caCertData();
396
397
/** Client certificate file */
398
Optional<String> clientCertFile();
399
400
/** Client certificate data */
401
Optional<String> clientCertData();
402
403
/** Client key file */
404
Optional<String> clientKeyFile();
405
406
/** Client key data */
407
Optional<String> clientKeyData();
408
409
/** Client key algorithm */
410
Optional<String> clientKeyAlgo();
411
412
/** Client key passphrase */
413
Optional<String> clientKeyPassphrase();
414
415
/** Kubernetes auth username */
416
Optional<String> username();
417
418
/** Kubernetes auth password */
419
Optional<String> password();
420
421
/** Kubernetes oauth token */
422
Optional<String> token();
423
424
/** Watch reconnect interval */
425
Optional<Duration> watchReconnectInterval();
426
427
/** Maximum reconnect attempts in case of watch failure */
428
OptionalInt watchReconnectLimit();
429
430
/** Maximum amount of time to wait for a connection with the API server to be established */
431
Optional<Duration> connectionTimeout();
432
433
/** Maximum amount of time to wait for a request to the API server to be completed */
434
Optional<Duration> requestTimeout();
435
436
/** Maximum number of retry attempts for API requests that fail with an HTTP code of >= 500 */
437
OptionalInt requestRetryBackoffLimit();
438
439
/** Time interval between retry attempts for API requests that fail with an HTTP code of >= 500 */
440
Optional<Duration> requestRetryBackoffInterval();
441
442
/** HTTP proxy used to access the Kubernetes API server */
443
Optional<String> httpProxy();
444
445
/** HTTPS proxy used to access the Kubernetes API server */
446
Optional<String> httpsProxy();
447
448
/** Proxy username */
449
Optional<String> proxyUsername();
450
451
/** Proxy password */
452
Optional<String> proxyPassword();
453
454
/** IP addresses or hosts to exclude from proxying */
455
Optional<List<String>> noProxy();
456
457
/** Enable the generation of the RBAC manifests */
458
@WithDefault("true")
459
boolean generateRbac();
460
461
/** DevServices configuration for testing */
462
KubernetesDevServicesBuildTimeConfig devservices();
463
}
464
465
@ConfigMapping(prefix = "quarkus.kubernetes-client.devservices")
466
public interface KubernetesDevServicesBuildTimeConfig {
467
468
/** If Dev Services for Kubernetes should be used (default: true) */
469
@WithDefault("true")
470
boolean enabled();
471
472
/** The kubernetes api server version to use */
473
Optional<String> apiVersion();
474
475
/** The kubernetes image to use */
476
Optional<String> imageName();
477
478
/** The flavor to use (kind, k3s or api-only). Default: api-only */
479
Optional<Flavor> flavor();
480
481
/** Override kubeconfig config if found. Default: false */
482
@WithDefault("false")
483
boolean overrideKubeconfig();
484
485
/** List of manifest file paths to apply on startup */
486
Optional<List<String>> manifests();
487
488
/** Whether the Kubernetes cluster is shared. Default: true */
489
@WithDefault("true")
490
boolean shared();
491
492
/** Service name for shared clusters. Default: kubernetes */
493
@WithDefault("kubernetes")
494
String serviceName();
495
496
/** Environment variables passed to the container */
497
Map<String, String> containerEnv();
498
499
enum Flavor {
500
kind, // needs privileged docker
501
k3s, // needs privileged docker
502
api_only // api only
503
}
504
}
505
```
506
507
## CDI Producers
508
509
The extension provides several CDI producers that create the necessary beans:
510
511
```java { .api }
512
@Singleton
513
public class KubernetesConfigProducer {
514
@DefaultBean
515
@Singleton
516
@Produces
517
public Config config(KubernetesClientBuildConfig buildConfig,
518
@All List<KubernetesConfigCustomizer> customizers);
519
}
520
521
@Singleton
522
public class KubernetesClientObjectMapperProducer {
523
@KubernetesClientObjectMapper
524
@DefaultBean
525
@Priority(Integer.MIN_VALUE)
526
@Singleton
527
@Produces
528
public ObjectMapper kubernetesClientObjectMapper(@All List<KubernetesClientObjectMapperCustomizer> customizers);
529
}
530
531
@Singleton
532
public class KubernetesSerializationProducer {
533
@DefaultBean
534
@Singleton
535
@Produces
536
public KubernetesSerialization kubernetesSerialization(
537
@KubernetesClientObjectMapper ObjectMapper objectMapper,
538
@KubernetesResources Class[] kubernetesResources);
539
}
540
```
541
542
## External Dependencies
543
544
The extension integrates with these key Fabric8 Kubernetes Client classes:
545
546
- `io.fabric8.kubernetes.client.KubernetesClient` - Main client interface for Kubernetes operations
547
- `io.fabric8.kubernetes.client.Config` - Configuration for the Kubernetes client
548
- `io.fabric8.kubernetes.client.utils.KubernetesSerialization` - Serialization utilities for Kubernetes resources
549
- `com.fasterxml.jackson.databind.ObjectMapper` - JSON serialization/deserialization
550
- `io.fabric8.kubernetes.client.http.HttpClient` - HTTP client abstraction for Kubernetes API calls
551
552
## Testing and DevServices
553
554
The extension provides automatic DevServices integration for testing:
555
556
```java
557
// DevServices automatically starts a kind cluster for tests
558
@QuarkusTest
559
public class KubernetesClientTest {
560
561
@Inject
562
KubernetesClient client;
563
564
@Test
565
public void testKubernetesOperations() {
566
// Test against the automatically started cluster
567
PodList pods = client.pods().list();
568
assertThat(pods).isNotNull();
569
}
570
}
571
```
572
573
Configuration for DevServices:
574
575
```properties
576
# Enable DevServices (default: true in test mode)
577
quarkus.kubernetes-client.devservices.enabled=true
578
579
# Choose cluster flavor
580
quarkus.kubernetes-client.devservices.flavor=kind
581
582
# Or use k3s
583
quarkus.kubernetes-client.devservices.flavor=k3s
584
585
# Or use api-only (for minimal testing)
586
quarkus.kubernetes-client.devservices.flavor=api-only
587
```