Getting Started with Skaffold for Kubernetes Deployments

Kubernetes has experienced rapid growth over the years, with a recent post from the Cloud Native Computing Foundation reporting a userbase increase of about 67% in just the past year. Kubernetes is a container orchestration platform that automates how containers are deployed, how they communicate, and how traffic is routed between them; it also scales configurations for both the containerized workloads and the underlying infrastructure that comprises the cluster. In this article, you will learn about Skaffold, scenarios in which it really shines, and how to implement it for your Kubernetes development workflow.

Adopting Kubernetes in your project requires an assessment of your software team’s ability to manage both the cluster and the maintenance it requires. While some involvement from application developers is necessary, the primary responsibility for operating Kubernetes tends to fall to DevOps and SRE teams or individuals.

With this in mind, you want your software teams to focus on application optimization, supported by an efficient workflow. An example of this is the process of automatically testing and building software before releasing it to a specific environment, better known as CI/CD. However, a CI/CD pipeline can be unnecessary and time consuming for a cloud-native inner development loop. The inner development loop is essentially the iterative process of coding, building, and testing an application on a local machine.

In the context of containerized applications and Kubernetes development, software teams have to work with Dockerfiles and YAML configuration files, typically referred to as manifest files, that describe how an application is to be deployed to a cluster. A full-fledged CI/CD system would be excessive, so software developers need a tool that can support the development loop of cloud-native applications on their local machines.

Having an automated approach to building container images from source code and deploying them to a Kubernetes cluster in a development environment will enhance your team’s cloud-native development lifecycle.

Skaffold enables this kind of workflow. It is a CLI tool from Google that provides continuous development for applications being released to a Kubernetes cluster. Skaffold is particularly helpful for software teams that would benefit from application debugging, a toolkit to create CI/CD pipelines, an automated approach to building Docker images and YAML manifest image tagging, and quick reflections of source code changes in their Kubernetes clusters.

In this article, you will learn about Skaffold, scenarios in which it really shines, and how to implement it for your Kubernetes development workflow.

What is Skaffold?

Skaffold is an open-source project aimed at simplifying the cloud-native development journey for software developers, whether your application runs in a local or remote Kubernetes cluster. Skaffold has been generally available since November 7, 2019, and is released under the Apache 2.0 license.

Cloud-native application development can be arduous and time-consuming. Software developers create new features or fix bugs. Once this is done, a container image with the latest changes needs to be built, tagged, and pushed to an image repository.

When the new image tag has been successfully pushed, the next step is to modify the manifest files (typically a Deployment or Pod manifest file) to reflect the image tag changes, then deploying the application to your Kubernetes cluster. Doing this manually, over and over again, can quickly become an impediment to workflow efficiency and quality, not to mention the developer experience.

Below are some of the use cases in which Skaffold proves especially useful.

  • Efficient Development Workflow: Instead of relying on a tedious manual process for deploying to a Kubernetes cluster, Skaffold automates and abstracts the build and deployment steps of container images for you. This makes the inner development loop more efficient, with quick changes and fixes visible in Pods running in the local or remote cluster.
  • Creating CI/CD Pipelines: Using Skaffold commands (i.e. skaffold dev, skaffold build, or skaffold deploy), you can create a continuous delivery pipeline for local development—or create a production-grade CI/CD pipeline integrated with other tools such as GitHub Actions or ArgoCD.
  • Minimal Kubernetes Knowledge and Experience: Skaffold is designed to take the responsibility of Kubernetes configuration management out of the hands of software development teams. The goal is to enable developers to focus on application development, not on acquisition of in-depth knowledge of Kubernetes.
  • Improve Developer Experience: Software developers aren’t opposed to Kubernetes environments, but they want a simplified approach that abstracts away some of the complexities of Kubernetes. A tool like Skaffold is suitable for enhancing the entire developer experience, from code changes to results in the cluster.

Implementing Skaffold

In this section, you’ll install Skaffold and create a simple project to get a taste of the inner development workflow with Skaffold.

Prerequisites

Provision Kubernetes Cluster

In this section, you will use Rancher Desktop to provision a Kubernetes cluster. Rancher Desktop gives you a fully fledged Kubernetes cluster, but is very lightweight and easy to get running. It gives you a single-node cluster out of the box, and updates the context of your kubeconfig to connect to the Rancher Desktop cluster. Once Rancher Desktop is ready, you can check that you can connect to your cluster with one of the following commands:

kubectl cluster-info
kubectl config current-context

Installing Skaffold

After provisioning your cluster, the next step is to install Skaffold. Below are the commands to install Skaffold on the major operating systems or on Docker. For more details on installation, you can view the official documentation.

Linux

# For Linux x86_64 (amd64)
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 && 
sudo install skaffold /usr/local/bin/

