Security Global Forum

Security Global Forum

Our mission is to provide clients with an online user community of industry peers and IBM experts, to exchange tips and tricks, best practices, and product knowledge. We hope the information you find here helps you maximize the value of your IBM Security solutions.

 View Only

My first Docker and IBM Containers Experience

By Shane Weeden posted Mon July 18, 2016 12:00 AM

  

Like most technical experimenters, from time to time I want a simple lightweight internet-facing linux box to test things from. There are lots of ways to get one of these, but in this case I also wanted to experiment with Docker, and IBM Containers on Bluemix, so decided to combine the goals into a self-education exercise. This article describes my experience.

Installing Docker

Operating on a Mac, I didn’t have the ability to really run the Docker engine natively (there are beta steps for this but I chose not to go down that route), so I decided to create a guest VM on which to begin my journey. For this I chose a recent Ubuntu Server installation, but any Docker-capable OS should do. This Ubuntu server initially became my Docker Host, and later is also where I installed both the Bluemix cf client, and the IBM Containers extension to this client.

From my Ubuntu host, I installed Docker engine, following standard instructions from here:
https://docs.docker.com/engine/installation/linux/ubuntulinux/

Instructions were very straight forward, and instructions for other host operating systems were present. I won’t replicate all those instructions here, but suffice to say at the end I was able to verify my installation with:

$ 

sudo docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c04b14da8d14: Pull complete 
Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
<plus more stuff I've removed for brevity>

 

To clean up, I listed all containers and images, then deleted them:

$ 

sudo docker ps –a

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f7d4d7c8cbe2 hello-world "/hello" 4 minutes ago Exited (0) 4 minutes ago goofy_ritchie
$ 

sudo docker images

REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest c54a2cc56cbb 2 weeks ago 1.848 kB
$ 

sudo docker rm f7d4d7c8cbe2

f7d4d7c8cbe2
$ 

sudo docker rmi c54a2cc56cbb

Untagged: hello-world:latest
Deleted: sha256:c54a2cc56cbb2f04003c1cd4507e118af7c0d340fe7e2720f70976c4b75237dc
Deleted: sha256:a02596fdd012f22b03af6ad7d11fa590c57507558357b079c3e8cebceb4262d7

Creating the Dockerfile for Ubuntu with sshd

Now I decided I wanted to create a docker container for Ubuntu with sshd, pre-configured for key authentication, and with a couple of common network utilities installed (ping, nslookup, curl, socat).

After some research, I started with this sshd example:
https://docs.docker.com/engine/examples/running_ssh_service/

I modified it for key authentication and installation of my utilities, ending up with this Dockerfile:

# sshd
#
# Started with the example from: https://docs.docker.com/engine/examples/running_ssh_service/
# Modified to build from latest ubuntu and include key authentication and installation of ping, dns utils, curl and socat
FROM ubuntu:latest
RUN apt-get update && apt-get install -y openssh-server
RUN apt-get install -y inetutils-ping
RUN apt-get install -y dnsutils
RUN apt-get install -y curl
RUN apt-get install -y socat
RUN mkdir /var/run/sshd
# For ssh key configuration use this
RUN mkdir /root/.ssh
ADD authorized_keys /root/.ssh
RUN chmod 600 /root/.ssh/authorized_keys
RUN echo "PasswordAuthentication no" >> /etc/ssh/sshd_config
# For password authentication, do these two. For now I'm leaving them commented out
#RUN echo 'root:SOME_STRONG_PASSWORD' | chpasswd
#RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config
# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

Building the Docker image

First I made sure my ssh public key file (authorized_keys) was in the local directory, along with the Dockerfile:

$ 

ls

authorized_keys Dockerfile

Then I built the docker image:

$ 

sudo docker build -t ubuntu_sshd .

...lots of trace output happens ...
Successfully built ecedb4aabd3a

At this point I can see the image in my list, along with the base ubuntu image:

$ 

sudo docker images

REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu_sshd latest ecedb4aabd3a About a minute ago 227.7 MB
ubuntu latest cf62323fa025 9 days ago 125 MB

Testing the Docker image locally

As per the instructions in the example, I can now run a container locally to try out the Ubuntu sshd image:

$ 

sudo docker run -d -P --name test_sshd ubuntu_sshd

2ea9bfbd2a6e146a245c0ca230b929374a64b5325663ed4f8e3855256865595c

I can find the local port the image is bound to, then ssh into that image (provided my ssh private key is correctly set up in ~/.ssh/id_rsa):

$ 

sudo docker port test_sshd 22

0.0.0.0: 32768
$ 

ssh root@localhost -p 32768

The authenticity of host '[localhost]:32768 ([::1]:32768)' can't be established.
ECDSA key fingerprint is 36:db:38:53:c3:af:69:97:1c:fd:79:8e:e3:9a:20:b8.
Are you sure you want to continue connecting (yes/no)? 

yes

Warning: Permanently added '[localhost]:32768' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 16.04 LTS (GNU/Linux 3.19.0-25-generic x86_64)
* Documentation: https://help.ubuntu.com
 * Management: https://landscape.canonical.com
 * Support: https://ubuntu.com/advantage
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
root@2ea9bfbd2a6e:~#

