3 Minutes to Single Node Kubernetes cluster on Docker for Mac Platform

Docker For Mac 17.12 GA Release is now available for the general public. Experimental Kubernetes Support is available only on Edge Release. You can now run a single-node Kubernetes cluster from the “Kubernetes” Pane in Docker For Mac Preferences and use kubectl commands as well as docker commands. This means that there is no need of installing Kubectl or related Kubernetes CLI commands. It is ready-to-use platform which gives developers a simple and fast way to build and test Kubernetes apps locally with the latest and greatest Docker.


Say Bye to Minikube

Before Docker for Mac 17.12 release, for anyone who wants to get started with single node Kubernetes cluster, Minikube was an ideal tool. Minikube is a great local development environment and a way to learn the most common commands that help you to bring up a single node K8s cluster. To use Minikube, one needed a hypervisor and a container solution as well as the Kubernetes command-line tool called kubectl. Now these tools has to be manually installed on your Linux/MacOS.

But with the arrival of Kubernetes powered Docker for Mac 17.12, you no longer need these 3rd party tools & hypervisor to be installed or configured. Just update your Docker for Mac to 17.12 release and there you have ready-to-use single node Kubernetes cluster already up and running.

The Kubernetes server runs within a Docker container on your Mac, and is only for local testing. When Kubernetes support is enabled, you can deploy your workloads, in parallel, on Kubernetes, Swarm, and as standalone containers. Enabling or disabling the Kubernetes server does not affect your other workloads.

A Little about Kubernetes in 2018..

Kubernetes is not a mere orchestration system, in fact, it eliminates the need for orchestration. If you look at the technical definition of orchestration in wikipedia, it is all about the execution of a defined workflow: first do X, then Y, then Z. But in contrast, Kubernetes is comprised of a set of independent, composable control processes that continuously drive the current state towards the provided desired state. It shouldn’t matter how you get from X to Z. No need of any centralised control. This results in a system that is easier to use and more powerful, robust, resilient, and extensible.

Kubernetes provides a rich set of features for container grouping, container orchestration, health checking, service discovery, load balancing, horizontal autoscaling, secrets & configuration management, storage orchestration, resource usage monitoring, CLI, dashboard and much more. Few of the important points one should know about K8s are –

  • Kubernetes operates at the application level rather than at the hardware level
  • Kubernetes is not monolithic, and these default solutions are optional and pluggable.
  • Kubernetes is not a traditional, all-inclusive PaaS (Platform as a Service) system
  • Kubernetes operates on a declarative model, object specifications provided in so called manifest files declare how you want the cluster to look.
  • Kubernetes aims to support an extremely diverse variety of workloads, including stateless, stateful, and data-processing workloads.If an application can run in a container, it should run great on Kubernetes.
  • Allows users to choose their logging, monitoring, and alerting systems. (It provides some integrations as proof of concept.)

Docker for Mac is a great platform for developers…

Yes, you read it right. For anyone who want to configure a Docker dev environment and build, test and debug containerized apps, Docker for Mac is a great platform to get started with. Under this blog post, I will show how to build a simple Web Application Server running on a Single Node K8s cluster.


Let’ begin with a clean Docker for Mac 17.12 system. I am running macOS High Sierra version 10.13.1.Follow the below link if you are setting up Kubernetes on Docker for Mac 17.12 for the first time.

A First Look at Kubernetes Integrated Docker For Mac Platform


Setting up Web Application Cluster on K8s in 3 minutes

This section assumes that you are well versed with Kubernetes architectureand concepts. We will start with a clean MacOS system, hence there is no POD, no deployment and just default Kubernetes service running on your machine.

Ajeets-MacBook-Air:example1 ajeetraina$ kubectl get pods
No resources found.
Ajeets-MacBook-Air:example1 ajeetraina$ kubectl get deployment
No resources found.
Ajeets-MacBook-Air:example1 ajeetraina$ kubectl get svc
kubernetes   ClusterIP    <none>        443/TCP   2d
Ajeets-MacBook-Air:example1 ajeetraina$ 
Ajeets-MacBook-Air:example1 ajeetraina$


  • Creating Pod using Pod Definition
  • Exposing Pod to external world
  • Cleaning up

Creating Pod using Pod Definition

The simplest pod definition describes the deployment of a single container. A pod definition is a declaration of a desired state. For example, a simple web server pod might be defined as such:

apiVersion: v1
kind: Pod
  name: collabweb
  - name: webnix
    image: ajeetraina/webdemo
      - containerPort: 8080

It’s time to create our first Pod.. 

To create a pod containing a web server, run the below command:


$kubectl create -f webdemo.yml

Once the pod is created, you can list it using the below command:

Ajeets-MacBook-Air:example1 ajeetraina$ kubectl get pods
collabweb   1/1       Running   0          48s

Showcasing details of a specific Pod can be achieved with the following command:


Ajeets-MacBook-Air:example1 ajeetraina$ kubectl describe pod collabweb 
Name:         collabweb
Namespace:    default
Node:         docker-for-desktop/
Start Time:   Mon, 15 Jan 2018 12:09:02 +0530
Labels:       <none>
Annotations:  <none>
Status:       Running
    Container ID:   docker://5e429a30c4648f2564ccc145c8a0fc5d7160f24a9358d4ee979ac3f4254b711f
    Image:          ajeetraina/webdemo
    Image ID:       docker-pullable://ajeetraina/webdemo@sha256:5fddb01a372b02ec2d49465a920eda0f864b9b71ac75032fcbeeba028764bcd8
    Port:           8080/TCP
    State:          Running
      Started:      Mon, 15 Jan 2018 12:09:12 +0530
    Ready:          True
    Restart Count:  0
    Environment:    <none>
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-4v6r8 (ro)
  Type           Status
  Initialized    True 
  Ready          True 
  PodScheduled   True 
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-4v6r8
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.alpha.kubernetes.io/notReady:NoExecute for 300s
                 node.alpha.kubernetes.io/unreachable:NoExecute for 300s
  Type    Reason                 Age   From                         Message
  ----    ------                 ----  ----                         -------
  Normal  Scheduled              1m    default-scheduler            Successfully assigned collabweb to docker-for-desktop
  Normal  SuccessfulMountVolume  1m    kubelet, docker-for-desktop  MountVolume.SetUp succeeded for volume "default-token-4v6r8"
  Normal  Pulling                1m    kubelet, docker-for-desktop  pulling image "ajeetraina/webdemo"
  Normal  Pulled                 1m    kubelet, docker-for-desktop  Successfully pulled image "ajeetraina/webdemo"
  Normal  Created                1m    kubelet, docker-for-desktop  Created container
  Normal  Started                1m    kubelet, docker-for-desktop  Started container

Listing the Deployment:

Ajeets-MacBook-Air:example1 ajeetraina$ kubectl get deployment -o wide
webdemo   1         1         1            1           7h        webdemo      ajeetraina/webdemo   run=webdemo

Creating a Deployment

kubectl run webdemo --image=ajeetraina/webdemo --port=8080 

Verifying the Deployment

kubectl get deployment webdemo -o wide


Exposing the pods

Exposing your pods so that it can access on the browser:

kubectl expose deployment webdemo --port=8080 --type=NodePort

Once the above command runs successfully, you should be able to list out the services –

Ajeets-MacBook-Air:example1 ajeetraina$ kubectl get services
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP      <none>        443/TCP          2d
webdemo      NodePort   <none>        8080:30990/TCP   5m

Now we should be able to access the Webdemo Test Page using the below command:

Ajeets-MacBook-Air:example1 ajeetraina$ curl localhost:30990
<h1>Web Test engine</h1>
        <a href='/type/text'>text</a>
        <code>Welcome to Collabnix</code>
        <a href='/type/html'>html</a>
        <code>&lt;h1&gt;Docker, Kubernetes &amp; Cloud!&lt;/h1&gt;</code>
        <a href='/type/json'>json</a>
        <code>{&quot;message&quot;:&quot;Hello JSON World!&quot;}</code>
    HTTP Status Codes
        <a href='/code/400'>400 &mdash; Bad Request</a>
        <a href='/code/401'>401 &mdash; Unauthorized</a>
        <a href='/code/403'>403 &mdash; Forbidden</a>
        <a href='/code/404'>404 &mdash; Not Found</a>
        <a href='/code/405'>405 &mdash; Method Not Allowed</a>
        <a href='/code/406'>406 &mdash; Not Acceptable</a>
        <a href='/code/418'>418 &mdash; I'm a teapot (RFC 2324)</a>
<h2>Web Demo Docker Container</h2>

Done. You have created your first Single Node web application cluster running on Kubernetes   powered Docker for Mac Platform.

Interestingly, one can run Docker specific commands too to list out the running containers:

Ajeets-MacBook-Air:~ ajeetraina$ docker ps | head -n 2
CONTAINER ID        IMAGE                                                    COMMAND                  CREATED             STATUS              PORTS                    NAMES
eb6312309518        ajeetraina/webdemo                                       "ruby webtest.rb -p …"   9 hours ago         Up 9 hours                                   k8s_webdemo_webdemo-85f56bc5d5-np9qh_default_eae29f0d-f9bf-11e7-994c-025000000001_0
Ajeets-MacBook-Air:~ ajeetraina$ docker exec -it eb631 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
   link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
   inet scope host lo
      valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1
   link/ipip brd
3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default qlen 1
   link/tunnel6 :: brd ::
5: eth0@if36: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
   link/ether 0a:58:0a:01:00:2b brd ff:ff:ff:ff:ff:ff
   inet scope global eth0
      valid_lft forever preferred_lft forever
Ajeets-MacBook-Air:~ ajeetraina$ 

Cleaning Up

To delete the webdemo containers, delete the deployment:


kubectl delete deployment webdemo

Did you find 3-minutes still time-consuming? Do visit the below post to see how docker stack deploy can save your time.

When Kubernetes Meet Docker Swarm for the First time under Docker for Mac 17.12 Release


Did you find this blog helpful?  Feel free to share your experience. Get in touch @ajeetsraina.

If you are looking out for contribution/discussion, join me at Docker Community Slack Channel.


  • MaxHuang

    Hi @ajeetsraina , follow your blog, it seems need deployment but no show in your blog.
    I got nothing with deployment after I run $ kubectl create -f webdemo.yml

    $ kubectl get deployment -o wide
    No resources found.
    Do I miss anything?

  • kf0s

    Does anyone know if we can change the Kubernetes configuration at all in this environment? If I wanted to add a GenericAdmissionWebhook on the admission-control flag for the api-server, is this possible?