# For Linux ARMv8 (arm64)
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-arm64 && 
sudo install skaffold /usr/local/bin/

MacOS

# For macOS on x86_64 (amd64)
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-darwin-amd64 && 
sudo install skaffold /usr/local/bin/

# For macOS on ARMv8 (arm64)
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-darwin-arm64 && 
sudo install skaffold /usr/local/bin/

Windows

# Using Scoop
scoop bucket add extras
scoop install skaffold

# Using chocolatey
choco install -y skaffold

Docker

docker run gcr.io/k8s-skaffold/skaffold:latest skaffold <command>

After selecting one of the above options, verify that Skaffold has been installed by running the following command:

skaffold version

Getting Started with Skaffold

This section will cover the usage of Skaffold with a custom Node.js application. This application has a single endpoint (/test) that returns the text “Simple Node App Working!”.

// Express App Setup
const express = require('express');
const http = require('http');
const bodyParser = require('body-parser');
const cors = require('cors');

// Initialization
const app = express();
app.use(cors());
app.use(bodyParser.json());

// Express route handlers
app.get('/', (req, res) => {
  res.status(200).send({ text: 'Welcome To This Basic Node.js Application!' });
});

app.get('/test', (req, res) => {
  res.status(200).send({ text: 'Simple Node App Working!' });
});

module.exports = app;

Initial Kubernetes Manifest Files

The following manifest files will be applied to the cluster by Skaffold. The deployment.yaml file will be applied continuously, based on the incremental changes made to the source code.

apiVersion: apps/v1
kind: Deployment
metadata:
 name: express-test
spec:
 replicas: 1
 selector:
   matchLabels:
     app: express-test
 template:
   metadata:
     labels:
       app: express-test
   spec:
     containers:
     - name: express-test
       image: <your-dockerhub-account-id>/express-test
       resources:
          limits:
            memory: 128Mi
            cpu: 500m
       ports:
       - containerPort: 8080

Here is a service to ensure the application can be invoked from your browser:

apiVersion: v1
kind: Service
metadata:
  name: express-test-svc
spec:
  selector:
    app: express-test
  type: LoadBalancer
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080

Initial Dockerfile

Create the initial Dockerfile that Skaffold will use to build container images from source code changes.

FROM node:14-alpine
WORKDIR /usr/src/app
COPY ["package.json", "package-lock.json*", "npm-shrinkwrap.json*", "./"]
RUN npm install 
COPY . .
EXPOSE 8080
RUN chown -R node /usr/src/app
USER node
CMD ["npm", "start"]

Initialize Skaffold

You can initialize your project by running skaffold init, after which you’ll be prompted with a series of questions that will shape the output of your Skaffold configuration file. The skaffold.yaml configuration file describes the build and deployment aspects of the workflow. This file is automatically generated with the skaffold init command.

apiVersion: skaffold/v2beta26
kind: Config
metadata:
  name: nodejs-express-test
build:
  artifacts:
  - image: <your-dockerhub-account-id>/express-test
    docker:
      dockerfile: Dockerfile
deploy:
  kubectl:
    manifests:
    - deployment.yaml
    - service.yaml

Skaffold Init Command

Execute Continuous Development Workflow

Once your project has been initialized, you can proceed to run the continuous development workflow. In this mode, Skaffold will continuously watch the source code files for any changes. When a change is detected, Skaffold will rebuild the image and push it to a local or remote container registry, depending on your Kubernetes cluster configuration. After that, Skaffold will re-deploy the application.

To create this workflow, run skaffold dev.

Skaffold Dev Command Output

After successful deployment, you can verify that the relevant Kubernetes resources have been created.

kubectl get pods
kubectl get services

You can view your application by going to localhost in the browser and entering the port on which the application is listening for traffic, which in this case is 8080. The entire URL is http://localhost:8080/test. If you’re using a LoadBalancer service as specified above, Rancher Desktop will take care of forwarding traffic to the service, which will in turn forward traffic to the application running in the pod replicas. If you’re using a NodePort service type, the application’s URL needs to include the assigned NodePort for the created service. This can be retrieved by running kubectl describe service express-test-svc.

Before Source Code Change

After that, modify the source code for the application in the src/app.js file from Simple Node App Working! to Simple Node App Working 2!. This change will trigger a rebuild, and Skaffold will deploy the updated image to your cluster.

After Source Code Change

Conclusion

As Kubernetes becomes more deeply embedded in the landscape, software teams and businesses should encourage and enable their developers to make use of Kubernetes in a way that doesn’t pull them away from their core responsibilities. Software developers’ primary concern should be using efficient workflows to deliver high-quality software, and the complexities of Kubernetes shouldn’t get in their way. Skaffold is a tool that automates and abstracts the workflow for software developers, allowing for cloud-native development with Kubernetes without compromising on developer experience, efficiency, or best practices.

About The Author