This chapter covers Skaffold, Google's open-source tool for continuous development on Kubernetes, with a focus on local GKE development. Skaffold automates the build-push-deploy cycle, enabling rapid inner-loop development. On the ACE exam, this topic appears in about 2-4% of questions under Objective 3.2 (Deploy Implement). You will be tested on Skaffold's pipeline stages, configuration structure, and how it integrates with Cloud Code, Cloud Build, and GKE. Understanding Skaffold is essential for scenarios requiring fast iteration without manual kubectl commands.
Jump to a section
Imagine a high-end custom furniture workshop. The master carpenter (developer) designs a chair in CAD (code). Each time she saves a change, she needs to: (1) cut new wood pieces (build the container image), (2) assemble them into a chair (deploy to the cluster), and (3) test the chair sits right (verify with tests). Doing all three manually for every small tweak would waste hours. Skaffold is like an automated assistant that watches the CAD file. When a change is detected, the assistant automatically triggers the CNC machine to cut new pieces, then hands them to the assembly robot, which builds the chair and places it in the showroom (cluster). The assistant also remembers the last successful chair configuration (artifact caching) and can reuse it if the design didn't change. If a new screw type is introduced (new base image), the assistant fetches it from the warehouse (container registry). The assistant can also run the chair through a durability test (integration test) before declaring it ready. This continuous loop — detect, build, deploy, test — is exactly what Skaffold does for Kubernetes applications, but with container images and manifests instead of wood and screws.
What is Skaffold and Why It Exists
Skaffold is a command-line tool that facilitates continuous development for Kubernetes applications. It handles the workflow of building, pushing, and deploying your application, and then monitoring for changes to repeat the cycle. Its primary purpose is to enable a fast inner-loop development experience: you write code, save, and see the changes running on your cluster within seconds, without manually running docker build, docker push, kubectl apply, etc.
Skaffold is not a CI/CD tool (like Cloud Build or Jenkins) — it is designed for local development. It can deploy to any Kubernetes cluster, including GKE, Minikube, or even remote clusters. On the ACE exam, you'll see Skaffold as part of the Cloud Code IDE integration, but knowing the standalone CLI is equally important.
How Skaffold Works Internally
Skaffold operates in a loop, defined by its configuration file (skaffold.yaml). The loop has four main stages:
Detect: Skaffold watches the filesystem for changes in your source code. By default, it uses filesystem watchers (e.g., fsnotify on Linux) to monitor file modifications. The watch is recursive and excludes common non-source directories like node_modules, .git, etc.
2. Build: When a change is detected, Skaffold builds the container image. It supports several builders:
- Docker: Runs docker build using a Dockerfile.
- Kaniko: Builds inside a container, useful for cluster-side builds without Docker daemon.
- Jib: For Java projects, builds optimized container images without Docker.
- Cloud Build: Offloads building to Google Cloud Build (must be enabled in skaffold.yaml).
- Buildpacks: Uses CNCF Buildpacks (e.g., pack).
The built image is tagged with a unique tag (default: git commit + timestamp or a random string). Skaffold can also cache intermediate layers to speed up subsequent builds.
Push: The built image is pushed to a container registry (e.g., gcr.io, docker.io). If using a local cluster like Minikube, pushing can be skipped by setting local: push: false and using the docker daemon directly.
4. Deploy: Skaffold applies the Kubernetes manifests (YAML files) to the cluster. It supports:
- kubectl: Directly runs kubectl apply.
- Helm: Uses Helm charts.
- Kustomize: Applies kustomize overlays.
- kpt: For GitOps-style deployments.
Skaffold can also wait for deployments to become ready (--wait-for-deployments).
After deploy, Skaffold can optionally run tests (e.g., integration tests) and then returns to watching for changes. This loop continues until you press Ctrl+C.
Key Components, Values, Defaults, and Timers
Configuration file: skaffold.yaml (required) — YAML format with apiVersion: skaffold/v4beta7 (current stable).
Build section: Defines artifacts (images) and their builders.
Deploy section: Defines how to deploy (kubectl, helm, kustomize, kpt).
Port forwarding: portForward section allows forwarding ports from the cluster to localhost for debugging.
Profiles: Define different configurations for different environments (e.g., dev, prod).
File watching: Default polling interval is 1000ms. Can be customized with watch: pollInterval: 500.
Image tagging: Default is gitCommit. Other options: sha256, envTemplate, dateTime, customTemplate.
Cache: Skaffold caches built images locally (~/.skaffold/cache). Default cache is enabled.
Deploy concurrency: Default 1 (serial). Can be increased with deploy: kubectl: concurrency: 5.
Configuration and Verification Commands
Initialize a Skaffold project:
skaffold initThis scans your project for Dockerfiles, Helm charts, etc., and generates a skaffold.yaml.
Run the development loop:
skaffold devThis starts the continuous build-deploy loop. Use --port-forward to enable port forwarding automatically.
Run a single build and deploy:
skaffold runUseful for one-off deployments.
Delete deployed resources:
skaffold deleteDiagnose the pipeline:
skaffold diagnosePrints the resolved configuration, including all profiles applied.
How Skaffold Interacts with Related Technologies
Cloud Code: Skaffold is the engine behind Cloud Code's run/debug features. When you click "Run" in VS Code or IntelliJ, Cloud Code invokes Skaffold under the hood.
Cloud Build: Skaffold can use Cloud Build as a remote builder. This is configured in skaffold.yaml under build: googleCloudBuild: {}. The build happens in Cloud Build, and the image is pushed to GCR/Artifact Registry. This is useful for teams that want consistent builds.
GKE: Skaffold deploys to GKE by using your current kubeconfig context. You can target a specific GKE cluster by setting kubecontext in skaffold.yaml or using environment variable KUBECONFIG.
Artifact Registry: Skaffold pushes images to any registry specified in the image name (e.g., us-central1-docker.pkg.dev/my-project/my-repo/my-image).
Minikube: For local development, Skaffold can deploy to Minikube. Use skaffold dev --kube-context minikube.
Skaffold Profiles: You can define profiles to switch between local and remote builds. For example, a dev profile uses Docker local, a ci profile uses Cloud Build.
Advanced Features
Hot Reload: Skaffold supports syncing files directly into running containers without rebuilding the image. This is configured with sync in the artifact definition. For example, syncing static HTML files or Python code. This dramatically reduces iteration time.
Custom Builders: You can define custom build scripts using custom artifact type.
Dependencies: Artifacts can depend on other artifacts. Skaffold builds them in order.
Lifecycle Hooks: Run commands before/after build, deploy, etc. (e.g., pre-deploy: - command: echo 'deploying').
Debug: Skaffold can automatically configure debuggers for Java, Python, Node.js, and Go using --debug flag.
Exam-Relevant Details
The ACE exam expects you to know the skaffold dev vs skaffold run difference.
You should understand that Skaffold is not a CI/CD system but a local development tool.
Know that Skaffold can use Cloud Build as a builder, but that requires Cloud Build API enabled and appropriate permissions.
Be aware that Skaffold can deploy using Helm, kubectl, or Kustomize.
Remember that skaffold init can auto-generate the config file.
Port forwarding is a key feature for accessing services locally during development.
Common Exam Scenarios
Scenario: A developer wants to automatically rebuild and redeploy a Go application on GKE whenever they save a file. Answer: Use skaffold dev with a skaffold.yaml that builds the Docker image and deploys using kubectl.
Scenario: A team wants to ensure consistent builds across developers by using Cloud Build. Answer: Configure build: googleCloudBuild: {} in the skaffold.yaml.
Scenario: A developer wants to only update static files without rebuilding the container. Answer: Use the sync feature in Skaffold to copy files directly into the running pod.
Scenario: A developer needs to access a database running in the cluster from their local machine. Answer: Use portForward in skaffold.yaml to forward a local port to the database service.
Conclusion
Skaffold is an essential tool for Kubernetes development, especially when targeting GKE. The ACE exam tests your ability to choose the right Skaffold command and configuration for a given development workflow. Focus on understanding the build-deploy loop, the difference between dev and run, and the integration with Cloud Build and Cloud Code.
Initialize Skaffold Configuration
Run `skaffold init` in your project root. Skaffold scans for Dockerfiles, Helm charts, and Kustomize overlays. It generates a `skaffold.yaml` file with default build and deploy sections. You can also manually create the file. The `apiVersion` must match the Skaffold version installed (check with `skaffold version`). The config defines artifacts (images to build) and how to deploy them. For GKE, ensure your kubeconfig points to the correct cluster.
Start Development Loop
Run `skaffold dev` in the terminal. Skaffold reads `skaffold.yaml`, builds images (e.g., using Docker), pushes them to the registry (if not local), and deploys manifests to the cluster. It then watches for file changes. When a change is detected, it rebuilds only the affected image and redeploys. The `--port-forward` flag automatically forwards container ports to localhost. Use `Ctrl+C` to stop the loop and optionally clean up resources.
Build and Tag Images
Skaffold builds each artifact defined in `skaffold.yaml`. For a Docker artifact, it runs `docker build` with the specified Dockerfile. The image is tagged with a unique tag (default: `gitCommit`). If using Cloud Build, Skaffold submits the build to Cloud Build, which builds and pushes the image. The image tag is used in the Kubernetes manifests via image replacement (Skaffold automatically updates the manifest with the new tag).
Deploy to GKE Cluster
Skaffold applies the Kubernetes manifests to the cluster using the configured deployer (kubectl, Helm, etc.). For kubectl, it runs `kubectl apply -f <manifest>`. Skaffold can wait for deployments to become ready with `--wait-for-deployments`. If using Helm, it runs `helm upgrade --install`. The deployment is done in the current kubeconfig context. To target a specific GKE cluster, set the context in `skaffold.yaml` under `deploy: kubeContext: gke_my-project_us-central1_my-cluster`.
Port Forward for Local Access
Skaffold can forward ports from the cluster to your local machine using the `portForward` section in `skaffold.yaml`. For example, to forward a service named `web` on port 8080 to localhost:8080, add `portForward: - resourceType: service; resourceName: web; port: 8080; localPort: 8080`. This allows you to access the application at `http://localhost:8080`. Port forwarding is especially useful for debugging and testing without exposing services publicly.
File Sync for Hot Reload
For interpreted languages or static files, Skaffold supports file sync. In `skaffold.yaml`, under an artifact, define `sync: manual: - src: 'static/**/*'; dest: /app/static`. When a file matching `src` changes, Skaffold copies it directly into the running container(s) without rebuilding the image. This reduces iteration time from seconds to milliseconds. Sync works only when the container is running and the destination path exists.
Enterprise Scenario 1: Fast-Feedback Web Development
A mid-sized company develops a Node.js web application deployed on GKE. Developers frequently tweak front-end code (HTML, CSS, JS) and need to see changes immediately. Without Skaffold, they would run docker build (30 seconds), push to GCR (20 seconds), then kubectl set image (5 seconds) — total ~55 seconds per change. With Skaffold file sync, they configure sync for the static directory. Now a CSS change takes <1 second to appear in the browser. The team uses skaffold dev with port forwarding to localhost:3000. The skaffold.yaml uses Docker builder and kubectl deploy. They also use Cloud Build for CI (not local dev) via a profile. The main challenge is ensuring sync rules don't accidentally overwrite important files; they use .skaffoldignore to exclude sensitive configs.
Enterprise Scenario 2: Microservices with Dependencies
A fintech startup has 20 microservices, each with its own Dockerfile and Kubernetes manifests. Developers often work on one service but need to test against the full stack. They use Skaffold with skaffold dev but only for the service they are modifying. They define dependencies in skaffold.yaml so that if a shared library changes, all dependent services rebuild. The team uses Helm as the deployer because they have complex templating. They also use Skaffold profiles: one for local Minikube (no push), one for GKE dev cluster (push to GCR). The challenge is managing multiple skaffold.yaml files; they use a root skaffold.yaml that references sub-configs. Performance: with 20 services, skaffold dev is resource-heavy; they limit concurrent builds to 3.
Enterprise Scenario 3: Java Microservices with Jib and Cloud Build
An enterprise uses Java with Spring Boot. They want fast local development but also consistent builds across teams. They use Skaffold with Jib builder (no Dockerfile needed) for local development, and Cloud Build builder for CI. The skaffold.yaml has two profiles: dev (Jib local) and ci (Cloud Build). Developers run skaffold dev --profile dev on their workstations. The build time is ~10 seconds because Jib caches layers. The deployment is via kubectl. The team also uses Skaffold's debug feature (--debug) to attach a Java debugger. The main issue is that Jib requires Java 8+, and some old services still use Dockerfiles; they handle this by mixing artifact types in the same config.
Common Misconfigurations and Failures
Wrong kubecontext: If the current context points to production, skaffold dev could deploy to prod. Always set kubeContext in skaffold.yaml or use --kube-context.
Missing dependencies: If an artifact depends on another, and the dependency changes, Skaffold might not rebuild it unless requires is set correctly.
Port forwarding conflicts: If local ports are already in use, Skaffold fails. Use localPort: 0 to auto-assign a random port.
Sync failures: If the destination path doesn't exist in the container, sync fails silently. Always verify paths.
Exactly What ACE Tests on This Topic
The ACE exam (Objective 3.2: Deploy Implement) tests Skaffold in the context of local development workflows targeting GKE. Specific areas include:
- Skaffold commands: skaffold dev vs skaffold run — know that dev is for continuous development (watch mode), run is for one-off deployment.
- Configuration file structure: Recognize a valid skaffold.yaml and know the required sections (build, deploy).
- Builders: Docker, Kaniko, Jib, Cloud Build, Buildpacks. Know which is best for which language (e.g., Jib for Java).
- Deployers: kubectl, Helm, Kustomize, kpt. Know the default (kubectl).
- Port forwarding: How to configure it and its purpose.
- File sync: When to use it (static files, interpreted languages).
- Integration with Cloud Code: Skaffold is the engine behind Cloud Code's run/debug.
- Profiles: How to define and use them (e.g., skaffold dev --profile dev).
Common Wrong Answers and Why Candidates Choose Them
Wrong answer: "Use skaffold run for continuous development." Why: Candidates confuse run (one-shot) with dev (continuous). The exam might ask: "Which command should a developer use to automatically rebuild and redeploy on file changes?" The correct answer is skaffold dev.
Wrong answer: "Skaffold is a CI/CD tool." Why: Skaffold is designed for local development, not CI/CD pipelines. The exam might present a scenario where a team wants to automate builds in a CI pipeline; the correct answer would be Cloud Build, not Skaffold.
Wrong answer: "Skaffold only works with Docker." Why: Skaffold supports multiple builders (Kaniko, Jib, Cloud Build, etc.). Candidates might think it's Docker-only because it's the most common.
Wrong answer: "Skaffold automatically pushes images to Artifact Registry." Why: Skaffold pushes to whatever registry is specified in the image name. It does not automatically choose Artifact Registry. The exam might ask: "Where does Skaffold push images?" The answer: "To the registry defined in the image name."
Specific Numbers, Values, and Terms That Appear Verbatim on the Exam
skaffold dev: continuous development loop
skaffold run: one-time build and deploy
skaffold init: initialize configuration
skaffold delete: delete deployed resources
portForward: section in skaffold.yaml
sync: section for file syncing
googleCloudBuild: builder for Cloud Build
kubeContext: specify cluster context
profiles: for different environments
apiVersion: skaffold/v4beta7 (current version on exam)
Edge Cases and Exceptions the Exam Loves to Test
Multiple artifacts: If you have multiple images, Skaffold builds them in parallel by default (configurable). The exam might ask: "How does Skaffold handle multiple artifacts?"
Custom tags: If you need a specific tag format, use customTemplate or envTemplate.
Cluster-side builds: Kaniko builds inside the cluster; no Docker daemon needed. This is useful when you can't run Docker locally.
Debug mode: skaffold dev --debug automatically configures debuggers for supported languages. The exam might ask: "Which flag enables debug mode?"
How to Eliminate Wrong Answers Using the Underlying Mechanism
If a question mentions "continuous watching" or "automatic redeploy on save", eliminate any answer that suggests skaffold run or skaffold delete. Only skaffold dev provides the watch loop.
If a question mentions "building without Docker", eliminate answers that say "Docker" and look for Kaniko, Jib, or Buildpacks.
If a question mentions "port forwarding", the answer must involve the portForward section in skaffold.yaml or the --port-forward flag.
If a question mentions "file sync", the answer must involve the sync section. If the question says "without rebuilding", sync is the correct answer.
If a question mentions "Cloud Build", the answer must involve googleCloudBuild builder in the build section.
Skaffold is a local development tool that automates the build-push-deploy cycle for Kubernetes applications.
Use `skaffold dev` for continuous development (watches for changes) and `skaffold run` for one-shot deployments.
Skaffold supports multiple builders: Docker, Kaniko, Jib, Cloud Build, Buildpacks.
Skaffold supports multiple deployers: kubectl, Helm, Kustomize, kpt.
File sync (sync) allows updating files in running containers without rebuilding the image.
Port forwarding (portForward) enables local access to cluster services during development.
Skaffold is the engine behind Cloud Code's run/debug features.
Use `skaffold init` to auto-generate a skaffold.yaml configuration file.
Profiles allow different configurations for different environments (e.g., dev vs CI).
Skaffold caches built images locally to speed up subsequent builds.
These come up on the exam all the time. Here's how to tell them apart.
Skaffold dev
Continuous file watching loop
Automatically rebuilds and redeploys on changes
Supports port forwarding automatically with --port-forward
Designed for development (inner loop)
Press Ctrl+C to stop; can optionally clean up
Skaffold run
One-time build and deploy
Does not watch for changes
Port forwarding not automatic (can be configured but not typical)
Designed for CI/CD or one-off deployments
Resources remain after command completes
Docker Builder
Builds locally using Docker daemon
Requires Docker installed and running
Faster for small projects (no network overhead)
No additional cost (local resources)
Not suitable for team consistency (different Docker versions)
Cloud Build Builder
Builds remotely on Google Cloud Build
No local Docker required
Consistent build environment across team
Incurs Cloud Build costs
Requires Cloud Build API enabled and appropriate IAM permissions
Mistake
Skaffold is a CI/CD tool like Jenkins or Cloud Build.
Correct
Skaffold is a local development tool for fast inner-loop iteration. It can integrate with Cloud Build as a builder, but it is not designed for CI/CD pipelines. For CI/CD, use Cloud Build or other CI tools.
Mistake
Skaffold only works with Docker and kubectl.
Correct
Skaffold supports multiple builders (Docker, Kaniko, Jib, Cloud Build, Buildpacks) and multiple deployers (kubectl, Helm, Kustomize, kpt). You are not limited to Docker and kubectl.
Mistake
Skaffold requires a container registry to be configured.
Correct
Skaffold can push to a registry, but for local clusters like Minikube, you can set `local: push: false` to use the Docker daemon directly without pushing.
Mistake
Skaffold automatically deploys to the currently active kubeconfig context.
Correct
By default, yes. But you can override with `kubeContext` in `skaffold.yaml` or the `--kube-context` flag to target a specific cluster, preventing accidental deployments to the wrong cluster.
Mistake
Skaffold rebuilds all images every time any file changes.
Correct
Skaffold rebuilds only the images whose source files have changed. It uses file watching to detect which artifacts are affected. Additionally, file sync can update files in the container without rebuilding at all.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
`skaffold dev` starts a continuous loop that watches for file changes, rebuilds, and redeploys automatically. It is designed for development. `skaffold run` performs a single build and deploy without watching for changes. Use `dev` for inner-loop development, `run` for one-off deployments or CI/CD.
Yes, Skaffold can deploy to any Kubernetes cluster, including remote GKE clusters. Ensure your kubeconfig context points to the correct cluster, or specify `kubeContext` in `skaffold.yaml`. You can also use `--kube-context` flag.
For local clusters like Minikube, you can set `local: push: false` to use the Docker daemon directly without pushing to a registry. For remote clusters, a registry is required so the cluster can pull the image. Skaffold pushes to the registry specified in the image name.
Add a `portForward` section to your `skaffold.yaml` specifying the resource type, name, port, and local port. Alternatively, use the `--port-forward` flag with `skaffold dev` to automatically forward all ports defined in the Kubernetes manifests.
Yes, configure `build: googleCloudBuild: {}` in `skaffold.yaml`. Skaffold will submit the build to Cloud Build, which builds and pushes the image. This ensures consistent builds across the team.
File sync allows you to copy changed files directly into running containers without rebuilding the image. Configure it under `sync` in the artifact definition. It works best for static files or interpreted languages like Python, Node.js, or PHP.
Run `skaffold dev --debug`. Skaffold automatically configures the Java debug agent and forwards the debugging port (usually 5005) to your local machine. You can then attach a debugger from your IDE.
You've just covered Skaffold for Local GKE Development — now see how well it sticks with free ACE practice questions. Full explanations included, no account needed.
Done with this chapter?