Kubernetes Tutorial: Attaching A Volume Mount To Your Application

- By Ambarish Chitnis on November 01, 2017

Kubernetes allows you to package multiple containers into a pod. All containers in the pod run on the same Nodeshare the IP address and port space, and can find each other via localhost. To share data between pods, Kubernetes has an abstraction called Volumes. In this blog, we demonstrate how you can  easily hookup Kubernetes Volumnes to your pod and define the containers in the pod using Shippable.

 

Kuberetes Volumes

A Volume is a directory with data that is accessible to all containers running in a pod and gets mounted into each containers filesystem. Its lifetime is identical to the lifetime of the pod. Decoupling the volume lifetime from the container lifetime allows the volume to persist across container crashes and restarts. Volumes further can be backed by host's filesystem, by persistent block storage volumes such as AWS EBS or a distributed file system. The complete list of the different types of volumes that Kubernetes supports can be found here.

Shippable supports mounting all the types of volumes that Kubernetes supports via the dockerOptions resource. However, the specific volume type that we demonstrate in this blog is a gitRepo volume. A gitRepo volume mounts a directory into each containers filesystem and clones a git repository into it. 

 

Scenario

Our scenario is a single container Node.js application to which we want to attach a gitRepo volume and deploy to a Kubernetes cluster. In the gitRepo volume, we will clone the devops-recipes/volume-mount-kubernetes gitHub repository. After the application the deployed, we will serve HTML content from an API exposed by the application to validate the gitRepo volume.

We will build the scenario using the following steps using Shippable -

  • Define the containers in the pod
  • Define the gitRepo volume and the directory to which to mount into the container filesystem
  • Create a load balancer for the application
  • Deploy the pod 
  • Test the gitRepo volume mount using an exposed route in the Node.js application

 

Deployment Workflow

This is a pictorial representation of the workflow we're going to configure. The green boxes are jobs and the grey boxes are the input resources for the jobs. The workflow is defined across two configuration files: shippable.jobs.yml and shippable.resources.yml.

 

vm-pipeline.png

 

Resources (grey boxes)

  • vmk_app_img is a required image resource that represents the docker image of your application.
  • vmk_opts is an required dockerOptions resource where we define the gitRepo volume configuration.
  • vmk_kube_cluster is a required cluster resource that represents the Kubernetes cluster.
  • vmk_lb is an optional loadBalancer resource that defines the loadbalancer properties such as labels, port, cluster etc.

Jobs (green boxes)

  • vmk-app-def is a required manifest job that defines all the containers than run in the pod. This definition is versioned and each version is immutable.
  • vmk-app-deploy is a required deploy job which builds the Deployment spec for our application and deploys it to the Kubernetes cluster.
  • vmk-provision-lb is a optional provision job used to create the load balancer for the Kubernetes cluster.

 

Prerequisites

  • An existing Kubernetes cluster where you will deploy this sample application.
  • Any Supported Docker registry with a repository for your application. We have used Docker Hub as the Docker registry in this sample.
  • A GitHub account where you will fork and run this sample.
  • Sign in with GitHub to create a Shippable account

If you're not familiar with Shippable, it is also recommended that you read the Platform overview doc to understand the overall structure of Shippable's DevOps Assembly Lines platform.

 

Sample project

The code for this example is in GitHub at devops-recipes/volume-mount-kubernetes. You can fork the repository to try out this sample yourself or just follow instructions to configure your own use case.

  • The Node.js application source code and Dockerfile can be found here in the repository.
  • This repository also has the Shippable configuration files to create the workflow. 

 

1. Define the containers in a pod 

A. Create an account integration using your Shippable account for your Docker registry.

 Instructions to create an integration can be found here. Copy the friendly name of the integration, which we have set as drship_dockerhub.

 

B. Define vmk_app_img

vmk_app_img is an image resource that represents the docker image of your application. In our example, we're using an image hosted on Docker Hub.

Add the following yml block to your shippable.resources.yml file.

resources:

- name: vmk_app_img type: image # replace drship_dockerhub with your docker registry integration name integration: drship_dockerhub pointer: # replace devopsrecipes/basic_node with your organization/repository sourceName: "devopsrecipes/vmk_node_sample_app" seed:
# replace master.1 with the image tag of your application versionName: "latest"

 

C. Define vmk-app-def

vmk-app-def is a manifest job that defines all the containers than run in the pod. This definition is versioned and each version is immutable.

Add the following yml block to your shippable.jobs.yml file.

jobs:

  - name: vmk-app-def
    type: manifest
    steps:
      - IN: vmk_app_img
      - TASK: managed

 

D. Commit config files and add them to your Shippable account.

Once you have these configuration files as described above, commit them to your repository. The shippable.jobs.yml and shippable.resources.yml can be committed to the same app repository, or to a separate repository.

The repository containing your jobs and resources ymls is called a Sync repository and basically represents your workflow configuration.

Follow these instructions to import your configuration files into your Shippable account.

 

2. Define the gitRepo volume

vmk_opts is a dockerOptions resource where we define the gitRepo volume configuration. This resource can also be used to define other volume types.

Add the following yml block to your shippable.resources.yml file.

resources:

  - name: vmk_opts
    type: dockerOptions
    version:
      volumeMounts:
        - name: git-volume
          mountPath: /data/appdata/
      pod:
        volumes:
          - name: git-volume
            gitRepo:
              # replace devops-recipes/volume-mount-kubernetes.git with your git repository url
              repository: "https://github.com/devops-recipes/volume-mount-kubernetes.git"

 

3. Create a load balancer for the application

This is an optional step and the configuration required to create the load balancer can be found in this document. The sample application also has the load balancer configuration.

 

4. Deploy the pod 

A. Create an account integration for Kubernetes in your Shippable UI.

Instructions to create an integration are here:

Copy the friendly name of the integration. We have set it to drship_kube and use in the next step.

B. Define vmk_kube_cluster

vmk_kube_cluster is a cluster resource that represents the Kubernetes cluster.

Add the following yml block to your shippable.resources.yml file.

jobs:

  - name: vmk_kube_cluster
    type: cluster
    #replace with your Kubernetes integration name
    integration: drship_kube
    pointer:
      # replace devops-test-cluster with your cluster name
      sourceName: "devops-test-cluster"
      # replace us-central1-a with your availability zone if using google container engine
      region: us-central1-a


C. Create deployment job
vmk-app-deploy is a deploy job which builds the Deployment spec for our application and deploys it to the Kubernetes cluster.

Add the following yml block to your shippable.jobs.yml file.

jobs:

  - name: vmk-app-deploy
    type: deploy
    method: replace
    steps:
      - IN: vmk_opts
      - IN: vmk-app-def
      - IN: vmk_kube_cluster

 

D. Commit the shippable.resources.yml and shippable.jobs.yml file to your repository. 

Your pipeline should now look like this in the SPOG view.

vm-kubernetes-pipeline.png

5. Trigger your pipeline

Right click on vmk-app-def in the SPOG and click on Build Job. This will trigger the entire pipeline.

buildjob.png

If you have created the load balancer configuration , you will first need to right click on your load balance job vmk_provision_lb and click Build Job to create the load balancer.

 

6. Testing the gitRepo volume

Here are some screenshots of the load balancer deployed in Google Container Engine and the content being served from the mounted gitRepo by the Node.js gitrepo route.

lb-gke.png 

 

route.png

 

Screenshot of deploy job run in Shippable account

lb.pngdeploy.png

 

Screenshot of load balancer job run in Shippable account

 

Topics: Docker, continuous integration (CI), Kubernetes, Google Cloud Platform, Docker Hub