Checking for vulnerabilities in Docker container images

It’s very likely that you are using a Docker container image for cloud native application. In which case, you’re probably also worry for possible security vulnerabilities in your base image.

As part of my daily work (I work for IBM), I use the IBM Bluemix Container Registry service. This service offers a Vulnerability Advisor which can let you know if there are any identified vulnerabilities in the image and also offer a detailed report. Nice.

I decided to create a Jenkins job that will check daily for such issues.
Here it is.

Note: since this is part of an IBM Bluemix service, use of the Bluemix CLI and Container Registry plug-in is required.

#!groovy

pipeline {
    stages {
        stage ("Check for vulnerability") {
            environment {
                JENKINSBOT = credentials('${JENKINSBOT_USERNAME_PASSWORD}')
            }
            steps {
                script {
                    // Login to Bluemix and the Bluemix Container Registry      
                    sh '''      
                        bx login -a ... -c ... -u $JENKINSBOT_USR -p $JENKINSBOT_PSW        
                        bx target -r ...    
                        bx cr login
                    '''

                    // Check for image vulnerability
                    isVulnerable = sh(script: "bx cr images --format '{{if and (eq .Repository \"registry.ng.bluemix.net/certmgmt_dev/node\") (eq .Tag \"6-alpine\")}}{{eq .Vulnerable \"Vulnerable\"}}{{end}}'", returnStatus: true)

                    if (isVulnerable == 1) {
                        slackSend (
                            channel: "...",
                            color: "#F01717",
                            message: "@iadar *Vulnberability Checker*: base image vulnerability detected! Run the following for a detailed report: ```bx cr va registry-name/my-namespace/node:6-alpine```"
                        )
                    }
                }
            }
        }
   }
}

Deploying to a Kubernetes cluster

As you may know, Kubernetes is all the rage these days. Kubernetes. Its feature list is impressive and it is no wonder why it is the go-to system of orchestrating your containers.

Kubernetes is an open-source system for automating deployment, scaling, and management of containerized applications.

I wanted to share my pipeline for building and updating containers in a Kubernetes cluster. In fact it’s quite straightforward. The pipeline includes: building a Docker container image, pushing the image to a container registry and updating the container image used in a Pod.

My environment is based in IBM Bluemix, so some commands will not apply…

stage ("Publish to Kubernetes cluster") {
   environment {
      JENKINSBOT = credentials('credentials-ID')
   }

   when {
      branch "develop"
   }

   steps {
      script {
         STAGE_NAME = "Publish to Kubernetes cluster"

         // Login to Bluemix and the Bluemix Container Registry
         sh '''
            bx login ...
            bx cr login
         '''

         // Build the Docker container image and push to Bluemix Container Registry
         sh '''
            docker build -t registry.../myimage:0.0.$BUILD_NUMBER --build-arg NPM_TOKEN=${NPM_TOKEN} .
            docker push registry.../myimage:0.0.$BUILD_NUMBER
         '''

         // Check for image vulnerabilities - applies only if you have such a service...
         isVulnerable = sh(script: "bx cr images --format '{{if and (eq .Repository \"registry.../myimage\") (eq .Tag \"0.0.$BUILD_NUMBER\")}}{{eq .Vulnerable \"Vulnerable\"}}{{end}}'", returnStatus: true)

         if (isVulnerable=="true") {
            error "Image may be vulnerable! failing the job."
         }

         // Apply Kubernetes configuration and update the pods in the cluster
         sh '''
            export KUBECONFIG=/home/idanadar/.bluemix/plugins/container-service/clusters/certmgmt/kube-config.yml
            kubectl set image deployment myimage myimage=registry.../myimage:0.0.$BUILD_NUMBER --record
         '''

         // If reached here, it means success. Notify
         slackSend (
            color: '#199515',
            message: "$JOB_NAME: <$BUILD_URL|Build #$BUILD_NUMBER> Kubernetes pod update passed successfully."
         )
      }
   }
}

Notes:
* I use $BUILD_NUMBER as the means to tag the image.
* I use a pre-defined export... to configure the session with the required configuration for the kubectl CLI to know which cluster to work with.
* The Bluemix Container Registry provides image scanning for vulnerabilities!
* I use kubectl set image ... to update the image used in the Pod(s). Works great with the replica setting.

More on Kubernetes in a later blog post.