After exiting out of the ssh session, I can stop and clean up the container with:

$ 

sudo docker stop test_sshd

$ 

sudo docker rm test_sshd

Note that I while I have deleted the container, I have kept the image around, since we are now going to deploy that to IBM Bluemix.

Preparing to deploy the image to IBM Bluemix

Reference material: https://console.ng.bluemix.net/docs/containers/container_index.html

The reference documentation (which may easily have been change after I wrote this article) takes you on a step-by-step example of configuring your Bluemix account for containers.

What I’m going to show here is how I deployed my locally-created Docker image as a container on Bluemix, using the command-line interfaces.

First I had to install the CloudFoundry CLI, and the ibm-containers CLI plugin.

I obtained the CloudFoundry CLI plugin from github here:
https://github.com/cloudfoundry/cli/releases
I chose to download the Linux 64-bit binaries, scp them to my Ubuntu Docker host, and unzip it to ~/bin, which is in my PATH. I then had re-logged-in and had cf available on the command line.

The ibm-containers cli plugin was obtained per the instructions with:

$ 

cf install-plugin https://static-ice.ng.bluemix.net/ibm-containers-linux_x64

**Attention: Plugins are binaries written by potentially untrusted authors. Install and use plugins at your own risk.**
Do you want to install the plugin https://static-ice.ng.bluemix.net/ibm-containers-linux_x64? (y or n)> 

y

Attempting to download binary file from internet address...
12425856 bytes downloaded...
Installing plugin ibm-containers-linux_x64...
OK
Plugin IBM-Containers v0.8.897 successfully installed.

At this point I now have all the tools I need to deploy my Docker image as a container on Bluemix.

Login to Bluemix and establish Container Namespace

Again I’m following instructions provided at:
https://console.ng.bluemix.net/docs/containers/container_cli_cfic.html
These will vary slightly based on your own org/space and region.

Obtain an sso key from your browser at: https://login.ng.bluemix.net/UAALoginServerWAR/passcode

Then on the command line:
$ 

cf login -a https://api.ng.bluemix.net -sso

API endpoint: https://api.ng.bluemix.net
One Time Code (Get one at https://login.ng.bluemix.net/UAALoginServerWAR/passcode)> 

PASSCODE_HERE

Then pick the organization and space you wish to operate on. I am choosing not to show my list in this article.

ONE-TIME – create a namespace for containers in your org. In this example I will use the namespace “ibmsecuritydemos” in this article, however you should alter this for your own namespace:

$ 

cf ic namespace set ibmsecuritydemos

Allow Docker commands to run against Bluemix Registry

Again I’m following instructions provided at:
https://console.ng.bluemix.net/docs/containers/container_cli_cfic.html

To allow docker commands to run against the Bluemix registry:

$ cf ic login

There will be a lot of trace output, including information on how you can set the DOCKER_HOST, DOCKER_CERT_PATH and DOCKER_TLS_VERIFY environment variables so that you don’t have to perform the cf ic login command again. I suggest you put these variables in your .profile.

Tag Image, Obtain Public IP and Deploy to Bluemix

Tag the ubuntu_sshd image for the Bluemix registry, using your private namespace from Bluemix (instead of “ibmsecuritydemos”):

$ 

sudo docker tag ubuntu_sshd registry.ng.bluemix.net/ibmsecuritydemos/ubuntu_sshd:latest

You can view the tagged image with:

$ 

sudo docker images

Push the image to the Bluemix registry:

$ 

sudo docker push registry.ng.bluemix.net/ibmsecuritydemos/ubuntu_sshd:latest

This command will take a little while to run as the image contents are uploaded to Bluemix.

You can verify that the image is there with :

$ 

cf ic images

We will now get a public IP address to use on Bluemix with our image:

Reference: https://console.ng.bluemix.net/docs/containers/container_cli_ips.html
First check if you have any public IP addresses assigned. The first time this should be empty:

$ 

cf ic ip list

Request a public IP:

$ 

cf ic ip request

You should get back an IP, in a message similar to:
The IP address “192.168.42.100” was obtained.

Note that the example IP above is not a real public IP, but will be used for reference in this article.
We can bind the IP at the same time we run the image as a new container, with the following command (remember to change the ip address and container namespace to your own):

$ 

cf ic run -p 192.168.42.100:22:22 --name bm_ubuntu registry.ng.bluemix.net/ibmsecuritydemos/ubuntu_sshd:latest

Check the image is running with:

$ 

cf ic ps -a

You should be able to see the port mapping assigned in the output.
You now have a running container, and can ssh to it as we did before on the local docker host, this time with the public IP on Bluemix:

$ 

ssh root@192.168.42.100

I found that I had to wait some time (a few minutes at least) before the public IP worked. Also, at the time of writing, by default IBM Containers only allow ports 22, 80, 443, and 9443 through a public IP address.

Summary

I hope you find this article of practical use. It was my first pass at using Docker, and IBM Containers on Bluemix. I have no doubt there are a lot of things I could have done differently, or better, however at least you can see how to get started using your own containers on Bluemix, and for me it means I have a simple Linux test host that I can use to execute basic tests from without having to host another public facing machine or VM.

0 comments
4 views

Permalink