Skaffold is my top Kubernetes developer tool of the year so far. Since its accidental reveal about 3 months ago, it already got 3,700 stars on GitHub. Clearly the community is lovin’ it.
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 101
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 modes
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:
Most notably:
skaffold dev
is for your local development workflow on Minikube/Docker-for-Desktopskaffold run
should 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.
Google-ism much?
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
go
will 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.
If you’re serious about build times, you should use rules_docker/distroless with Skaffold’s Bazel support and/or invest in efficient Dockerfile builds.
Learn more
-
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.
Try Skaffold out and shoot me a tweet about what you think about it! If you find any issues please report them.