018: Client-side Kubernetes operations with Skaffold Skip to main content

018: Client-side Kubernetes operations with Skaffold

Skaffold is a client-only tool that watches changes on your local file system for automatically deploying to a local or remote Kubernetes cluster.

The daily mood

I heard several times that Flux may not offer the best developer experience. On one hand it might not fullfill all our requirements as per our Helm custom plugin. On the other hand despite it is fairly easy to use, it might ask developers and DevOps engineers for too much delegation to the operator running "behind the scenes", without offering a clear feedback loop. Today we are looking at Skaffold, a more developer-friendly tool.

What is the particularity of Skaffold

Skaffold follows a declarative approach but is not a pure GitOps implementation since Git is not the single-version-of-the-truth but a local copy of it.
The project was started 2y ago, is backed by Google and actually used behind their cloud-based IDE Cloud Code (IntelliJ/VSC as-a-Service).

Setup

Download Skaffold command-line and add it to your PATH.
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64
sudo install skaffold /usr/local/bin/
Client commands
  • init: setup project
  • config: change project configuration
  • build: build your app
  • deploy: deploy your app
  • render: render Kubernetes manifests
  • dev: build and deploy your app every time your code changes
  • run: build and deploy your app once, similar to a CI/CD pipeline
  • debug: same as run but verbose
Workflow definition

Skaffold follows a very minimalistic, descriptive approach to build and deployment. Each pipeline is configured by a skaffold.yaml file describing a Config object having one section per pipeline stage.
# skaffold.yaml
apiVersion: skaffold/v2alpha1
kind: Config
build:
  artifacts:
  - image: myDockerImage
deploy:
  kubectl:
    manifests:
    - k8s*.yaml
When running skaffold from here, the following actions are automatically executed:
  • Build a Docker image from source using Dockerfile (if available in current directory)
  • Tag the Docker image with default sha256 hash of its content
  • Update Kubernetes manifest to use the new image
  • Deploy Kubernetes manifest using kubectl apply -f
  • Stream logs back from the deployed application
Note that regarding image build we'll give us statisfied with the getting-started example from Skaffold, and the possibility to define a custom command/script instead of standard settings. Also, a default remote image/artifact repository can be set as part of the project configuration.

Regarding application deployment we will re-use the Kubernetes manifest of a custom nginx application from a previous post. So our starting point is the following directory.
$ tree
.
├── container-configmap.yaml
├── deployment.yaml
├── nginx-deployment.yaml
├── nginx-service.yaml
└── volume-configmap.yaml
Skaffold assists you in the creation of a new configuration.
$ skaffold init --skip-build
apiVersion: skaffold/v2beta4
kind: Config
metadata:
  name: --skaffold
deploy:
  kubectl:
    manifests:
    - container-configmap.yaml
    - deployment.yaml
    - nginx-deployment.yaml
    - nginx-service.yaml
    - volume-configmap.yaml
Do you want to write this configuration to skaffold.yaml? [y/n]: y
Configuration skaffold.yaml was written
You can now run [skaffold build] to build the artifacts
or [skaffold run] to build and deploy
or [skaffold dev] to enter development mode, with auto-redeploy $ skaffold dev
And that's it! As soon as I change something to the files watched by skaffold, like my nginx replicaCount (nginx-deployment.yaml) or welcome message (volume-configmap.yaml), then Skaffold takes care of updating the cluster. Note that the target cluster cluster context/namespace can be defined as well as part of the project configuration.

Profiles

We mentioned a couple of times the project configuration which is obviously a global setting which you are able to overwrite on purpose. Skaffold also supports settings per environment via the profile feature instanciated with -p.
$ vi skaffold.yaml
...
profiles:
- name: local-cluster
  activation:
  - env: ENV=local
  - kubeContext: microk8s
    command: dev
- name: dev-cluster
  activation:
  - env: ENV=dev
  - kubeContext: arn:aws:eks:<aws_region>:<aws_account>:cluster/aws_dev
    command: run
$ skaffold dev -p devcluster
Note that JSON patch notation is also supported by profiles, so that only the required configuration changes need to be specified.

Conclusion

We have tested a more developer-friendly approach to Kubernetes deployment automation. Next we'll have a look at Skaffold integration with Helm, and try to put together some pro and contra in a sort of best-practice.

Source


References

Comments