IBM/buildingimages

Name: buildingimages

Owner: International Business Machines

Description: content creation around image building for containers

Created: 2018-05-16 18:10:08.0

Updated: 2018-05-22 11:55:14.0

Pushed: 2018-05-22 15:59:52.0

Homepage: null

Size: 15

Language: Shell

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

Building Container Images in IBM Cloud

content creation around image building for containers

Prerequisites

Before you get started you'll need an IBM Cloud account and need to install the IBM Cloud Development Tools.

You should also clone the guestbook repository as all image builds will be based on that.

Once those are installed, you'll be able to complete the commands below.

Basics of Image Building

Kubernetes uses standard container images to deploy applications.

From the application's perspective, a container image is a single filesystem that is created before the application is started.

From a creation perspective, container images are layers. These layers are built up using a Docker file. Lets look at the example guestbook application Docker file and pull it apart.

 golang as builder
go get github.com/codegangsta/negroni
go get github.com/gorilla/mux github.com/xyproto/simpleredis
 main.go .
go build main.go

 busybox:ubuntu-14.04

 --from=builder /go//main /app/guestbook

public/index.html /app/public/index.html
public/script.js /app/public/script.js
public/style.css /app/public/style.css

DIR /app
["./guestbook"]
SE 3000

Docker files specific a set of commands, at each command we build a new layer.

FROM - pulls a layer from a remote repository. The default repository is the docker image registry. This could be a complete OS image, or some partial image that used to do something small. In this example we pull in 2 different base images. One is a named layer for the golang build environment, so that it can be referenced later. The second one is the base image with just enough operating system to provide debug facilities inside the image.

RUN - executes a command, all output files go into the layer. There are a few go get commands that pull in libraries for the main application. Later the main.go is compiled using this.

COPY - copy a file from the local filesystem into the container. This can work on a set of files.

WORKDIR - set the working directory for the entrypoint

CMD - what command should be run in this container if no exec is passed into it. CMD means that the command run is replaceable. There is another stanza ENTRYPOINT which is not replaceable.

EXPOSE - open up a specific port from this container to the infrastructure. Without this no network traffic will be allowed into the container.

These commands, plus many more are documented on the Docker reference site.

Best Practices for Building Images

There are a number of best practices when building images.

Clean up everything you can

Whatever files are created in a layer are stored in the intermediate layer. Sometimes what gets added in each layer ends up as a surprise. For instance, when install Linux packages with apt, not only is the software installed, but copies of the packages are stored in /var/cache/apt/archives. This can add significant bloat to your images, which slows down image upload/download times and thus container start times.

When using standard install tools, be sure to include clean up commands as part of the run command. For instance:

apt-get update && apt-get install -y python3 python3-pip && apt-get clean

Which updates the repos, installs packages, and deletes downloaded archive files.

Publishing to IBM Cloud

You can build images with docker and publish them publicly to docker hub. However, if you are going to be using these images inside of IBM cloud it's best practice to publish them into the IBM Cloud Container Registry. This makes the images much more network local to where they run, and makes them private to your IBM Cloud account.

Creating your registry

Before you can upload images to the IBM Cloud you must first create a registry namespace. Namespaces are just used to help you organize your account. You can have many namespaces in your account, creating one per project is a useful way of staying organized.

 cr namespace-add guestbook

This will create a registry url of registry.ng.bluemix.net/guestbook that you can use for uploading images.

Building using bx client

The bx client can be used to build images using the local docker system. When building with the bx client all the authentication to the IBM Cloud Container Registry is handled behind the scenes.

We will want to provide a meaningful name for the image, as well as some kind of version.

 cr build --tag registry.ng.bluemix.net/guestbook/gbv1:2018-05-18-1 guestbook
ing build context to Docker daemon  16.38kB
 1/13 : FROM golang as builder
> 6b369f7eed80
 2/13 : RUN go get github.com/codegangsta/negroni
> Using cache
> 6235665371cf
 3/13 : RUN go get github.com/gorilla/mux github.com/xyproto/simpleredis
> Using cache
> c7b784b25fd7
 4/13 : COPY main.go .
> 22bb5236a85b
 5/13 : RUN go build main.go
> Running in 7809ad57b6b4
> 7b70b540d7d4
ving intermediate container 7809ad57b6b4
 6/13 : FROM busybox:ubuntu-14.04
> d16744963217
 7/13 : COPY --from=builder /go//main /app/guestbook
> 8b7eb0124777
 8/13 : ADD public/index.html /app/public/index.html
> 9d763716676c
 9/13 : ADD public/script.js /app/public/script.js
> 353bca474993
 10/13 : ADD public/style.css /app/public/style.css
> 81819bed4684
 11/13 : WORKDIR /app
> 1a99524a116a
ving intermediate container 020c16388591
 12/13 : CMD ./guestbook
> Running in bdb88f981da7
> fc76ec26b945
ving intermediate container bdb88f981da7
 13/13 : EXPOSE 3000
> Running in b04f65bdedad
> b63df6f0716e
ving intermediate container b04f65bdedad
essfully built b63df6f0716e
essfully tagged registry.ng.bluemix.net/guestbook/gbv1:2018-05-18-1
push refers to a repository [registry.ng.bluemix.net/guestbook/gbv1]
baa1be3c: Pushed
58449645: Pushed
3cd4e753: Pushed
bbfcbb1d: Pushed
bf18a086: Layer already exists
f0efe4f2: Layer already exists
igest: sha256:cca8cdb32ed616ae13087a9b557696896505bb36241c0f24588987094a687000 size: 1772


