Java client for Kubernetes and OpenShift providing access to the full Kubernetes & OpenShift REST APIs via a fluent DSL
—
The Fabric8 Kubernetes Client provides dedicated DSL interfaces for each Kubernetes API group, enabling type-safe access to specialized resources like Deployments, Jobs, Network Policies, and more. Each API group interface follows consistent patterns while providing resource-specific operations.
The Apps API group contains workload resources for running applications.
public interface AppsAPIGroupDSL {
MixedOperation<Deployment, DeploymentList, RollableScalableResource<Deployment>> deployments();
MixedOperation<StatefulSet, StatefulSetList, RollableScalableResource<StatefulSet>> statefulSets();
MixedOperation<DaemonSet, DaemonSetList, Resource<DaemonSet>> daemonSets();
MixedOperation<ReplicaSet, ReplicaSetList, RollableScalableResource<ReplicaSet>> replicaSets();
MixedOperation<ControllerRevision, ControllerRevisionList, Resource<ControllerRevision>> controllerRevisions();
}
// Access via client
public interface KubernetesClient {
AppsAPIGroupDSL apps();
}// Create a deployment
Deployment deployment = client.apps().deployments().create(new DeploymentBuilder()
.withNewMetadata()
.withName("nginx-deployment")
.withLabels(Map.of("app", "nginx"))
.endMetadata()
.withNewSpec()
.withReplicas(3)
.withNewSelector()
.addToMatchLabels("app", "nginx")
.endSelector()
.withNewTemplate()
.withNewMetadata()
.addToLabels("app", "nginx")
.endMetadata()
.withNewSpec()
.addNewContainer()
.withName("nginx")
.withImage("nginx:1.21")
.addNewPort()
.withContainerPort(80)
.endPort()
.endContainer()
.endSpec()
.endTemplate()
.endSpec()
.build());
// Scale deployment
client.apps().deployments().withName("nginx-deployment").scale(5);
// Rolling update
client.apps().deployments().withName("nginx-deployment").rolling()
.withTimeout(5, TimeUnit.MINUTES)
.updateImage("nginx:1.22");
// Check rollout status
client.apps().deployments().withName("nginx-deployment").isReady();// Create a StatefulSet
StatefulSet statefulSet = client.apps().statefulSets().create(new StatefulSetBuilder()
.withNewMetadata()
.withName("web-statefulset")
.endMetadata()
.withNewSpec()
.withReplicas(3)
.withServiceName("nginx-service")
.withNewSelector()
.addToMatchLabels("app", "nginx")
.endSelector()
.withNewTemplate()
.withNewMetadata()
.addToLabels("app", "nginx")
.endMetadata()
.withNewSpec()
.addNewContainer()
.withName("nginx")
.withImage("nginx:1.21")
.endContainer()
.endSpec()
.endTemplate()
.addNewVolumeClaimTemplate()
.withNewMetadata()
.withName("web-storage")
.endMetadata()
.withNewSpec()
.withAccessModes("ReadWriteOnce")
.withNewResources()
.addToRequests("storage", new Quantity("1Gi"))
.endResources()
.endSpec()
.endVolumeClaimTemplate()
.endSpec()
.build());The Batch API group contains resources for running batch workloads.
public interface BatchAPIGroupDSL {
// V1 API
V1BatchAPIGroupDSL v1();
// Default methods (v1)
MixedOperation<Job, JobList, ScalableResource<Job>> jobs();
MixedOperation<CronJob, CronJobList, Resource<CronJob>> cronjobs();
}
public interface V1BatchAPIGroupDSL {
MixedOperation<Job, JobList, ScalableResource<Job>> jobs();
MixedOperation<CronJob, CronJobList, Resource<CronJob>> cronjobs();
}
// Access via client
public interface KubernetesClient {
BatchAPIGroupDSL batch();
}// Create a job
Job job = client.batch().jobs().create(new JobBuilder()
.withNewMetadata()
.withName("batch-job")
.endMetadata()
.withNewSpec()
.withCompletions(1)
.withParallelism(1)
.withNewTemplate()
.withNewSpec()
.addNewContainer()
.withName("worker")
.withImage("busybox:1.35")
.withCommand("sh", "-c", "echo 'Processing batch job'; sleep 30")
.endContainer()
.withRestartPolicy("Never")
.endSpec()
.endTemplate()
.endSpec()
.build());
// Wait for job completion
Job completedJob = client.batch().jobs().withName("batch-job")
.waitUntilCondition(job -> {
JobStatus status = job.getStatus();
return status != null && status.getSucceeded() != null && status.getSucceeded() > 0;
}, 5, TimeUnit.MINUTES);// Create a CronJob
CronJob cronJob = client.batch().cronjobs().create(new CronJobBuilder()
.withNewMetadata()
.withName("scheduled-job")
.endMetadata()
.withNewSpec()
.withSchedule("0 2 * * *") // Run daily at 2 AM
.withNewJobTemplate()
.withNewSpec()
.withNewTemplate()
.withNewSpec()
.addNewContainer()
.withName("backup")
.withImage("postgres:13")
.withCommand("pg_dump", "-h", "database", "mydb")
.endContainer()
.withRestartPolicy("OnFailure")
.endSpec()
.endTemplate()
.endSpec()
.endJobTemplate()
.endSpec()
.build());The Network API group contains networking-related resources.
public interface NetworkAPIGroupDSL {
// V1 API
V1NetworkAPIGroupDSL v1();
// Default methods (v1)
MixedOperation<NetworkPolicy, NetworkPolicyList, Resource<NetworkPolicy>> networkPolicies();
MixedOperation<Ingress, IngressList, Resource<Ingress>> ingresses();
MixedOperation<IngressClass, IngressClassList, Resource<IngressClass>> ingressClasses();
}
// Access via client
public interface KubernetesClient {
NetworkAPIGroupDSL network();
}// Create a network policy
NetworkPolicy policy = client.network().networkPolicies().create(new NetworkPolicyBuilder()
.withNewMetadata()
.withName("deny-all")
.withNamespace("production")
.endMetadata()
.withNewSpec()
.withNewPodSelector() // Empty selector = all pods
.endPodSelector()
.withPolicyTypes("Ingress", "Egress")
// No ingress/egress rules = deny all
.endSpec()
.build());
// Allow specific ingress traffic
NetworkPolicy allowWeb = client.network().networkPolicies().create(new NetworkPolicyBuilder()
.withNewMetadata()
.withName("allow-web-traffic")
.endMetadata()
.withNewSpec()
.withNewPodSelector()
.addToMatchLabels("app", "web")
.endPodSelector()
.withPolicyTypes("Ingress")
.addNewIngress()
.addNewPort()
.withPort(new IntOrString(80))
.withProtocol("TCP")
.endPort()
.addNewFrom()
.withNewPodSelector()
.addToMatchLabels("role", "frontend")
.endPodSelector()
.endFrom()
.endIngress()
.endSpec()
.build());// Create an ingress
Ingress ingress = client.network().ingresses().create(new IngressBuilder()
.withNewMetadata()
.withName("web-ingress")
.withAnnotations(Map.of(
"nginx.ingress.kubernetes.io/rewrite-target", "/",
"cert-manager.io/cluster-issuer", "letsencrypt-prod"
))
.endMetadata()
.withNewSpec()
.addNewTl()
.withHosts("example.com")
.withSecretName("example-tls")
.endTl()
.addNewRule()
.withHost("example.com")
.withNewHttp()
.addNewPath()
.withPath("/")
.withPathType("Prefix")
.withNewBackend()
.withNewService()
.withName("web-service")
.withNewPort()
.withNumber(80)
.endPort()
.endService()
.endBackend()
.endPath()
.endHttp()
.endRule()
.endSpec()
.build());Role-Based Access Control resources for security and authorization.
public interface RbacAPIGroupDSL {
// V1 API
V1RbacAPIGroupDSL v1();
// Default methods (v1)
MixedOperation<Role, RoleList, Resource<Role>> roles();
MixedOperation<RoleBinding, RoleBindingList, Resource<RoleBinding>> roleBindings();
NonNamespaceOperation<ClusterRole, ClusterRoleList, Resource<ClusterRole>> clusterRoles();
NonNamespaceOperation<ClusterRoleBinding, ClusterRoleBindingList, Resource<ClusterRoleBinding>> clusterRoleBindings();
}
// Access via client
public interface KubernetesClient {
RbacAPIGroupDSL rbac();
}// Create a Role
Role role = client.rbac().roles().create(new RoleBuilder()
.withNewMetadata()
.withName("pod-reader")
.withNamespace("development")
.endMetadata()
.addNewRule()
.withApiGroups("")
.withResources("pods")
.withVerbs("get", "list", "watch")
.endRule()
.build());
// Create a RoleBinding
RoleBinding roleBinding = client.rbac().roleBindings().create(new RoleBindingBuilder()
.withNewMetadata()
.withName("read-pods")
.withNamespace("development")
.endMetadata()
.addNewSubject()
.withKind("User")
.withName("jane@example.com")
.withApiGroup("rbac.authorization.k8s.io")
.endSubject()
.withNewRoleRef()
.withKind("Role")
.withName("pod-reader")
.withApiGroup("rbac.authorization.k8s.io")
.endRoleRef()
.build());
// Create a ClusterRole
ClusterRole clusterRole = client.rbac().clusterRoles().create(new ClusterRoleBuilder()
.withNewMetadata()
.withName("cluster-reader")
.endMetadata()
.addNewRule()
.withApiGroups("")
.withResources("nodes", "namespaces")
.withVerbs("get", "list")
.endRule()
.build());Storage-related resources for persistent storage management.
public interface StorageAPIGroupDSL {
// V1 API
V1StorageAPIGroupDSL v1();
// Default methods (v1)
NonNamespaceOperation<StorageClass, StorageClassList, Resource<StorageClass>> storageClasses();
NonNamespaceOperation<VolumeAttachment, VolumeAttachmentList, Resource<VolumeAttachment>> volumeAttachments();
NonNamespaceOperation<CSIDriver, CSIDriverList, Resource<CSIDriver>> csiDrivers();
NonNamespaceOperation<CSINode, CSINodeList, Resource<CSINode>> csiNodes();
}
// Access via client
public interface KubernetesClient {
StorageAPIGroupDSL storage();
}// Create a StorageClass
StorageClass storageClass = client.storage().storageClasses().create(new StorageClassBuilder()
.withNewMetadata()
.withName("fast-ssd")
.endMetadata()
.withProvisioner("kubernetes.io/aws-ebs")
.withParameters(Map.of(
"type", "gp3",
"iops", "3000",
"throughput", "125"
))
.withReclaimPolicy("Delete")
.withVolumeBindingMode("WaitForFirstConsumer")
.withAllowVolumeExpansion(true)
.build());Horizontal Pod Autoscaler resources for automatic scaling.
public interface AutoscalingAPIGroupDSL {
// V1 API
V1AutoscalingAPIGroupDSL v1();
// V2 API
V2AutoscalingAPIGroupDSL v2();
// Default methods (v2)
MixedOperation<HorizontalPodAutoscaler, HorizontalPodAutoscalerList, Resource<HorizontalPodAutoscaler>> horizontalPodAutoscalers();
}
// Access via client
public interface KubernetesClient {
AutoscalingAPIGroupDSL autoscaling();
}// Create an HPA (v2)
HorizontalPodAutoscaler hpa = client.autoscaling().v2().horizontalPodAutoscalers().create(
new HorizontalPodAutoscalerBuilder()
.withNewMetadata()
.withName("web-app-hpa")
.endMetadata()
.withNewSpec()
.withNewScaleTargetRef()
.withApiVersion("apps/v1")
.withKind("Deployment")
.withName("web-app")
.endScaleTargetRef()
.withMinReplicas(2)
.withMaxReplicas(10)
.addNewMetric()
.withType("Resource")
.withNewResource()
.withName("cpu")
.withNewTarget()
.withType("Utilization")
.withAverageUtilization(70)
.endTarget()
.endResource()
.endMetric()
.endSpec()
.build());The client provides access to many other API groups:
Each follows similar patterns with versioned sub-interfaces and consistent operation methods.
Install with Tessl CLI
npx tessl i tessl/maven-io-fabric8--kubernetes-client