Avoid Docker in Docker in Windows 10

Originally published by Thomas Suedbroecker at https://dzone.com

We defined a Dockerfile to create a Docker image for our Cloud-Native-Starter workshop especially for Windows 10 users. The users can now simply create a Docker image on the local Windows 10 machine and then follow the guided steps in the hands-on workshop documentation and use the bash scripts.

These are some challenges we had during the testing of the Dockerfile definition:

  • File sharing for Docker images on Windows
  • Docker port forwarding
  • Docker in Docker
  • Istio Virtual service configuration
  • Linux tools missing

Why Should We Use a Docker Image?

We wrote a lot of bash scripts to simplify the setup and steps inside the hands-on workshop. These bash scripts can’t be executed on a Windows console or in a Windows Powershell.

It is possible to install other environments like Cygwin on Windows to use bash scripts, but we notice with those solutions, other problems do appear, related to development tools installations.

We know that it is possible to install bash on Ubuntu on Windows 10, but we want to avoid such additional effort in a hands-on workshop for participants, who will maybe come unprepared to the workshop.

The Dockerfile Solution Decision

We decided to use a Docker image on Windows and define our own Dockerfile using Ubuntu as a starting point. The reason that we don’t build a Docker image and share it on Dockerhub is because we want to provide users the freedom of their own customization we can add the file with no effort to our GitHub project, and the users will always build an actual Docker image with the newest tools.

Use of The Docker Image

With the Docker command:

docker run -ti my-workshop-image:v1

we can start the Docker image in the interactive mode in a terminal session on our Windows 10 machine.

In the image below we see the start of the Docker image and the verification of the installed prerequisites of the workshop on the Docker image.

Docker image initialization

It seems that’s the best solution for our Windows 10 users to setup their machines in our workshop. They only need is to install Docker on Windows 10, which is effortless.

Installation of The Developer and Linux Tools

We need to install developer tools on our Docker image, as documented in our workshop, and some missing or useful Linux tools.

These are the developer tools we need to install into the Docker image:

  • Git
  • CURL
  • Docker (CLI online)
  • IBM Cloud CLI and two specific packages
  • kubectl from Kubernetes

In the Dockerfile definition, we see Ubuntu is our starting point for the Docker image and the needed/useful Linux tools:

FROM ubuntu
RUN apt-get update
RUN apt-get --assume-yes install curl
RUN apt-get --assume-yes install git-core
RUN apt-get --assume-yes install wget
# editor
RUN apt-get --assume-yes install nano
# setup network tools
RUN apt-get --assume-yes install apt-utils
RUN apt-get --assume-yes install net-tools
# zip
RUN apt-get --assume-yes install unzip
RUN apt-get --assume-yes install zip

File Sharing for Docker Images on Windows

It is challenging to share the local host filesystem on a Windows machine with a Docker image, because of the Windows Azure authorization. We search in the internet to get an easy solution, but the search ends with no easy solution. Here we see a long discussion in the Docker community about that topic.

With this in mind we decide just to clone our git repository into the Docker image, because that is the simplest way for our situation. Here we see how we clone our project.

# Cloud-Native-Starter -project 
# https://github.com/IBM/cloud-native-starter/blob/master/workshop/00-prerequisites.md                
# Install RUN mkdir usr/cns 
WORKDIR /usr/cns RUN 
git clone https://github.com/IBM/cloud-native-starter.git 
WORKDIR /usr/cns/cloud-native-starter

Docker in Docker

With the usage of the IBM Cloud Kubernetes service and the IBM Cloud Container Registry we don’t need to run the Docker daemon inside our Docker image. So we can move on with the Dockerfile solution for the workshop. Inside our bash scripts, we log on to IBM Cloud and we use the command ibmcloud cr build. Here we see the build command:

ibmcloud cr build -f Dockerfile --tag $REGISTRY/$REGISTRY_NAMESPACE/authors:1 .

In the following image, we see the difference between the usage of the IBM Cloud CLI and the Docker CLI.

Docker CLI

With Docker CLI we can’t build the Docker image and with the IBM Cloud CLI we can build a container image.

The reason why we can build the container image is because we are logged on to the IBM Cloud and we use the IBM Cloud CLI to upload the build context to the IBM Cloud Container Registry and we build the image inside the IBM Cloud Container Registry. With that situation, we are able to avoid Docker in Docker usage, but we need the Docker CLI to be installed. The image below shows a simplified view of how it works in our situation on Windows 10.

Windows container upload

Port Forwarding

The last remaining problem is how to do a port forwarding with Docker on Windows that uses Hyper-V?

Normally we do a local port forwarding on a PC from our IBM Cloud Kubernetes cluster to access the Kiali with a local browser. That is the command:

kubectl -n istio-system port-forward $(kubectl  -n istio-system get pod -l app=kiali -o jsonpath='{.items[0].metadata.-n istio-system get pod -l app=kiali -o jsonpath='{.items[0].metadata.name}') 20001:20001

But when we use this local port-forwarding inside the Docker image we can’t access the Kiali UI.

The reason is that we don’t have a browser inside our Docker image and even if we would install one, we can’t use command line and an open browser in our Docker image at the same time. Remember we are in an interactive terminal mode.

We must expose the port 20001 to our Docker image, to access Kiali in a browser on a local machine. That is the command, we use to start the Docker image and expose the port 20001.

docker run -ti -p 20001:20001 my-workshop-image:v1

But we notice that we are not able to access Kiali in a browser on the local Windows system. The reason for this is that Hyper-V runs our Docker Linux and we only have exposed the port to that Linux in the Hyper-V. If we want to access the port from the Windows host system, we need to expose the same port 20001 in Hyper-V. That’s too complex a configuration for our workshop and we decide to use Virtual Service configuration with Istio on our Kubernetes cluster in IBM Cloud.

The image below shows a simplified view of our needed port forwarding/exposing.

Docker portforwarding

Configuration of The Virtual Service for Istio

To solve the port forwarding challenge, we decide to configure the Istio Virtual Service. We map the Kiali port directly in the Istio Virtual Service and with that configuration it is possible to access Kiali from our Kubernetes Cluster directly.

Therefore we define a match for Kiali using: URI, port, and host information, as we see in the following YAML configuration.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: virtualservice-ingress-web-api-web-app
spec:
  hosts:
  - "*"
  gateways:
  - default-gateway-ingress-http
  http:
  - match:
    - uri:
        prefix: /kiali
    route:
    - destination:
        port:
          number: 20001
        host: kiali.istio-system.svc.cluster.local

With that configuration we access easily the Kiali UI directly on our free Kubernetes Cluster on IBM Cloud.

Kiali access

I hope this was useful for you and let’s see what’s next.

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow me on Facebook | Twitter

Further reading

Docker and Kubernetes: The Complete Guide

Docker Mastery: The Complete Toolset From a Docker Captain

Docker for the Absolute Beginner - Hands On - DevOps

Docker for Absolute Beginners

How to debug Node.js in a Docker container?

Docker Containers for Beginners

Deploy Docker Containers With AWS CodePipeline

Build Docker Images and Host a Docker Image Repository with GitLab

How to create a full stack React/Express/MongoDB app using Docker

#docker #kubernetes #devops

Avoid Docker in Docker in Windows 10
9.10 GEEK