Let's answer honestly, how we usually imagine a Kubernetes related environment? So far we have:
-
docker
for building container images (and running them locally but we typically only do that for testing) - a docker registry for storing the container images and making them accessible for kubernetes to use
- YAML manifests to describe what containers, pods... we actually want to run in Kubernetes. These YAML files could refer to docker images we created ourselves.
-
kubectl
as a tool to make requests to the kubernetes API (and create objects based on YAMLs). -
helm
for packaging YAMLs together and making stuff configurable.
Let's add something new now. Suppose we are now working on a real app, and we want to make some code changes and deploy them. What we would need to do:
- first make the code changes.
- then build new docker images. Better give them a different tag than the old docker images so we can tell them apart.
- then push the new docker images to the docker registry.
- then re-deploying the YAMLs to kubernetes. Probably using
helm
: the container images we want to use will be settings inhelm
. So we change the settings before deploying.
๐๐๐ That's a lot of steps! Kubernetes is cool but it slows down our development pensive.
This is where skaffold
comes in the picture. Skaffold is a little glue layer (it is more than that, but we use it as that for now) that:
- builds the docker images
- pushes them
- then deploys your kubernetes resources (optionally using
helm
) with the docker images it just built
And it does everything with one single command.
Skaffold is a ~13k โญ open source CLI tool created by Google that helps with continuous development and deployment of Kubernetes applications specifically aimed at developers.
You can iterate on your application source code locally then deploy to local Kubernetes clusters. Skaffold handles the workflow for building, pushing and deploying your application.
At the most basic level, Skaffold works this way; it:
- Creates Kubernetes configuration files for your apps
- Deploys your application to a local or remote cluster
- Monitors your source code and automatically re-deploys when needed
- Steams logs from your deployed pods to your local terminal
But Skaffold also offers several advanced features on top of this basic functionality. First of all, Skaffold provides an extensible pluggable architecture, allowing developers to choose the appropriate tools for each step involved in building and deploying their application. Skaffold also attempts to provide portability for CI integrations among different build systems, image registries and deployment tools.
skaffold
can also interact with Docker registries by pushing your application image. It is capable to work with plain Kubernetes manifests (using helm
as a package manager is optional).
The figure below depicts the skaffold
workflow, including the generation of the configuration files and the deployment lifecycle in both aforementioned execution modes.
Deployments with Skaffold
Skaffold can be used in two different modes:
โ๏ธ DEVELOPment mode
By issuing the command skaffold dev
. In development mode, it monitors the changes in source code, automatically generates all appropriate Docker images and deploys the images to the Kubernetes cluster. In addition, it provides logs streaming from deployed applications.
โ๏ธ DEPLOYment mode
By issuing the command skaffold run
. In this mode, Skaffold runs a pipeline only once and exits on any errors in the pipeline. This is useful because it can be used as a sanity check after the completion of the development of the application.
The main features of the Scaffold are:
- It monitors local changes in your source code and automatically triggers build/push deployments to local or remote Kubernetes clusters.
- It supports remote and local Docker engines and registries. (Note that using remote Docker engines may increase build times significantly.)
- Can track dependencies between applications and automatically deploy on what was changed.
- Supports existing tooling and workflows with the ability to build and deploy APIs that make each implementation composable to support various different workflows.
One of the main advantages of Skaffold is the number of integrations it provides. It has native support for:
- Buildkit
- Google cloud build
- Helm
- Kustomize
The skaffold.yaml
file, which is the main configuration file, has several options that you can use to change the way your application is built and deployed. It is essentially a mini CI/CD solution for local development that can also take care of testing or pushing images.
Our Skaffold installation will be completed using the standalone executable, for Linux. The installation steps are:
Download the latest version of Skaffold, unpack it and place it to your $PATH
. Verify Skaffold executable and version
$ curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 && \
sudo install skaffold /usr/local/bin/
Application configuration
For this tutorial, a Spring-Boot application will be used. It provides one endpoint that returns a simple greeting message in JSON
format.
In order to run the application, we first need to create a Dockerfile
file to containerize our application. Here is an example:
FROM maven:3-jdk-11 as BUILD
COPY . /usr/src/app
RUN mvn --batch-mode -f /usr/src/app/pom.xml clean package
FROM openjdk:11-jre-slim
ENV PORT 42050
EXPOSE 42050
COPY --from=BUILD /usr/src/app/target /opt/target
WORKDIR /opt/target
CMD ["/bin/bash", "-c", "find -type f -name '*.jar' | xargs java -jar"]
In addition to the Dockerfile
, we will also create a k8s-app.yaml
file in order to generate the Skaffold configuration file. A simple version of k8s-app.yaml
file is shown below:
apiVersion: v1
kind: Pod
metadata:
name: skaffold-demo
spec:
containers:
- name: skaffold-demo
image: somerepo/skaffold-demo
Now, the Skaffold configuration files can be generated by issuing the command:
$ skaffold init
This command will generate a skaffold.yaml
file containing all needed information in order to build and deploy the application to the desired Kubernetes cluster. The generated skaffold.yaml
file is:
apiVersion: skaffold/v1beta28
kind: Config
build:
artifacts:
- image: somerepo/skaffold-demo
deploy:
kubectl:
manifests:
- k8s-app.yaml
It is worth mentioning that when creating a new project, you can bootstrap Skaffold configs with init
command (a very convenient feature). Also, you can define several configs: one config for developing and another one to deploy to the stage environment via the run command (the same workflow as with dev
except for, in this case, Skaffold doesnโt monitor for changes).
Application deployment flow
After successful creation of the configuration files, there are two options to deploy the desired application. During development time, we can use the command:
$ skaffold dev --default-repo localhost:32000
The above command will continuously deploy your application when a file is changed (speeding up development). It monitors the source code files for every change and makes fast re-deployments.
If you want to deploy once and donโt track code changes, you need the run command:
$ skaffold run --default-repo localhost:32000
We use insecure MicroK8s repo here, but you are free to use your own. If no --default-repo
is provided by the user, there is no automated image name rewriting, and Skaffold will try to push the image as provided in the YAML.
After a successful deployment you can check if your application has been deployed in your Kubernetes cluster using the familiar kubectl commands:
$ kubectl get pods
You can check that the application is running by using k9s or your Kubernetes dashboard to ensure your application has been deployed as expected.
Skaffold lets you set breakpoints and step through your application in debug purposes. You may find detailed manual about debugging here.
Finally, you can remove your deployed application with the delete command:
$ skaffold delete
๐ In summary, skaffold
is a very flexible solution that does not require helm
and is very extensive on what kind of integrations it can be used with.
Top comments (2)
I'm a big fan of skaffold! I've been using this for a year now and it's just so great!
As a suggestion, you could also point out that - for local development pushing the images can be omitted by configuring:
Also, during local development it might be desired to enforce that the latest version of each image is being used (see: skaffold.dev/docs/taggers/):
Good points! We'll edit the post ASAP! Thanks for bringing this up!