如何通过Fabric8 Java Client API获取Kubernetes中Deployment滚动升级的状态?
Great question! When using Fabric8 Java Client to trigger a rolling update via rolling().updateImage(), the client doesn’t wait for the upgrade to complete by default—so you’ll need to track the Deployment’s status programmatically to determine success or failure. Here are two reliable approaches:
1. Use the Watch API for real-time status monitoring
Fabric8’s Watch API lets you listen to changes to the Deployment as the rolling update progresses. This is ideal if you want immediate feedback on the upgrade’s state:
// Trigger the rolling update Operation<Deployment> updateOp = client.apps().deployments() .inNamespace("your-namespace") .withName("your-deployment") .rolling() .updateImage("your-new-image:tag"); // Fetch the initial updated Deployment Deployment deployment = updateOp.get(); String ns = deployment.getMetadata().getNamespace(); String name = deployment.getMetadata().getName(); int desiredReplicas = deployment.getSpec().getReplicas().intValue(); // Set up a watch to monitor status changes Watch upgradeWatch = client.apps().deployments() .inNamespace(ns) .withName(name) .watch(new Watcher<Deployment>() { @Override public void eventReceived(Action action, Deployment updatedDeploy) { DeploymentStatus status = updatedDeploy.getStatus(); // Check for successful upgrade if (status.getAvailableReplicas() != null && status.getAvailableReplicas() == desiredReplicas && status.getUpdatedReplicas() != null && status.getUpdatedReplicas() == desiredReplicas && (status.getOldReplicaSets() == null || status.getOldReplicaSets().isEmpty())) { System.out.println("Rolling update completed successfully!"); upgradeWatch.close(); // Stop watching once done } // Check for failure conditions if (status.getProgressDeadlineExceeded() != null) { System.err.println("Rolling update failed: Progress deadline exceeded"); upgradeWatch.close(); } } @Override public void onClose(WatcherException cause) { if (cause != null) { System.err.println("Error monitoring update: " + cause.getMessage()); } } });
2. Poll the Deployment status (for simpler use cases)
If real-time updates aren’t necessary, you can periodically fetch the Deployment and check its status until it reaches a terminal state or times out:
// Trigger the update and get the initial Deployment Deployment updatedDeployment = client.apps().deployments() .inNamespace("your-namespace") .withName("your-deployment") .rolling() .updateImage("your-new-image:tag") .get(); int desiredReplicas = updatedDeployment.getSpec().getReplicas().intValue(); long timeoutMs = 5 * 60 * 1000; // 5-minute timeout long startTime = System.currentTimeMillis(); boolean upgradeSucceeded = false; try { while (System.currentTimeMillis() - startTime < timeoutMs) { // Fetch the latest state of the Deployment Deployment currentDeploy = client.apps().deployments() .inNamespace(updatedDeployment.getMetadata().getNamespace()) .withName(updatedDeployment.getMetadata().getName()) .get(); DeploymentStatus status = currentDeploy.getStatus(); // Verify success conditions if (status.getAvailableReplicas() != null && status.getAvailableReplicas() == desiredReplicas && status.getUpdatedReplicas() != null && status.getUpdatedReplicas() == desiredReplicas && (status.getOldReplicaSets() == null || status.getOldReplicaSets().isEmpty())) { upgradeSucceeded = true; break; } // Check for failure via progress deadline if (status.getProgressDeadlineExceeded() != null) { upgradeSucceeded = false; break; } // Wait 5 seconds before polling again Thread.sleep(5000); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); System.err.println("Update monitoring interrupted: " + e.getMessage()); } if (upgradeSucceeded) { System.out.println("Rolling update succeeded!"); } else { System.out.println("Rolling update failed or timed out."); }
Key Status Conditions to Check
To accurately determine success or failure, focus on these Kubernetes Deployment status fields:
- Success:
availableReplicasmatches the desired replica count (all new Pods are ready)updatedReplicasmatches the desired count (all Pods are running the new image)oldReplicaSetsis empty (Kubernetes has cleaned up the old Pods)
- Failure:
progressDeadlineExceededis set (Kubernetes detects the update isn’t making progress)unavailableReplicasremains above 0 for an extended periodobservedGenerationis less thanmetadata.generation(the cluster hasn’t processed the update)
Adjust timeouts and polling intervals based on your cluster’s typical upgrade speed, and don’t forget to handle exceptions appropriately!
内容的提问来源于stack exchange,提问作者LubaT

