Integration with Continuous Delivery

Jonathan Baier

December 2015

In this article by Jonathan Baier, the author of the book Getting Started with Kubernetes, we will go through a brief description on how to deploy Gulp.js task on Kubernetes, its prerequisites, and the variety of plugins using use cases.

(For more resources related to this topic, see here.)

Continuous integration and delivery are key components to modern development shops. Speed to market or meantime-to-revenue are crucial for any company that is creating their own software. We'll see how Kubernetes can help you.

CI/CD often requires ephemeral build and test servers to be available whenever changes are pushed to the code repository. Docker and Kubernetes are well suited for this task as it's easy to create containers in a few seconds and just as easy to remove them after builds are run. In addition, if you already have a large portion of infrastructure available on your cluster, it can make sense to utilize the idle capacity for builds and testing.

Kubernetes integrates with a number of CI/CD tools in the marketplace. In this article, we will look at one in particular named Gulp.js. Gulp.js is a simple task runner used to automate the build process using JavaScript and Node.js.

Gulp.js

Gulp.js gives us the framework to do Build as code. Similar to Infrastructure as code, this allows us to programmatically define our build process. We will walk through a short example to demonstrate how you can create a complete workflow from a Docker image build to the final Kubernetes service.

Prerequisites

For this section, the reader will need a Node.js environment installed and ready, including the node package manage (npm). If you do not already have these packages installed, you can find instructions at https://docs.npmjs.com/getting-started/installing-node.

You can check that Node.js is installed correctly with a node –v command.

You'll also need the Docker CLI and a DockerHub account to push a new image. You can find instructions to install the Docker CLI at https://docs.docker.com/installation/.

You can easily create a DockerHub account at https://hub.docker.com/.

After you have your credentials, you can log in with the CLI using the following code:

$ docker login

Gulp build example

Let's start creating a project directory named node-gulp:

$ mkdir node-gulp
$ cd node-gulp

Next, we will install the gulp package and check whether it's ready by running the command with the version flag as follows:

$ npm install -g gulp

You may need to open a new terminal window to make sure that gulp is on your path. Also, make sure to navigate back to your node-gulp directory:

$ gulp –v

Next, we will install gulp locally in our project folder as well as the gulp-git and gulp-shell plugins as follows:

$ npm install --save-dev gulp
$ npm install gulp-git –save
$ npm install --save-dev gulp-shell

Finally, we need to create a Kubernetes controller and service definition file as well as gulpfile.js to run all our tasks. We have the following code:

apiVersion: v1
kind: ReplicationController
metadata:
  name: node-gulp
  labels:
    name: node-gulp
spec:
  replicas: 1
  selector:
    name: node-gulp
  template:
    metadata:
      labels:
        name: node-gulp
    spec:
      containers:
      - name: node-gulp
        image: <your username>/node-gulp:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 80
Listing 5-1: node-gulp-controller.yaml

As you can see, we have a basic controller. You will need to replace <your username>/node-gulp:latest with your username as follows:

apiVersion: v1
kind: Service
metadata:
  name: node-gulp
  labels:
    name: node-gulp
spec:
  type: LoadBalancer
  ports:
  - name: http
    protocol: TCP
    port: 80
  selector:
    name: node-gulp
Listing 5-2: node-gulp-service.yaml

Next, we have a simple service that selects the pods from our controller and creates an external load balancer for access. We have the following code:

var gulp = require('gulp');
var git = require('gulp-git');
var shell = require('gulp-shell');

// Clone a remote repo
gulp.task('clone', function(){
  return git.clone('https://github.com/jonbaierCTP/getting- 
    started-with-kubernetes.git', function (err) {
    if (err) throw err;
  });

});

// Update codebase
gulp.task('pull', function(){
  return git.pull('origin', 'master', {cwd: './getting-started- 
    with-kubernetes'}, function (err) {
    if (err) throw err;
  });
});

//Build Docker Image
gulp.task('docker-build', shell.task([
  'docker build -t <your username>/node-gulp ./getting-started- 
    with-kubernetes/ docker-image-source/container-info/',
  'docker push <your username>/node-gulp'
]));

//Run New Pod
gulp.task('create-kube-pod', shell.task([
  'kubectl create -f node-gulp-controller.yaml',
  'kubectl create -f node-gulp-service.yaml'
]));

//Update Pod
gulp.task('update-kube-pod', shell.task([
  'kubectl delete -f node-gulp-controller.yaml',
  'kubectl create -f node-gulp-controller.yaml'
]));
Listing 5-3: gulpfile.js

Finally, we have the gulpfile.js file. This is where all our build tasks are defined. Also, fill in your username in both the <your username>/node-gulp sections.

Looking through the file, first the clone task downloads our image source code from GitHub. The pull task executes a git pull on the cloned repository. Next, the docker-build command builds an image from the container-info subfolder and pushes it to DockerHub. Finally, we have the create-kube-pod and update-kube-pod command. As you can guess, create-kube-pod creates our controller and service for the first time, whereas update-kube-pod simply replaces the controller.

Let's go ahead and run these commands and see our end-to-end workflow:

$ gulp clone
$ gulp docker-build

The first time through you can run the create-kube-pod command as follows:

$ gulp create-kube-pod

That's all there is to it. If we run a quick kubectl describe command for the node-gulp service, we can get the external IP for our new service. Browse to that IP and you'll see the familiar container-info application running. Note that the host starts with node-gulp just as we named it in the pod definition previously, as shown in the following figure:

Getting Started with Kubernetes

Figure 5.1. Service launched by Gulp build

On subsequent updates, run pull and update-kube-pod as follows:

$ gulp pull
$ gulp docker-build
$ gulp update-kube-pod

This is a very simple example, but you can begin to see how easy it is to coordinate your build and deployment end to end with a few simple lines of code. Next, we will look at using Kubernetes to actually run builds using Jenkins.

More plugins

If you are interested in more of the capabilities of Gulp.js, you can find documentation and additional plugins here:

Summary

In this article we had a brief walk-through of deploying Gulp.js task on Kubernetes. There are a variety of plugins available on the Gulp.js site to expand beyond these simple use cases. Gulp.js can be a very useful tool in your CI/CD pipeline.

Resources for Article:

 


Further resources on this subject:


You've been reading an excerpt of:

Getting Started with Kubernetes

Explore Title
comments powered by Disqus