⚡️ Updated on July 3, 2018 to reflect changes introduced by Skaffold 0.9.

Using Kubernetes for Local Development

In the past years, I've been using Kubernetes in production both at RisingStack - the Node.js consulting company I've co-founded - and at GoDaddy at large scale. One of the common challenges I've seen is the lack of proper tooling on how one can develop their services locally against a real Kubernetes cluster. In practice, it meant that the developers ran their local instances against development or staging environments, which is far from ideal: if don’t have those services running locally, debugging them can be challenging.

A few days ago, I bumped into Skaffold, a command line tool that facilitates continuous development for Kubernetes applications. In this article, I am going to show you how you can start developing a Node.js app with the help of Skaffold and Kubernetes.

Skaffold is a command line tool that facilitates continuous development for Kubernetes applications. You can iterate on your application source code locally then deploy to local or remote Kubernetes clusters. Skaffold handles the workflow for building, pushing and deploying your application. It can also be used in an automated context such as a CI/CD pipeline to leverage the same workflow and tooling when moving applications to production. - The official Skaffold docs

In practice, Skaffold can:

detect changes in the source code and automatically build, push and deploy

in the source code and automatically build, push and deploy automatically update image tags , so you don't have to do that manually in the Kubernetes manifest files

, so you don't have to do that manually build/deploy/push different applications at once, so it is a perfect fit for microservices too ,

, support both development and production environment, by running the manifests only once, or continuously watching for changes.

Installing Skaffold

Prerequisites:

Make sure that you have Minikube installed - (Skaffold works with any Kubernetes clusters, for the sake of simplicity I picked Minikube) Make sure that you have kubectl installed Make sure that you have docker installed

Once you have all the dependencies installed, visit the Skaffold Releases page, and grab a build that suits your system, then put it on the system path.

Developing a Node.js Application with Skaffold

Let's start with a simple Node.js application - no magic here, just a dummy HTTP server using Express:

const express = require ( "express" ) ; const app = express ( ) ; app . get ( "/" , function ( req , res ) { res . json ( { status : "ok" , } ) ; } ) ; app . listen ( 3000 , ( err ) => { if ( err ) { throw err ; } console . log ( "server is listening" ) ; } ) ;

Next, let's create a Dockerfile to containerize the above Node.js application:

FROM node : 8.10 .0 - alpine WORKDIR / usr / src / app COPY package . json . COPY package - lock . json . RUN npm install COPY . . EXPOSE 3000 CMD node index . js

In order to run this application inside Kubernetes, we have to create a deployment and a service to expose the given deployment. To do so, I am using:

# k8s - app . yml apiVersion : extensions / v1beta1 kind : Deployment metadata : name : node - app spec : replicas : 1 template : metadata : labels : app : node - app spec : containers : - name : node - app image : node - app ports : - containerPort : 3000 -- - apiVersion : v1 kind : Service metadata : name : node - app labels : app : node - app spec : selector : app : node - app ports : - port : 3000 protocol : TCP nodePort : 30003 type : LoadBalancer

Now you can create a dockerized Node.js application by issuing the docker build . command. However, with that approach, you would only have the image built, but it wouldn’t be running inside a Kubernetes cluster. This is where Skaffold helps out.

Skaffold uses YAML files to describe workflows. For the above application, ours may look like this:

# skaffold . yaml apiVersion : skaffold / v1alpha2 kind : Config build : artifacts : - imageName : node - app workspace : . docker : { } bazel : null local : skipPush : null googleCloudBuild : null kaniko : null deploy : helm : null kubectl : manifests : - k8s - app . yml kustomize : null

As you can see, we have two main parts of the configuration file, the first one being the build section, the second one being the deploy section. In the build section, we can define what artifacts (most probably Docker images) we'd like to build, while in the deploy section we can define resources (like services or deployments) we'd like to see in Kubernetes.

The paths array tells Skaffold where the Kubernetes manifests are, while with the parameters, you can inject variables into the manifests. To get a more detailed description, please refer to the annotated skaffold example.

With these last steps, you've finished the setup process of Skaffold. Chances are, if you are already deploying applications using Kubernetes, you can simply reuse your Dockerfile and Kubernetes manifests, so you’ll only have to write the Skaffold yaml .

To start using Skaffold, you will have to start up Minikube (using minikube start ), then run Skaffold:

skaffold dev Starting build ... Found minikube or Docker for Desktop context , using local docker daemon . Sending build context to Docker daemon 2.014 MB Step 1 / 8 : FROM node : 8.6 .0 - alpine -- - > b7e15c83cdaf Step 2 / 8 : WORKDIR / usr / src / app -- - > Using cache -- - > e4cf80f4e3d6 Step 3 / 8 : COPY package . json . -- - > Using cache -- - > 78 f285cee4cb Step 4 / 8 : COPY package - lock . json . -- - > Using cache -- - > 52 c2cc2364fe Step 5 / 8 : RUN npm install -- - > Using cache -- - > f773a4b93a4b Step 6 / 8 : COPY . . -- - > b0cc2a87fe89 Step 7 / 8 : EXPOSE 3000 -- - > Running in cd4d940ddaff -- - > e2f558c9f067 Step 8 / 8 : CMD node index . js -- - > Running in 4752 ba26ff2c -- - > 5 b62e8667662 Successfully built 5 b62e8667662 Successfully tagged 71 dba0517e741b4c8a11728cf905fe84 : latest Successfully tagged node - app : 5 b62e86676627e49417af333b8da588b728bd3c9e5d777f6db5565d0e7a91015 Build complete . Starting deploy ... Deploying k8s - app . yml ... Deploy complete . [ node - app - 5 d4df6585b - r87lk node - app ] server is listening

Once you start modifying your files, Skaffold will automatically re-deploy to Kubernetes. To access your running service, you can run minikube service [service-name] . In our example, it is minikube service node-app . This will open your default browser with the Node.js application you've just deployed.

I hope that this tutorial will save you some time when developing services with Kubernetes - as I am fairly new to Skaffold too, please let me know in the comments below in case I missed anything! You can check out the whole example project on my GitHub.

Furher reading