This builds and pushes all the relevant layers.

The --tag field gives the image a name and version, separated by the :. When using the IBM Cloud Container Registry the name is going to include the full URL to that image.

The version portion can be anything that's meaningful to you. The important thing is that tags do not get reused. If you rebuild an image, make sure to change the version before uploading. Many kubernetes primitives, such as deployments, will perform a graceful rolling upgrade when you specify a new image version. If image versions get reused it hampers the effectiveness of container orchestration systems.

Retrieving from IBM Cloud

IBM Cloud images are included in kubernetes configuration in the same way as images from docker hub. The only difference is the full url is needed as it's the non default image repository.

ersion: apps/v1
: Deployment
data:
me: guestbook
bels:
app: guestbook
:
plicas: 3
lector:
matchLabels:
  app: guestbook
mplate:
metadata:
  labels:
    app: guestbook
spec:
  containers:
  - name: guestbook
    image: registry.ng.bluemix.net/guestbook/gbv1:2018-05-18-1
    ports:
    - name: http-server
      containerPort: 3000

Vulnerability Advisor

An additional feature of using the IBM Container Service is IBM Vulnerabiliy Advisor. After the image is uploaded it is scanned by a set of tools that look for common security issues. These scans are also run regularly as new CVEs are issued.

In the case of the guestbook image it's an extremely small microservice that doesn't include a traditional OS base, so there is not much VA can do with it. If we look at a set of images that are based on an Ubuntu Linux base we can see it in action.

 cr images --restrict ny-power
ing images...

SITORY                                            NAMESPACE   TAG   DIGEST         CREATED        SIZE     VULNERABILITY STATUS
stry.ng.bluemix.net/ny-power/ny-power-api         ny-power    5     16041dfa9da4   1 month ago    203 MB   Vulnerable
stry.ng.bluemix.net/ny-power/ny-power-base        ny-power    7     56ef5e28ad5e   1 month ago    208 MB   Vulnerable
stry.ng.bluemix.net/ny-power/ny-power-ibm-cloud   ny-power    5     3e5fbcddf92c   1 month ago    107 MB   OK
stry.ng.bluemix.net/ny-power/ny-power-ibm-cloud   ny-power    6     e735f31e9e81   22 hours ago   107 MB   OK
stry.ng.bluemix.net/ny-power/ny-power-influxdb    ny-power    3     596642b949a6   1 month ago    84 MB    Vulnerable
stry.ng.bluemix.net/ny-power/ny-power-mqtt        ny-power    4     b94db277bbd5   1 month ago    88 MB    OK
stry.ng.bluemix.net/ny-power/ny-power-web         ny-power    10    e2b7fd0b3a44   1 month ago    203 MB   Vulnerable
stry.ng.bluemix.net/ny-power/ny-power-web         ny-power    11    dc56770012f8   1 month ago    203 MB   Vulnerable
stry.ng.bluemix.net/ny-power/ny-power-web         ny-power    12    25bee418debe   1 month ago    203 MB   Vulnerable
stry.ng.bluemix.net/ny-power/ny-power-web         ny-power    15    166225785d06   1 month ago    203 MB   Vulnerable
stry.ng.bluemix.net/ny-power/ny-power-web         ny-power    16    3b861213f07e   23 hours ago   203 MB   OK
stry.ng.bluemix.net/ny-power/ny-power-web         ny-power    7     419f2cf4738a   1 month ago    203 MB   Vulnerable
stry.ng.bluemix.net/ny-power/ny-power-web         ny-power    8     0481120a635d   1 month ago    203 MB   Vulnerable
stry.ng.bluemix.net/ny-power/ny-power-web         ny-power    9     81cdb370bd74   1 month ago    203 MB   Vulnerable

We can drill down into an image in question:

 cr va registry.ng.bluemix.net/ny-power/ny-power-base:7 --extended
king vulnerabilities for 'registry.ng.bluemix.net/ny-power/ny-power-base:7'...

e 'registry.ng.bluemix.net/ny-power/ny-power-base:7' was last scanned on Mon May 14 23:38:51 UTC 2018.
scan results show the image should be deployed with CAUTION.

ERABLE PACKAGES FOUND
=====================


orrective action: Upgrade to perl 5.22.1-9ubuntu0.3

IX SUMMARY                                OFFICIAL NOTICE                        CVE ID
everal security issues were fixed in      http://www.ubuntu.com/usn/usn-3625-1   CVE-2015-8853,CVE-2016-6185,CVE-2017-6512,CVE-2018-6797,CVE-2018-6798,CVE-2018-6913
erl.


IGURATION ISSUES FOUND
======================

RITY PRACTICE                                                     CORRECTIVE ACTION
_MAX_DAYS must be set to 90 days                                  Maximum password age must be set to 90 days.
mum password length not specified in /etc/pam.d/common-password   Minimum password length must be 8.
_MIN_DAYS must be set to 1                                        Minimum days that must elapse between user-initiated password changes should be 1.
 /var/log/faillog does not exist                                  Permission check of /var/log/faillog
 /var/log/faillog must exist if pam_tally2.so is not being used   faillog file checking


This scans inside the image and found that the standard perl package that was part of the base image has a security notice associated with it, as well as the CVEs that references. Rebuilding this image with updates applied would address this issue.

It also scans for potential configuration issues. The configuration issues listed here aren't really applicable to this image as there is no login services to the container.


This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.