Docker, Kubernetes

Docker for Mac with Kubernetes support

During DockerCon Copenhagen, Docker announced support and integration for Kubernetes, alongside Swarm. The first integration is in the Docker for Mac, where you can run now a 1 node Kubernetes cluster. This allows you to deploy apps with Docker-compose files to that local Kubernetes cluster via the docker cli. In this blogpost, I’ll cover what you need to know about this integration and how to make the most out of it.

Why we need local orchestration

While a lot of computing workload moves to the cloud, the local environment is still relevant. This is the first place where software is built, executed and where (unit) tests run. Docker, helped us to get rid of the famous “it works on my machine” by automating the repetitive and error-prone tasks. But unless you’re into building “hello world” apps, you’ll have to manage the lifecycle of a bunch of containers that need to work together. Thus, you’ll need management for your running containers, commonly called nowadays orchestration.

All major software orchestration platforms have their own “mini” distribution that can run on a developer machine. If you work with Mesos you have minimesos (container based), for Kubernetes there is minikube (virtual machine). RedHat offers both a virtual machine (minishift) and a container based tool (oc cli) for their K8s distribution (Openshift). Docker has compose, swarm-mode orchestration and since recently also supports Kubernetes (for now only in Docker for Mac).

If you’re new to Kubernetes you’ll wanna familiarize with the basic concepts using this official Kubernetes tutorial we build together with Google, Remembertoplay and Katacoda.

Installation

Enabling Kubernetes in Docker for Mac, will install a containerized distribution of Kubernetes and it's cli (kubectl), which will allow you to interact with the cluster. On resource level, the new cluster will use whatever Docker for Mac has available for use.

The release is in beta (at the time of writing the article) and available via the Docker Edge channel. Once you’re logged in with your Docker account, you can enable Kubernetes via the dedicated menu from the UI:

 

kubernetes docker mac

At this point, if you never connected to a Kubernetes cluster on your Mac, you're good to go. Kubectl will point to the new (and only) configured cluster. If this is not the case, you'll need to point kubectl to the right cluster. Docker for Mac will not change your default Kubernetes context. You’ll need to manually switch the context to  ‘docker-for-desktop’:

  
kubectl config get-contexts
(out) CURRENT NAME CLUSTER AUTHINFO NAMESPACE
(out) ...
(out) docker-for-desktop docker-for-desktop-cluster docker-for-desktop
(out) * minikube minikube minikube
(out) ...
kubectl config use-context docker-for-desktop
(out) Switched to context "docker-for-desktop".
 

Going to kubectl utility now, you should be able to run commands towards the new cluster:

  
kubectl cluster-info
(out) Kubernetes master is running at https://localhost:6443
(out) KubeDNS is running at https://localhost:6443/api/v1/namespaces/kube-system/services/kube-dns/proxy

Note: You may have already another kubectl installed on your machine (E.g. installed via gcloud utility if you used GKE before, or as a stand-alone program if you used minikube). Docker will install automatically a new kubectl binary in /usr/local/bin/. You’ll need to decide which one you’ll keep.

Deploying apps on the local Kubernetes cluster via Docker for Mac

Ok, let’s try to install our first apps using a Docker-compose file. Yes, the previous sentence is correct. If you want to deploy apps to your new local Kubernetes cluster using the docker cli, docker-compose file is the only way. If you already have some Kubernetes manifests you plan to deploy, you can do it using the known way, with kubectl.

We’re using here the demo-app from the official docker-page about Kubernetes:

  
wget https://raw.githubusercontent.com/jocatalin/k8s-docker-mac/master/docker-compose.yaml
docker stack deploy -c docker-compose.yaml hello-k8s-from-docker
(out) Stack hello-k8s-from-docker was updated
(out) Waiting for the stack to be stable and running...
(out) - Service db has one container running
(out) - Service words has one container running
(out) - Service web has one container running
(out) Stack hello-k8s-from-docker is stable and running

If you’re familiar with Docker swarm, there is nothing new about the command. What’s different is that the stack was deployed to our new Kubernetes cluster. The command generated deployments, replica sets, pods and services for the 3 applications defined in the compose file:

  
kubectl get all
(out) NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
(out) deploy/db 1 1 1 1 39s
(out) deploy/web 1 1 1 1 39s
(out) deploy/words 1 1 1 1 39s
(out) .
(out) NAME DESIRED CURRENT READY AGE
(out) rs/db-794c8bc8d9 1 1 1 39s
(out) rs/web-54cbf7d7fb 1 1 1 39s
(out) rs/words-575cd67dff 1 1 1 39s
(out) .
(out) NAME READY STATUS RESTARTS AGE
(out) po/db-794c8bc8d9-mrw79 1/1 Running 0 39s
(out) po/web-54cbf7d7fb-mx4c7 1/1 Running 0 39s
(out) po/words-575cd67dff-ddgw2 1/1 Running 0 39s
(out) .
(out) NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
(out) svc/db ClusterIP None 55555/TCP 39s
(out) svc/web LoadBalancer 10.96.17.42 80:31420/TCP 39s
(out) svc/words ClusterIP None 55555/TCP 39s

Doing any change in the docker-compose file and re-deploying it (e.g. change the number of replicas, change the image version) will update the Kubernetes app accordingly. The concept of namespaces is supported as well via the --namespace parameter. Deleting the application stacks can also be done via the docker cli.

Implementation details

Will Docker for Mac allow you to deploy with the docker cli the compose-files on other Kubernetes cluster? No, it won’t. Trying to deploy the same file on another cluster will return this error:

could not find compose.docker.com api.
Install it on your cluster first
	
	

The integration is implemented at API level. Open a proxy to the Docker for mac Kubernetes cluster:

  
kubectl proxy
(out) Starting to serve on 127.0.0.1:8001

Going in the browser to http://localhost:8001 will reveal some new API’s that are (most probably) responsible for this compose to k8s manifest translation:


"/apis/compose.docker.com"
"/apis/compose.docker.com/v1beta1"

So at this point, if you want to deploy the same application stack on other clusters, you need to use something like Kompose to convert docker-compose files to Kubernetes manifests (it didn’t work for my example), or write the manifests by hand.

Docker for Mac with Kubernetes vs minikube

There are a few advantages here if we’re comparing this implementation with minikube:

  • If you’re new to Kubernetes, you can deploy and run a local cluster without any other tools or Kubernetes knowledge
  • You can reuse the docker-compose files and deploy apps both on Swarm and Kubernetes (think POC’s or migrations user cases)
  • You’ll have one registry for local docker images and the Kubernetes cluster (not the case with minikube for example)

There are also some disadvantages:

  • The Kubernetes version is hardcoded
  • It’s more or less a “read-only” Kubernetes that you can't really change
  • Mixing the terminologies (use docker cli to deploy to k8s) can become somehow confusing

If you’re completely new to Kubernetes but you’re familiar with Docker, this approach allows you to get a pick at what K8s can do from a safe zone (docker cli). But for application debugging and writing manifests, you’ll need to learn some Kubernetes.

In the docker style, the implementation is clean, simple and user-friendly. Will this make minikube obsolete? For casual users probably yes. But, if you want to run a specific version of Kubernetes, specific add-ons or for more advanced use cases, minikube is still the way to go. Further integration will come into the Docker stack, so for enterprise and Windows, keep an eye here.

Comments
Leave your Comment