A year and a half ago, on March 5, 2018, Google released the first alpha version of its Open Source project for CI / CD called Skaffold , whose goal was to create a βsimple and reproducible development for Kubernetesβ so that developers could focus on development, and not on administration. What might be of interest to Skaffold? As it turned out, he has a few trump cards in his sleeve, thanks to which he can become a powerful tool for the developer, and maybe an operating engineer. We will get acquainted with the project and its capabilities.
NB : By the way, we already talked briefly about Skaffold in our general overview of tools for developers whose life is connected with Kubernetes.
Theory. Purpose and features
So, speaking generally, Skaffold solves the problem of automating the CI / CD cycle (at the stages of build, push, deploy), offering the developer prompt feedback, i.e. the ability to quickly get the result of the next code changes - in the form of an updated application running in the Kubernetes cluster. And it can work in different contours (dev, stage, production ...), for which Skaffold helps to describe the appropriate pipelines for roll-out.
The source code for Skaffold is written in Go, and is distributed under the free Apache License 2.0 ( GitHub ).
Consider the main functions and features. The first include the following:
- Skaffold offers tools for creating CI / CD pipelines.
- Allows you to monitor changes in the source code in the background and start the automated process of building code into container images, publishing these images to the Docker Registry and deploying them to the Kubernetes cluster.
- Synchronizes files in the repository with the working directory in the container.
- Automatically tests using container-structure-test.
- Forwards ports.
- Reads the logs of the application running in the container.
- Helps in debugging applications written in Java, Node.js, Python, Go.
Now about the features:
- Skaffold itself has no cluster-side components . That is, you do not need to additionally configure Kubernetes to use this utility.
- Different pipelines for your application . Need to roll out the code in the local Minikube while you are developing, and then on stage or production? To do this, profiles and user configurations, environment variables and flags are provided, which allow you to describe different pipelines for one application.
- CLI Only console utility and configurations in YAML. On the network you can find references to attempts to create an experimental GUI , but at the moment this probably only means that someone needs it, but not really.
- Modularity . Skaffold is not an independent combine harvester, but seeks to use separate modules or existing solutions for specific tasks.
Illustration of the latter:
- At the assembly stage, you can use:
- docker build locally, in a cluster using kaniko or in Google Cloud Build;
- Bazel locally;
- Jib Maven and Jib Gradle locally or on Google Cloud Build;
- custom build scripts run locally. If you need to run another (more flexible / familiar / ...) solution for the assembly, it is described in the script so that Skaffold runs it ( example from the documentation ). This allows you to use any collector that can be called using a script;
- At the testing stage, the already mentioned container-structure-test is supported;
- For deployment are provided:
- Kubectl;
- Helm;
- kustomize.
Thanks to this, Skaffold can be called a kind of framework for building CI / CD . Here is an example of a workflow when using it (from the project documentation):
What does Skaffold's work look like in general?
- The utility monitors changes in the source directory. If modifications are made to the files, they are synchronized with the application pod in the Kubernetes cluster. If possible, without reassembling the image. Otherwise, a new image is going.
- The assembled image is checked using container-structure-test, tagged and sent to the Docker Registry.
- After that, the image is deployed - it is deployed in a Kubernetes cluster.
- If the launch was initialized using the
skaffold dev
command, then we begin to receive logs from the application, and Skaffold expects changes to repeat all the steps again.
Skaffold milestones illustration
Practice. Trying Skaffold
To demonstrate the use of Skaffold, Iβll take an example from the project βs GitHub repository . By the way, there you can find many other examples that take into account various specifics. All actions will be performed locally in Minikube. Installation is simple and takes a few minutes, and kubectl is required to get started.
Install Skaffold:
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 chmod +x skaffold sudo mv skaffold /usr/local/bin skaffold version v0.37.1
Let's clone the Skaffold repository with the necessary examples:
git clone https://github.com/GoogleContainerTools/skaffold cd skaffold/examples/microservices
I chose an example with two pods, each of which contains one small application on Go. One application is the frontend (leeroy-web), a redirect request to the second application is the backend (leeroy-app). Let's see how it looks:
~/skaffold/examples/microservices # tree . βββ leeroy-app β βββ app.go β βββ Dockerfile β βββ kubernetes β βββ deployment.yaml βββ leeroy-web β βββ Dockerfile β βββ kubernetes β β βββ deployment.yaml β βββ web.go βββ README.adoc βββ skaffold.yaml 4 directories, 8 files
leeroy-app and leeroy-web contain Go code and simple Dockerfiles for building this code locally:
~/skaffold/examples/microservices # cat leeroy-app/Dockerfile FROM golang:1.12.9-alpine3.10 as builder COPY app.go . RUN go build -o /app . FROM alpine:3.10 CMD ["./app"] COPY --from=builder /app .
I will not give the application code - it is enough to know that
leeroy-web
accepts requests and proxies them to
leeroy-app
. Therefore, in the
Deployment.yaml
files, there is Service only for the
app
(for internal routing). The
web
pod port will be thrown to us for quick access to the application.
What
skaffold.yaml
looks
skaffold.yaml
:
~/skaffold/examples/microservices # cat skaffold.yaml apiVersion: skaffold/v1beta13 kind: Config build: artifacts: - image: leeroy-web context: ./leeroy-web/ - image: leeroy-app context: ./leeroy-app/ deploy: kubectl: manifests: - ./leeroy-web/kubernetes/* - ./leeroy-app/kubernetes/* portForward: - resourceType: deployment resourceName: leeroy-web port: 8080 localPort: 9000
All the steps mentioned above are described here. In addition to this config, there is also a file with global settings -
~/.skaffold/config
. It can be edited manually or through the CLI - for example, like this:
skaffold config set --global local-cluster true
This command sets the
local-cluster
global variable to
true
, after which Skaffold will not attempt to 'push' the images into the remote registry. If you are developing locally, you can use this command to add images locally as well.
Back to
skaffold.yaml
:
- At the
build
stage, we indicate that you need to collect and save the image locally. After the assembly starts for the first time, we will see the following:
// .. Minikube , // , # minikube ssh $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE leeroy-app 7d55a50803590b2ff62e47e6f240723451f3ef6f8c89aeb83b34e661aa287d2e 7d55a5080359 4 hours ago 13MB leeroy-app v0.37.1-171-g0270a0c-dirty 7d55a5080359 4 hours ago 13MB leeroy-web 5063bfb29d984db1ff70661f17d6efcc5537f2bbe6aa6907004ad1ab38879681 5063bfb29d98 5 hours ago 13.1MB leeroy-web v0.37.1-171-g0270a0c-dirty 5063bfb29d98 5 hours ago 13.1MB
As you can see, Skaffold independently tested the images. By the way, several tagging policies are supported. - Further in the config,
context: ./leeroy-app/
, i.e. The context in which the image is assembled is specified. - At the deployment stage, it is determined that we will use kubectl and a mask for the desired manifestos.
-
PortForward
: similar to how we usually forward ports usingkubectl port-forward
, give Skaffold instructions to invoke this command. In this case, the local port 9000 is forwarded to 8080 in Deployment with the nameleeroy-web
.
It's time to start
skaffold dev
: the team will create an ongoing βfeedback loopβ, i.e. not only collects everything and installs in a cluster, but also tells about the status of pods at the moment, will monitor the changes and update the status of pods.
Here is the result of running
skaffold dev --port-forward
when reassembling:
Firstly, itβs clear that the cache is being used. Next - the application is assembled, deployed, ports are forwarded. Since
--port-forward
is specified, Skaffold forwarded the port to the
web
, as requested, but he forwarded the
app
at its own discretion (chose the nearest free one). After that, we get the first logs from the applications.
Check performance?
~/skaffold/examples/microservices # kubectl get po NAME READY STATUS RESTARTS AGE leeroy-app-6998dfcc95-2nxvf 1/1 Running 0 103s leeroy-web-69f7d47c9d-5ff77 1/1 Running 0 103s ~/skaffold/examples/microservices # curl localhost:9000 leeroooooy app!!!
Modify the
leeroy-app/app.go
- it takes a few seconds ... and:
~/skaffold/examples/microservices # kubectl get po NAME READY STATUS RESTARTS AGE leeroy-app-ffd79d986-l6nwp 1/1 Running 0 11s leeroy-web-69f7d47c9d-5ff77 1/1 Running 0 4m59s ~/skaffold/examples/microservices # curl localhost:9000 leeroooooy Habr!!!
At the same time, Skaffold itself brought to the console the same thing as before, with the exception of one point: it rolled out only the
leeroy-app
, and not all at once.
More practice
It is worth mentioning that when creating a new project, the configs for Skaffold can be bootstrap using the
init
command, which is very convenient. In addition, you can write several configs: develop on the default config, and then roll out to the stage with the
run
command (the same process as
dev
, just does not follow the changes), using a different config.
Katacoda has a tutorial with an example even simpler. But it offers a ready-made sandbox with Kubernetes, the application and Skaffold. A great option if you are interested to try the very basics on your own.
One possible use case for Skaffold is to conduct development on a remote cluster. Not everyone is comfortable running Minikube on their own hardware, and then rolling out the application and waiting for its proper functioning ... In this case, Skaffold perfectly solves the task, which, for example, Reddit engineers can confirm, as we already wrote about in our blog.
And in this publication from Weaveworks you can find an example of creating a pipeline for production.
Conclusion
Skaffold is a convenient tool for building pipelines, implying rollout of applications in Kubernetes and focused primarily on development needs. With it, itβs quite simple to create a βshortβ pipeline that takes into account the basic needs of the developer, but you can also organize larger processes if you wish. One of the illustrative examples of using Skaffold in CI / CD processes is a test project of 10 microservices that use the capabilities of Kubernetes, gRPC, Istio and OpenCensus Tracing.
Skaffold has already received almost 8000+ stars on GitHub, is being developed by Google and is part of GoogleContainerTools - in general, at the moment there is every reason to believe that the project will develop happily ever after.
PS
Read also in our blog: