I have been using Skaffold from the get go for all my new projects that involve multi-tier microservices, and it works like a charm on top of Docker for Mac/Minikube.
Skaffold is a tool to develop containerized applications locally or remotely while deploying them on Kubernetes. It automatically builds and deploys your apps as you change your source code.
Skaffold primarily simplifies the “build → deploy → refactor → repeat” cycle.
In a single command, Skaffold can:
- Build container images (either locally or remotely)
- Push container images (unless the target is local cluster)
- Update Kubernetes manifests with the correct image tags
- Deploy your application with “kubectl apply” or “helm upgrade”
- Stream logs from the deployed/running Pods.
- Watch for changes in the source code or Kubernetes manifests, and repeat 1-5
Features 1 & 6 are what freshpod does, and 4 & 5 are what docker-compose does (but for Docker/Swarm). Skaffold brings all these ideas together in a bundle with awesome experience designed for Kubernetes. It’s not magic, so let’s unfold it all.
Skaffold not only works on your laptop as a development tool, it also lets you
reuse the same
skaffold.yaml file to do deployments to your clusters in your
continuous deployment system.
This is possible because different parts of Skaffold are exposed through different commands:
skaffold devis for your local development workflow on Minikube/Docker-for-Desktop
skaffold runshould be used from continuous deployment environments like Jenkins, Travis CI etc.
How Skaffold works
Here’s a diagram explaining what happens when you run “skaffold dev” or “skaffold run”:
Cool Skaffold features
Remote development: Skaffold doesn’t require you to run a local Kubernetes cluster (minikube or docker-for-desktop). It can build/push images locally with docker, and run them on the remote clusters (such as GKE). This is a laptop battery saver!
More remote development: You actually don’t need to run a local docker either. Skaffold can do remote builds using services like Google Container Builder. Although it’ll be slow.
Tag management: In your Kubernetes manifests, you leave the image tags out in the “image:” field, and Skaffold automatically changes the manifests with the new tags as it rebuilds the images.
Rebuild only what’s changed: If your microservices are on separate directories, changing source code for one will not cause rebuild for all images. Skaffold understands which images have been impacted by the change.
Cleanup on exit: Terminating “skaffold dev” runs a routine that cleans up the deployed k8s resources. If this fails, you can run “skaffold delete” to clean up deployed artifacts.
If you noted above, I have mentioned Skaffold can do certain things with Google Container Builder. It’s true that there are Google-specific features and magic in Skaffold. That said, the Skaffold team is open for more integrations!
Similarly, the “deploy” step currently only supports “kubectl” and “helm”. If you’re using “ksonnet“, “kustomize“, or some other tool to deploy, Skaffold currently may not work for you. But again, the project is actively seeking contributions for more tooling support. This tool should not have lock-in to a vendor or particular tools (other than Kubernetes itself).
Build Speed Challenges
Rebuilding your code every time something changes can take time. I’m using Go for my applications and Go is a compiled language. Go has a fast compiler but there are some things that slow this process down:
- Docker has to tar up and send my code to docker-engine which lives in a VM.
- docker-engine VM usually has less CPU/memory than my host machine.
- rebuilt image is saved to file system of the VM, which is slower than my host fs.
- most (>90%) of the compiled packages my program depends on almost never
change. Yet, I still have to recompile them every time in a container (no
way to use go1.10 build cache in
a docker container yet). On my workstation
gowill make use of the build cache.
- if you have more Dockerfile instructions after compilation, those steps will not be cached.
- “kubectl apply” will be executed and existing pods need to be terminated, this takes time.
In most cases, running something directly on your workstation is probably going to be faster.
There a lot of great examples in Skaffold github repository. You should start from there.
I have converted Docker’s example voting app to use Skaffold. It’s in a tutorial format at the skaffold-from-laptop-to-cloud repository.