Kubernetes – 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 through to the final Kubernetes service.

Prerequisites

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

You can check whether or not Node.js is installed correctly by using the node -v command.

You’ll also need Docker CE and a Docker Hub account to push a new image. You can find instructions to install Docker CE 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 $ docker login command.

gulp.js build example

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

$ mkdir node-gulp
$ cd node-gulp

Next, we will install the gulp package and then check whether it’s ready by running the npm 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 with the following command:

 $ gulp -v

Next, we will install gulp locally in our project folder, along with 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 a gulpfile.js file, to run all of our tasks. Again, these files are available in the book file bundle, should you wish to copy them straight over instead. Refer to the following node-gulp-controller.yaml file:

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 

As you can see in the preceding code, we have a basic controller. You will need to replace <your username>/node-gulp:latest with your Docker Hub username. Save the following code as node-gulp-service.yaml file:

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 

Next, we have a simple service that selects the pods from our controller and creates an external load balancer for access, as earlier:

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-se.git', function (err) { 
    if (err) throw err; 
  }); 

}); 

// Update codebase 
gulp.task('pull', function(){ 
  return git.pull('origin', 'master', {cwd: './getting-started-with-kubernetes-se'}, 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-se/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' 
])); 

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

Looking through the file, first, we can see that the clone task downloads our image source code from GitHub. The pull tasks execute a git pull on the cloned repository. Next, the docker-build command builds an image from the container-info sub folder and pushes it to Docker Hub. Finally, we have the create-kube-pod and update-kube-pod commands. As you can probably guess, the create-kube-pod command creates our controller and service for the first time, whereas the update-kube-pod command 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 also run the create-kube-pod command, as follows:

$ gulp create-kube-pod

This is 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 previously mentioned pod definition:

On subsequent updates, run the pull and update-kube-pod commands, as shown here:

$ 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 how to use Kubernetes to actually run builds using Jenkins.

Comments are closed.