Java client for Kubernetes and OpenShift providing access to full REST APIs via a fluent DSL
—
This document covers OpenShift DeploymentConfig operations, including scaling, rollouts, pod management, and deployment strategies.
import io.fabric8.openshift.client.OpenShiftClient;
import io.fabric8.openshift.api.model.DeploymentConfig;
import io.fabric8.openshift.api.model.DeploymentConfigList;
import io.fabric8.openshift.client.dsl.DeployableScalableResource;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.PodList;
import io.fabric8.kubernetes.client.dsl.MixedOperation;
import io.fabric8.kubernetes.client.dsl.RollableScalableResource;// List all deployment configurations in a namespace
DeploymentConfigList deploymentConfigs = client.deploymentConfigs()
.inNamespace("my-project")
.list();
// Get a specific deployment configuration
DeploymentConfig dc = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.get();
// List with label selector
DeploymentConfigList appDCs = client.deploymentConfigs()
.inNamespace("my-project")
.withLabel("app", "my-application")
.list();// Create a new deployment configuration
DeploymentConfig newDC = new DeploymentConfigBuilder()
.withNewMetadata()
.withName("my-new-app")
.withNamespace("my-project")
.addToLabels("app", "my-new-app")
.endMetadata()
.withNewSpec()
.withReplicas(3)
.addToSelector("app", "my-new-app")
.withNewTemplate()
.withNewMetadata()
.addToLabels("app", "my-new-app")
.endMetadata()
.withNewSpec()
.addNewContainer()
.withName("my-container")
.withImage("my-app:latest")
.addNewPort()
.withContainerPort(8080)
.endPort()
.endContainer()
.endSpec()
.endTemplate()
.endSpec()
.build();
DeploymentConfig created = client.deploymentConfigs()
.inNamespace("my-project")
.create(newDC);// Scale deployment configuration to specified replicas
DeploymentConfig scaled = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.scale(5);
// Scale with edit operation
DeploymentConfig scaledEdit = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.edit(dc -> new DeploymentConfigBuilder(dc)
.editSpec()
.withReplicas(3)
.endSpec()
.build());
// Get current scale
Scale currentScale = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.getScale();
int currentReplicas = currentScale.getSpec().getReplicas();// Create horizontal pod autoscaler for deployment config
HorizontalPodAutoscaler hpa = new HorizontalPodAutoscalerBuilder()
.withNewMetadata()
.withName("my-app-hpa")
.withNamespace("my-project")
.endMetadata()
.withNewSpec()
.withNewScaleTargetRef()
.withApiVersion("apps.openshift.io/v1")
.withKind("DeploymentConfig")
.withName("my-app")
.endScaleTargetRef()
.withMinReplicas(2)
.withMaxReplicas(10)
.withTargetCPUUtilizationPercentage(70)
.endSpec()
.build();
client.autoscaling().v1().horizontalPodAutoscalers()
.inNamespace("my-project")
.create(hpa);// Trigger a new deployment (rollout)
DeploymentConfig rolledOut = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.deployLatest();
// Get rollout status
DeploymentConfig dc = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.get();
Integer latestVersion = dc.getStatus().getLatestVersion();
List<DeploymentCondition> conditions = dc.getStatus().getConditions();
// Check if rollout is complete
boolean isProgressing = conditions.stream()
.anyMatch(condition ->
"Progressing".equals(condition.getType()) &&
"True".equals(condition.getStatus()));// Rollback to previous version
DeploymentConfig rolledBack = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.rollback();
// Rollback to specific version
DeploymentConfig specificRollback = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.rollback(3); // rollback to version 3// Pause rollouts
DeploymentConfig paused = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.pause();
// Resume rollouts
DeploymentConfig resumed = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.resume();
// Check if paused
boolean isPaused = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.get()
.getSpec()
.getPaused();// Get all pods managed by deployment configuration
PodList pods = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.getPods();
// Get pods for specific deployment version
PodList versionPods = client.pods()
.inNamespace("my-project")
.withLabel("deployment", "my-app-3") // version 3
.list();// Get logs from all pods
List<Pod> appPods = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.getPods();
for (Pod pod : appPods) {
String podLogs = client.pods()
.inNamespace("my-project")
.withName(pod.getMetadata().getName())
.getLog();
System.out.println("Pod " + pod.getMetadata().getName() + " logs:\n" + podLogs);
}
// Execute command in deployment config pods
String output = client.pods()
.inNamespace("my-project")
.withName(appPods.get(0).getMetadata().getName())
.exec("ps", "aux");// Watch deployment configuration changes
client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.watch(new Watcher<DeploymentConfig>() {
@Override
public void eventReceived(Action action, DeploymentConfig dc) {
System.out.println("DeploymentConfig " + action + ": " +
dc.getMetadata().getName() +
" (version: " + dc.getStatus().getLatestVersion() + ")");
}
@Override
public void onClose(WatcherException cause) {
System.out.println("Watch closed: " + cause.getMessage());
}
});// Wait for rollout to complete
client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.waitUntilCondition(dc -> {
List<DeploymentCondition> conditions = dc.getStatus().getConditions();
return conditions.stream().anyMatch(condition ->
"Progressing".equals(condition.getType()) &&
"False".equals(condition.getStatus()) &&
"NewReplicationControllerAvailable".equals(condition.getReason()));
}, 5, TimeUnit.MINUTES);// Update container image
DeploymentConfig updated = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.rolling()
.withTimeout(10, TimeUnit.MINUTES)
.updateImage("my-container", "my-app:v2.0");
// Update multiple images
DeploymentConfig multiUpdated = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.rolling()
.updateImage(Map.of(
"app-container", "my-app:v2.0",
"sidecar-container", "sidecar:v1.1"
));// Update environment variables
DeploymentConfig envUpdated = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.edit(dc -> new DeploymentConfigBuilder(dc)
.editSpec()
.editTemplate()
.editSpec()
.editFirstContainer()
.addNewEnv()
.withName("NEW_ENV_VAR")
.withValue("new-value")
.endEnv()
.endContainer()
.endSpec()
.endTemplate()
.endSpec()
.build());// Update resource requirements
DeploymentConfig resourceUpdated = client.deploymentConfigs()
.inNamespace("my-project")
.withName("my-app")
.edit(dc -> new DeploymentConfigBuilder(dc)
.editSpec()
.editTemplate()
.editSpec()
.editFirstContainer()
.withNewResources()
.addToRequests("cpu", new Quantity("100m"))
.addToRequests("memory", new Quantity("128Mi"))
.addToLimits("cpu", new Quantity("500m"))
.addToLimits("memory", new Quantity("512Mi"))
.endResources()
.endContainer()
.endSpec()
.endTemplate()
.endSpec()
.build());import io.fabric8.openshift.client.OpenShiftClient;
import io.fabric8.openshift.api.model.*;
public class DeploymentLifecycle {
private final OpenShiftClient client;
public DeploymentLifecycle(OpenShiftClient client) {
this.client = client;
}
public void deployApplication(String namespace, String appName, String image) {
// 1. Create or update deployment configuration
DeploymentConfig dc = createOrUpdateDeploymentConfig(namespace, appName, image);
// 2. Wait for deployment to complete
waitForDeploymentComplete(namespace, appName);
// 3. Verify deployment health
verifyDeploymentHealth(namespace, appName);
System.out.println("Application " + appName + " deployed successfully");
}
private DeploymentConfig createOrUpdateDeploymentConfig(String namespace,
String appName, String image) {
DeploymentConfig existing = client.deploymentConfigs()
.inNamespace(namespace)
.withName(appName)
.get();
if (existing != null) {
// Update existing deployment
return client.deploymentConfigs()
.inNamespace(namespace)
.withName(appName)
.rolling()
.withTimeout(10, TimeUnit.MINUTES)
.updateImage(appName, image);
} else {
// Create new deployment
return client.deploymentConfigs()
.inNamespace(namespace)
.create(new DeploymentConfigBuilder()
.withNewMetadata()
.withName(appName)
.withNamespace(namespace)
.addToLabels("app", appName)
.endMetadata()
.withNewSpec()
.withReplicas(3)
.addToSelector("app", appName)
.withNewStrategy()
.withType("Rolling")
.withNewRollingParams()
.withMaxUnavailable(new IntOrString("25%"))
.withMaxSurge(new IntOrString("25%"))
.endRollingParams()
.endStrategy()
.addNewTrigger()
.withType("ConfigChange")
.endTrigger()
.addNewTrigger()
.withType("ImageChange")
.withNewImageChangeParams()
.withAutomatic(true)
.addToContainerNames(appName)
.withNewFrom()
.withKind("ImageStreamTag")
.withName(appName + ":latest")
.endFrom()
.endImageChangeParams()
.endTrigger()
.withNewTemplate()
.withNewMetadata()
.addToLabels("app", appName)
.endMetadata()
.withNewSpec()
.addNewContainer()
.withName(appName)
.withImage(image)
.addNewPort()
.withContainerPort(8080)
.withProtocol("TCP")
.endPort()
.withNewResources()
.addToRequests("cpu", new Quantity("100m"))
.addToRequests("memory", new Quantity("128Mi"))
.addToLimits("cpu", new Quantity("500m"))
.addToLimits("memory", new Quantity("512Mi"))
.endResources()
.withNewLivenessProbe()
.withNewHttpGet()
.withPath("/health")
.withNewPort(8080)
.endHttpGet()
.withInitialDelaySeconds(30)
.withPeriodSeconds(10)
.endLivenessProbe()
.withNewReadinessProbe()
.withNewHttpGet()
.withPath("/ready")
.withNewPort(8080)
.endHttpGet()
.withInitialDelaySeconds(5)
.withPeriodSeconds(5)
.endReadinessProbe()
.endContainer()
.endSpec()
.endTemplate()
.endSpec()
.build());
}
}
private void waitForDeploymentComplete(String namespace, String appName) {
client.deploymentConfigs()
.inNamespace(namespace)
.withName(appName)
.waitUntilCondition(dc -> {
Integer latestVersion = dc.getStatus().getLatestVersion();
Integer replicas = dc.getSpec().getReplicas();
Integer readyReplicas = dc.getStatus().getReadyReplicas();
return latestVersion != null &&
replicas != null &&
readyReplicas != null &&
replicas.equals(readyReplicas);
}, 10, TimeUnit.MINUTES);
}
private void verifyDeploymentHealth(String namespace, String appName) {
PodList pods = client.deploymentConfigs()
.inNamespace(namespace)
.withName(appName)
.getPods();
long readyPods = pods.getItems().stream()
.filter(pod -> pod.getStatus().getConditions().stream()
.anyMatch(condition ->
"Ready".equals(condition.getType()) &&
"True".equals(condition.getStatus())))
.count();
DeploymentConfig dc = client.deploymentConfigs()
.inNamespace(namespace)
.withName(appName)
.get();
int expectedReplicas = dc.getSpec().getReplicas();
if (readyPods != expectedReplicas) {
throw new RuntimeException(
"Deployment unhealthy: " + readyPods + "/" + expectedReplicas + " pods ready");
}
}
}public class DeploymentConfig implements HasMetadata {
public ObjectMeta getMetadata();
public DeploymentConfigSpec getSpec();
public DeploymentConfigStatus getStatus();
}
public class DeploymentConfigSpec {
public Integer getReplicas();
public Map<String, String> getSelector();
public PodTemplateSpec getTemplate();
public DeploymentStrategy getStrategy();
public List<DeploymentTriggerPolicy> getTriggers();
public Integer getRevisionHistoryLimit();
public Boolean getPaused();
}
public class DeploymentConfigStatus {
public Integer getLatestVersion();
public Integer getObservedGeneration();
public Integer getReplicas();
public Integer getUpdatedReplicas();
public Integer getAvailableReplicas();
public Integer getUnavailableReplicas();
public Integer getReadyReplicas();
public List<DeploymentCondition> getConditions();
public List<ReplicationControllerCondition> getDetails();
}public class DeploymentStrategy {
public String getType(); // Rolling, Recreate, Custom
public RollingDeploymentStrategyParams getRollingParams();
public RecreateDeploymentStrategyParams getRecreateParams();
public CustomDeploymentStrategyParams getCustomParams();
public ResourceRequirements getResources();
public Map<String, String> getLabels();
public Map<String, String> getAnnotations();
}
public class RollingDeploymentStrategyParams {
public IntOrString getMaxUnavailable();
public IntOrString getMaxSurge();
public Long getTimeoutSeconds();
public Long getIntervalSeconds();
public Long getUpdatePeriodSeconds();
public LifecycleHook getPre();
public LifecycleHook getPost();
}public interface DeployableScalableResource<T> extends RollableScalableResource<T> {
T deployLatest();
T rollback();
T rollback(int toRevision);
T pause();
T resume();
PodList getPods();
// Scaling operations
T scale(int count);
Scale getScale();
// Rolling update operations
RollingUpdater<T> rolling();
}public interface RollingUpdater<T> {
RollingUpdater<T> withTimeout(long timeout, TimeUnit timeUnit);
T updateImage(String containerName, String image);
T updateImage(Map<String, String> containerToImageMap);
}Install with Tessl CLI
npx tessl i tessl/maven-io-fabric8--kubernetes-client-project