Skaffold’s status check subcommand, when configured to wait for rollout completion, is actually a sophisticated orchestration layer that leverages Kubernetes’ own deployment status reporting to ensure your application is truly ready before marking it as deployed.
Let’s see it in action. Imagine you have a simple deployment in your skaffold.yaml:
apiVersion: skaffold/v2beta29
kind: Config
deploy:
kubectl:
- manifests:
- k8s/deployment.yaml
- statusCheck:
- manifests:
- k8s/deployment.yaml
waitForResourceState:
- Deployment/default/my-app
And your k8s/deployment.yaml looks like this:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: nginx:1.25.3
When you run skaffold dev, Skaffold will deploy this Deployment and then pause. It will continuously query the Kubernetes API for the my-app Deployment’s status. It’s not just checking if the Deployment exists; it’s looking for the Available condition to be true, and crucially, for status.readyReplicas to equal spec.replicas.
Here’s what Skaffold is doing under the hood. It’s essentially running a loop that looks something like this (simplified):
func waitForRollout(deploymentName, namespace string, desiredReplicas int) error {
for {
dep, err := kubernetesClient.AppsV1().Deployments(namespace).Get(context.TODO(), deploymentName, metav1.GetOptions{})
if err != nil {
// Handle error: maybe the deployment hasn't been created yet, or there's a connection issue.
// Skaffold might retry or log a warning here.
time.Sleep(5 * time.Second) // Simple retry logic
continue
}
availableReplicas := dep.Status.AvailableReplicas
readyReplicas := dep.Status.ReadyReplicas // Note: ReadyReplicas is preferred for newer K8s versions
// Check if the deployment is available and the desired number of replicas are ready
if availableReplicas != nil && *availableReplicas == int32(desiredReplicas) && readyReplicas == int32(desiredReplicas) {
return nil // Success!
}
// Log progress (e.g., "Waiting for 3/3 replicas to be ready...")
fmt.Printf("Waiting for %d/%d replicas to be ready for deployment %s/%s...\n", readyReplicas, desiredReplicas, namespace, deploymentName)
time.Sleep(5 * time.Second) // Wait before checking again
}
}
The core problem this solves is the "stale deployment" scenario. Without status checks, Skaffold might consider a deployment complete as soon as the kubectl apply command returns, even if the Pods are still starting up, crashing, or haven’t reached a ready state. This means your application could be marked as running when it’s actually broken, leading to user-facing errors or failed integration tests.
The statusCheck block in skaffold.yaml is your lever. You can specify waitForResourceState to target specific Kubernetes resources. For Deployments, Skaffold looks for the Available condition. For other resources like StatefulSets, it performs similar checks to ensure their readyReplicas match the spec.replicas. You can even specify a timeoutSeconds to prevent indefinite waiting if something goes wrong.
Let’s say you’ve updated your nginx image to nginx:invalid-tag. If you run skaffold dev with the statusCheck configured, Skaffold will deploy the invalid image, and the Deployment will enter a Progressing state with zero available replicas. Skaffold will then time out (if a timeout is set) or continuously report that it’s waiting for replicas, indicating a failure.
The statusCheck configuration can also be applied to individual manifests within a deploy.kubectl block, allowing for granular control. You could have one Deployment that Skaffold waits for and another that it doesn’t.
One crucial detail that trips people up is the difference between AvailableReplicas and ReadyReplicas in the Deployment status. While AvailableReplicas has been around longer, ReadyReplicas is a more precise indicator of pods that have passed their readiness probes. Skaffold, especially in newer versions, prioritizes ReadyReplicas when available, aligning with Kubernetes’ own definition of a healthy deployment. If your readinessProbe is not configured correctly, or takes a long time to pass, Skaffold will correctly reflect this delay.
The next logical step after ensuring your deployments are ready is to understand how Skaffold can integrate with these ready applications for automated testing.