Walkthrough: How to build your own customised LinuxKit kernel?

Estimated Reading Time: 5 minutes


“..Its Time to Talk about Bring Your Own Components (BYOC) now..”

The Moby Project  is gaining momentum day by day. If you are System Builder looking out for building your own container based systems, Moby is for you. You have freedom to choose from the library of components derived from Docker or you can elect to “bring your own components” packaged as containers with mix-&match options among all of the components to create your own customised container system. Moby as a tool promises to convert Docker from a monolithic engine into a toolkit of reusable components and these individual components results in the building blocks for custom solutions.


I was a speaker at Docker Bangalore Meetup last weekend and talked about “Introduction to LinuxKit”. I walked through the need of LinuxKit for immutable infrastructure, platform it supports and finally demoed PWM(Play with Moby). I spent considerable amount of time talking about “How to Build Your Own LinuxKit OS” and showcased them how to build it using a single YAML file. One of the interesting question raised was – ” How shall I build Ubuntu or Debian based OS as our infrastructure runs most of these distributions?” I promised them to write a blog post which is easy to follow and help them build their own customised kernel with LinuxKit.

A Brief about LinuxKit Kernel..

LinuxKit Kernel images are distributed as hub images as shown below:

Screen Shot 2017-07-09 at 7.25.10 AM


It contains the kernel, kernel modules, kernel config file, and optionally, kernel headers to compile kernel modules against. It is important to note that LinuxKit kernels are based on the latest stable releases.Each kernel image is tagged with the full kernel version (e.g.,linuxkit/kernel:4.10.x) and with the full kernel version plus the hash of the files it was created from.

LinuxKit offers the ability to build bootable Linux images with kernels from various distributions like CentOS, Debian, Ubuntu. As of today, LinuxKit offers a choice of the following kernels:

Moby uses YAML file as an input to build LinuxKit OS image. By default, the YAML file uses the default linuxkit/kernel:<version> as an official image as shown below in the first 3 lines.

Screen Shot 2017-07-09 at 7.34.01 AM


Let us see how to build our own distribution Linux Kernel(Ubuntu) through the below steps:

Under LinuxKit project repository, there is a kernel build directory and holds essential Dockerfile, configuration files and patches available to build your own Kernel for LinuxKit OS.

Screen Shot 2017-07-09 at 7.46.57 AM

If you want to include your own new patch, you can fork the repository and get the patch added under the right patch directory(shown above). For example, if you need to add patch to 4.11.x release, you can add it under patch-4.11.x directory as shown below:

Screen Shot 2017-07-09 at 7.57.35 AM

Below is the snippet of kernel_config-4.11.x file. The few lines below shows that the new built kernel will be pushed to Dockerhub under ORG/kernel:<version>.

Screen Shot 2017-07-09 at 8.33.36 AM

Next, all you need to do is run the below command to build your own customised kernel with required patches and modules loaded:

make build_4.11.x ORG=ajeetraina

PLEASE NOTE – ORG should be replaced by your Dockerhub ORG (it’s basically Dockerhub ID). If you are planning to raise PR for your patch to be included, you can use LinuxKit ORG and then get it approved.


Screen Shot 2017-07-09 at 7.52.21 AM

This will take sometime to create a local kernel image called ajeetraina/kernel:4.11.8-8bcfec8e1f86bab7a642082aa383696c182732f5 assuming you haven’t committed you local changes.

Screen Shot 2017-07-09 at 9.24.57 AM


You can then use this kernel in your YAML file as:

   image: "ajeetraina/kernel:4.11.9-2fd6982c78b66dbdef84ca55935f8f2ab3d2d3e6"

Screen Shot 2017-07-09 at 9.45.42 AM


Run the Moby tool to build up this new kernel:

moby build linuxkit.yml

Screen Shot 2017-07-09 at 9.46.57 AM


How to Build Ubuntu based Kernel Image

If you are looking out for building distribution specific Kernel images, then this is the right section for you to refer. Docker Team has done a great job in putting it altogether under linuxkit/scripts/kernel directory as shown below:

Screen Shot 2017-07-09 at 8.12.28 AM

Let us look inside Dockerfile.deb:

Screen Shot 2017-07-09 at 8.50.35 AM

The script ubuntu.sh picks up Dockerfile.deb to build and push the kernel-ubuntu image as shown below in the snippet:

Screen Shot 2017-07-09 at 8.53.07 AM

All you need to do is execute the script:

sh ubuntu.sh

It will take sometime and you should see the below output:

Screen Shot 2017-07-09 at 8.56.10 AM

Now you can leverage this kernel into YAML file as shown below in the output:

Screen Shot 2017-07-09 at 10.01.27 AM

Let us pick up linuxkit/linuxkit.yml and add the above kernel entry to build LinuxKit OS running Docker containers as a service.

Screen Shot 2017-07-09 at 10.31.12 AM


Use the moby build command to build LinuxKit OS image based on Ubuntu kernel:

moby build linuxkit.yml

Screen Shot 2017-07-09 at 10.36.47 AM



Next, execute the linuxkit run command to boot up LinuxKit.

linuxkit run linuxkit

Screen Shot 2017-07-09 at 10.40.18 AM


Let us verify if the services are up and running:

Screen Shot 2017-07-09 at 10.48.50 AM

It’s easy to enter into one of service container as shown below:

Screen Shot 2017-07-09 at 10.52.40 AM

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.

Know more what’s happening in LinuxKit project by visiting this link.

Talking about Moby & LinuxKit Awesomeness at Docker Bangalore Meetup

Estimated Reading Time: 4 minutes

Today  I spoke at Docker Bangalore Meetup which took place in IBM India Systems Development Lab(ISL) – an R&D Division located at Manyata Embassy Business Park. Docker Bangalore Meetup Group is one of the most highest registered (holds around 5000+ registered Docker users currently) in India. Founded in November 22, 2013, it is now 4 year old and has been led by a Docker Captain & Founder of CloudYuga, Neependra Khare who has been actively organising this event since its birth. This event was Live streamed using Google HangOut and most of the sessions are available under YouTube here.



This time I chose  “An Introduction to LinuxKit” topic as I spent considerable amount of time writing
blogs around LinuxKit, InfraKit, Moby and it’s supported platforms. Since DockerCon 2017, I have written around 6-7 blogs primarily on LinuxKit on various platform and this was one great chance to meet with Docker enthusiasts and clarify around Docker  Vs Moby Vs LinuxKit.



Neependra started the Meetup talking about Moby. He clarified most of the facts around “Docker ! = Moby” and talked around Moby tool. He touched upon LinuxKit YAML file and demonstrated docker-17.06-ce container service built by Moby tool & LinuxKit toolkit. It was overall very interactive session and there were couple of great questions from the audience related to Moby assemblies. Docker Captain, Sreenivas Makam from Cisco delivered a great deep-dive talk around “Docker networking – Common issues and troubleshooting techniques”.  He brought up interesting troubleshooting techniques and common issues around Docker Networking and you can find his impressive slide here.

Screen Shot 2017-07-02 at 11.04.13 PM


I was the 2nd speaker on the row. I started my talk with “Why LinuxKit?” and spent considerable amount of time talking about the problem statement which led to the birth of LinuxKit. I walked through the audience on LinuxKit & introduced new Moby playground called as “Play with Moby“. In case you’re new, Play-with-moby (PWM) is a site made by Docker captains Marcos Nils and Jonathan Leibiusky as an extension of PWD. PWM is a Moby playground which allows you to try different components of the platform in seconds. It gives you the experience of having a free Alpine Linux Virtual Machine in the cloud where you can build and run Moby projects and even create clusters to experiment. Under the hood DIND or Docker-in-Docker is used to give the effect of multiple VMs/PCs.


At the end of the session, I demonstrated around “Building Docker containers using LinuxKit”. I enjoyed talking around LinuxKit Packaging System” during which there were numerous interesting queries from the audience. You can refer the below slides to get the glimpse of the talk.




Few of interesting questions around Moby & LinuxKit:

  1. How does LinuxKit implementation works for bare metal system?
  2. Can I build CentOS based LinuxKit Operating System as we use CentOS primarily on IBM Power System S822LC?
  3. What’s happening around LinuxKit Security areas? How secure is LinuxKit today?
  4. Can I use my own customised Kernel and get it work under LinuxKit YAML?
  5. Is LinuxKit completely open source?
  6. What is the story of Volume mount in terms of LinuxKit? What about the data persistence?

Special thanks goes to all the speakers for the valuable sessions. I have been closely watching the feedback and I could read that the audience liked the event and enjoyed the informative session. Thanks to IBM ISL Team for your sponsorship and a great lunch at the end of the day.

If you are keen to learn what’s happening in LinuxKit, Moby & Docker space, don’t miss out the below links –


Running LinuxKit on AWS Platform made easy

Estimated Reading Time: 4 minutes

With around 2800+ GITHUB stars, 54 contributors,  28 external, 50+ commits per week since the DockerCon launch, LinuxKit has really gained a lot of momentum among the community users. LinuxKit today supports multiple platforms – AWS, Hyper V, Azure, MacOS, Google Cloud Platform, Packets.net, VMware Fusion, QEMU & Local Hypervisors. Installation of LinuxKit on macOS has been simplified using Homebrew. Just 2 simple brew commands and moby is ready to build up your LinuxKit OS image.


Soon after DockerCon 2017, I wrote a blog post on how to get started with LinuxKit for Google Cloud Platform. Since then I have been closely keeping eye on the latest features, enablements & releases of LinuxKit. Under this blog post, I bring up a simplified approach to get LinuxKit OS instance running on top of Amazon Web Services(AWS) Platform.

Here we go..


  1. Install AWS CLI on macOS(Using Homebrew)
  2. Installing LinuxKit & Moby Tool(Using Homebrew)
  3. Configuring AWS S3 bucket
  4. Building a RAW image with Moby tool
  5. Configuring VM Import Service Role
  6. Upload the aws.raw Image to remote AWS S3 bucket using LinuxKit
  7. Run the LinuxKit OS as EC2 Instance 

Installing AWS CLI on macOS


Screen Shot 2017-06-20 at 8.11.00 AM

Screen Shot 2017-06-20 at 8.12.14 AM


Setting the AWS_REGION environment variable as this is used by the AWS Go SDK:

export AWS_REGION=ap-south-1

Installing LinuxKit & Moby tool:

brew tap linuxkit/linuxkit
brew install --HEAD moby
brew install --HEAD linuxkit


Screen Shot 2017-06-20 at 7.47.54 AM

Screen Shot 2017-06-20 at 8.08.07 AM


Creating/Configuring AWS S3 bucket:

Open up AWS Management console and click on S3 under AWS Services. It will open up the below page:

Screen Shot 2017-06-18 at 10.14.01 PM

Screen Shot 2017-06-18 at 10.15.19 PM

Screen Shot 2017-06-18 at 10.15.51 PM

Screen Shot 2017-06-18 at 10.16.28 PM


Building AWS RAW Image using Moby:

Screen Shot 2017-06-18 at 10.44.35 PM

Screen Shot 2017-06-18 at 10.46.30 PM


This builds up aws.raw which we need to push to AWS S3 bucket using the below command:

linuxkit push aws -bucket linuxkit-images  -timeout 1200 aws.raw

This will throw the below error:

“…The sevice role <vmimport> does not exist or does not have sufficient permissions for the service to continue. status code: 400, request id: 0ce661fb-e9b4-40b8-af07-9da6a6fc3c94..”

Follow the next section to get it fixed..

Configuring VM Import Service Role 

VM Import requires a role to perform certain operations in your account, such as downloading disk images from an Amazon S3 bucket. You must create a role named vmimport with a trust relationship policy document that allows VM Import to assume the role, and you must attach an IAM policy to the role. I used this script to setup everything in a single shot:

Upload the aws.raw Image to remote AWS S3 bucket using LinuxKit

It’s time to push the RAW Image to S3 bucket:

linuxkit push aws -bucket linuxkit-images -timeout 1200 aws.raw
Created AMI: ami-0a81fe65

Creating an instance

linuxkit run aws aws
Created instance i-02b28f9f8eee1dcf2
Instance i-02b28f9f8eee1dcf2 is running

Open up your AWS Management console and you will soon see new instance coming up.

Screen Shot 2017-06-19 at 12.41.11 AM


Screen Shot 2017-06-19 at 12.45.15 AM


Here you go.. AWS E2 instance running LinuxKit OS is up and running..

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.

Know more what’s happening with AWS project activities clicking on this link.

Why Infrakit & LinuxKit are better together for Building Immutable Infrastructure?

Estimated Reading Time: 6 minutes

Yet Another Problem Statement(YAPS)…

Let us accept the fact – “Managing Docker on different Infrastructure is still difficult and not portable”. While working on Docker for Mac, AWS, GCP & Azure, Docker Team realized the need for a standard way to create and manage infrastructure state that was portable across any type of infrastructure, from different cloud providers to on-prem. One serious challenge is that each vendor has differentiated IP invested in how they handle certain aspects of their cloud infrastructure. It is not enough to just provision n-number of servers;what IT ops teams need is a simple and consistent way to declare the number of servers, what size they should be, and what sort of base software configuration is required. Also, in the case of server failures (especially unplanned), that sudden change needs to be reconciled against the desired state to ensure that any required servers are re-provisioned with the necessary configuration. Docker Team introduced and open sourced “InfraKit” last year to solve these problems and to provide the ability to create a self healing infrastructure for distributed systems.

Screen Shot 2017-06-11 at 5.05.12 PM


InfraKit is basically a toolkit for infrastructure orchestration. With an emphasis on immutable infrastructure, it breaks down infrastructure automation and management processes into small, pluggable components. These components work together to actively ensure the infrastructure state matches the user’s specifications. InfraKit therefore provides infrastructure support for higher-level container orchestration systems and can make your infrastructure self-managing and self-healing.

Why the Integration of LinuxKit with Infrakit now??

LinuxKit is gaining momentum in terms of  a toolkit for building custom minimal, immutable Linux distributions. Integration of Infrakit with LinuxKit will help users  to build and deploy custom OS images to a variety of targets – from a single vm instance on the mac (via xhyve / hyperkit, no virtualbox) to a cluster of them, as well as booting a remote ARM host on Packet.net from the local laptop via a ngrok tunnel.

Under this blog post, I will show you how does InfraKit and LinuxKit work together to build immutable infrastructure. I want to test drive these toolkits on my macOS Sierra 10.12.3 system.

Installing Homebrew

/usr/bin/ruby -e “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)”

Installing WGET

brew install wget

Installing Infrakit:

sudo wget -qO- https://docker.github.io/infrakit/install | sh

Copy the file to your path:

sudo cp ./infrakit /usr/local/bin/

Infrakit is cross compiled and installed on your system. Let us try to see what playbook are available as of now.

Screen Shot 2017-06-12 at 2.04.28 AM


Adding INFRAKIT_HOME variable:

bash-3.2$ source ./.bash_profile

bash-3.2$ echo $INFRAKIT_HOME



Adding LinuxKit Playbook

By default, there is no playbook available . Let us try to install LinuxKit and see how InfraKit integrate with LinuxKit.

Create a directory called testproj. 

mkdir testproj
cd testproj

Add the LinuxKit Playbook:

 infrakit playbook add linuxkit https://docker.github.io/infrakit/playbooks/linuxkit/index.yml

Verifying the LinuxKit Playbook

sudo infrakit playbook ls
PLAYBOOK                      URL                           
linuxkit                      https://docker.github.io/infrakit/playbooks/linuxkit/index.yml

Screen Shot 2017-06-12 at 2.02.57 AM


Run the below command to see what options are available under LinuxKit playbook:

infrakit playbook linuxkit

Screen Shot 2017-06-12 at 2.05.51 AM


Installing HyperKit Plugin on your Mac

infrakit playbook linuxkit install-hyperkit


Screen Shot 2017-06-12 at 2.01.54 AM

This command installs HyperKit plugins and add it under /usr/local/bin directory automatically.

Under the testproj directory, you will now see infrakit-instance-hyperkit gets created:

testproj$ ls
docker4mac infrakit-instance-hyperkit

Installing Moby Build Tool  to build custom OS images

infrakit playbook linuxkit install-moby

Screen Shot 2017-06-12 at 1.56.10 AM

Once it gets completed, you will see the options to build OS images:

Screen Shot 2017-06-11 at 7.50.40 AM

Now the software has been installed. The Playbook has command to start everything.

Starting the LinuxKit 

sudo infrakit playbook linuxkit start

Screen Shot 2017-06-12 at 1.59.23 AM

Ensure that you type “yes” for ‘Start HYPERKIT plugin’ while running the above command.

By now, the Infrakit command line interface will show additional options:

infrakit -h
Infrakit command line interface
infrakit [command]
Available Commands:
event Access event exposed by infrakit plugins
event-time Access plugin event-time which implements Metadata/0.1.0
event-time/time Access plugin event-time/time which implements Metadata/0.1.0
event-time/timer Access plugin event-time/timer which implements Event/0.1.0
flavor-vanilla Access plugin flavor-vanilla which implements Flavor/0.1.0
group Access plugin group which implements Group/0.1.0,Manager/0.1.0,Metadata/0.1.0,Updatable/0.1.0
group-stateless Access plugin group-stateless which implements Group/0.1.0,Metadata/0.1.0
instance-hyperkit Access plugin instance-hyperkit which implements Instance/0.5.0,Metadata/0.1.0
manager Access the manager
metadata Access metadata exposed by infrakit plugins
playbook Manage playbooks
plugin Manage plugins
remote Manage remotes
template Render an infrakit template at given url. If url is ‘-‘, read from stdin
util Utilities
version Print build version information
x Experimental features

As you see above, CLI is contextual. It basically discovers the hyperkit plugin running and generates a new command for you to access it


In case hyperkit plugin is not turning up, you can kill the old hyperkit instance process and re-start it.

Screen Shot 2017-06-13 at 9.19.10 AM

Verify if the hyperkit plugin is up and running

Screen Shot 2017-06-12 at 1.52.27 AM

In case you want to run HyperKit, there is recommended command for it.

bash-3.2$ infrakit playbook linuxkit run-hyperkit
Start HYPERKIT plugin? [no]: yes
Starting HYPERKIT plugin.  This must be running on the Mac as a daemon and not as a container
This plugin is listening at localhost:24865

By now, we have everything ready for our LinuxKit SSH playbook

LinuxKit SSHD Example:

Now let me show you how to build a LinuxKit image containing just a simple sshd.The file `sshd.yml` defines the components inside the image.  Instead of a standard LinuxKit image yml, it is actually an InfraKit template that is rendered before the moby tool is invoked to build the actual OS image.

sudo infrakit playbook linuxkit demo-sshd

This will show up the detailed information on its usage on your terminal:


Screen Shot 2017-06-11 at 8.13.58 AM

Screen Shot 2017-06-11 at 8.14.51 AM

Screen Shot 2017-06-11 at 8.16.07 AM

Let us first build the “SSHD” YAML file using the below command:

sudo infrakit playbook linuxkit demo-sshd build-image
Verifying the SSH outputs:
Looking into sshd.yml content:
The below content shows us that SSH service has been right created:
The command `build-image` will collect user input such as the public key location and use that to generate the final input to `moby`.
Open up a new terminal to watch our first Hyperkit instance:
watch -d infrakit instance-hyperkit describe

Running the SSH Instance

Using the `hyperkit` subcommand (does not require billing accounts / signup on providers),you can create a single or a cluster of instances after you run the `build-image`.

The command `… hyperkit run-instance` will use hyperkit plugin to create a single guest vm that boots from the image you built with `build-image`.

infrakit playbook linuxkit demo-sshd hyerpkit run-instance

This command brings up the LinuxKitOS instance. 

Now you can run the below command to enter into SH shell

docker run --rm -ti -v ~/.ssh:/root/.ssh  infrakit/ssh /bin/sh

[ A Special Thanks to David Chung, Docker Team for assisting me understand LinuxKit Playbook thoroughly.]

In the future blog post, I will show you how LinuxKit + Infrakit + GCP works together.

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.

Know more what’s happening with Infrakit project activities clicking on this link.

A Quick Look at LinuxKit Packaging System

Estimated Reading Time: 5 minutes

One of the most compelling feature of LinuxKit is “Everything replaceable and customisable”. You can now build up your own customised Linux Operating System so as to run it across various platforms like Bare Metal Hardware, Virtual Machines, Cloud Instances etc. As of today, LinuxKit supports various platform like OSX/Hypervisor, Google Cloud Platform, Packets.net, QEMU/KVM &  VMware ESXi vCenter Server. Effort has already been started for enabling this solution on AWS, Azure, Bluemix etc. For Raspberry Pi aspirants, there is already a feature request raised for enabling LinuxKit on ARM64 platform.

Screen Shot 2017-06-03 at 9.44.56 AM

LinuxKit is built with containers to run the containers. It involves easy tooling and that too with easy iteration.Under LinuxKit, we have runc and containerd which are used to run containers.Containers under LinuxKit are managed by runc and containerd and not by Docker.Everything apart from the init process and runc/containerd run in a container. Under this blog post, I will take you through Packaging System under LinuxKit. This might help you build your own customised OS for your infrastructure requirement.

Screen Shot 2017-06-03 at 9.41.00 AM

Building Packages Under LinuxKit:

Packages under LinuxKit are just container images stored on DockerHub or in private registries. They are stored under Dockerhub under LinuxKit org.

Screen Shot 2017-06-03 at 7.42.13 AM

Base packages for LinuxKit are stored under /pkg directory under LinuxKit repository. To view it, you can clone LinuxKit GITHUB repository and look under linuxkit/pkg directory as shown below:

git clone https://github.com/linuxkit/linuxkit
cd linuxkit/pkg/


Screen Shot 2017-06-03 at 6.56.14 AM


There are different ways for building LinuxKit base packages. You can either use DockerHub images directly or build your own wrapper around DockerHub images in the form of shell script. You have flexibility to use customised base images or custom package with just 1 binary.

It is important to note that Packaging System under LinuxKit uses extensive use of Multi-Stage Builds to Keep package Smaller. To demonstrate, let us pick up one base package – OpenNTPD and see what does it contain.

Screen Shot 2017-06-03 at 9.38.57 AM

Ajeets-MacBook-Air:openntpd ajeetraina$ pwd;ls
Dockerfile Makefile etc

As shown above, OpenNTPD contains a Dockerfile, Makefile & etc directory to hold NTP configurational changes.


Screen Shot 2017-06-03 at 7.54.05 AM

There are multiple FROMs in this Dockerfile which indicates that packages are built using Multi-Stage Build environment. Let us closely look line by line:

FROM linuxkit/alpine:630ee558e4869672fae230c78364e367b8ea67a9

In the first stage, we are trying to pull ALPINE base image which is part of LinuxKit project. LinuxKit has specific versions of all the packages and hence you can see that specific version is hard-coded.

RUN mkdir -p /out/etc/apk && cp -r /etc/apk/* /out/etc/apk/

This creates a directory where it is going to install the  contents of the packages.

RUN apk add --no-cache --initdb -p /out \
    alpine-baselayout \
    busy box \
    musl \
    openntpd \
    && true

It uses Alpine Package Manager(APK) to install standard base layout for standard root filesystem, busy box for SHELL environment, musl in order to have C libraries which is used by all of these components and finally OpenNTP related packages.

At the end of first stage, a container image based on Alpine base image having a directory holding required files and packages with root filesystem enough to run OpenNTP container is successfully built.

RUN rm -rf /out/etc/apk /out/lib/apk /out/var/cache

This removes temporary/unwanted files from OUT directly so as to keep the container smaller in size.

Under the 2nd Stage, the content of Dockerfile look like this:

Screen Shot 2017-06-03 at 9.10.29 AM


This starts with empty container image. We copy it from the first stage (i.e.. OUT directory) to our root filesystem. Then OpenNTPD daemon configuration & OpenNTP scripts are added from external /etc directory to the container image. Next, we specify the command that whenever container starts, we need OpenNTP daemon to be started.This provides us a minimal package which runs OpenNTPD service.

The last line is very important and recently been introduced under LinuxKit project. If you remember while building YAML file for LinuxKit, we used to specify CAPABILITIES section. For this OpenNTP service, we won’t require it now because we have now LABEL section added during the build process.  We have bind mounts so that /etc is mounted, network namespace can be specified, CAP_NET_BIND_SERVICE which helps in binding the container  to the interface.

Screen Shot 2017-06-03 at 9.24.45 AM

File: Makefile

Screen Shot 2017-06-03 at 8.43.44 AM

It contains docker build command, squash parameter is passed to squash the layer of the image into a single image to make it smaller in the 2nd stage, –network=none to indicates that while booting the container , it has no access to the network. Other essential entries includes the HASH value provides you with the content hash of all the files in the directory and hence  it becomes important to ensure that only the required files are being used to build up container image.

Let us try to run make command and see if this builds up right container image for us.

Ajeets-MacBook-Air:openntpd ajeetraina$ sudo make
docker build --squash --no-cache --network=none -t linuxkit/openntpd:45deeb05f736162d941c9bf494983f655ab80aa5 .
Sending build context to Docker daemon  5.632kB
Step 1/12 : FROM linuxkit/alpine:630ee558e4869672fae230c78364e367b8ea67a9 AS mirror
 ---> 72ff54f67634
Step 2/12 : RUN mkdir -p /out/etc/apk && cp -r /etc/apk/* /out/etc/apk/
 ---> Running in 175f2b917c9a
 ---> 08b114fc941c
Removing intermediate container 175f2b917c9a
Step 3/12 : RUN apk add --no-cache --initdb -p /out     alpine-baselayout     busybox     musl     openntpd     && true
 ---> Running in 3109ff2301fa
(1/7) Installing musl (1.1.16-r9)
(2/7) Installing busybox (1.26.2-r4)
Executing busybox-1.26.2-r4.post-install
(3/7) Installing alpine-baselayout (3.0.4-r0)
Executing alpine-baselayout-3.0.4-r0.pre-install
Executing alpine-baselayout-3.0.4-r0.post-install
(4/7) Installing libressl2.5-libcrypto (2.5.4-r0)
(5/7) Installing libressl2.5-libssl (2.5.4-r0)
(6/7) Installing libressl2.5-libtls (2.5.4-r0)
(7/7) Installing openntpd (6.0_p1-r3)
Executing openntpd-6.0_p1-r3.pre-install
Executing busybox-1.26.2-r4.trigger
OK: 3 MiB in 7 packages
 ---> 2336220414ec
Removing intermediate container 3109ff2301fa
Step 4/12 : RUN rm -rf /out/etc/apk /out/lib/apk /out/var/cache
 ---> Running in c39c2d86c898
 ---> 9248b40c1e31
Removing intermediate container c39c2d86c898
Step 5/12 : FROM scratch
Step 6/12 : ENTRYPOINT
 ---> Running in a1475ce25417
 ---> 89a4eefb0f2e
Removing intermediate container a1475ce25417
Step 7/12 : CMD
 ---> Running in 3299eb03002b
 ---> e0761d845e86
Removing intermediate container 3299eb03002b
Step 8/12 : WORKDIR /
 ---> dc50915b1354
Removing intermediate container 37292d5db9f6
Step 9/12 : COPY --from=mirror /out/ /
 ---> 60c358443d49
Removing intermediate container 4c746169a103
Step 10/12 : COPY etc/ /etc/
 ---> 049744fe228f
Removing intermediate container f9f21176ca4d
Step 11/12 : CMD /usr/sbin/ntpd -d -s
 ---> Running in 94c8a776666d
 ---> 56d618a1fa76
Removing intermediate container 94c8a776666d
Step 12/12 : LABEL org.mobyproject.config ‘{“capabilities”: [“CAP_SYS_TIME”, “CAP_SYS_NICE”, “CAP_SYS_CHROOT”, “CAP_SETUID”, “CAP_SETGID”]}’
 ---> Running in c1514342c0fb
 ---> 46987e8c78bc
Removing intermediate container c1514342c0fb
Successfully built c1dbda899687
Successfully tagged linuxkit/openntpd:45deeb05f736162d941c9bf494983f655ab80aa5
DOCKER_CONTENT_TRUST=1 docker pull linuxkit/openntpd:45deeb05f736162d941c9bf494983f655ab80aa5 || \
DOCKER_CONTENT_TRUST=1 docker push linuxkit/openntpd:45deeb05f736162d941c9bf494983f655ab80aa5
Pull (1 of 1): linuxkit/openntpd:45deeb05f736162d941c9bf494983f655ab80aa5@sha256:26e88ffd48262f4a03ed678d2edee35b807b4d7fe561a3aa6577eef325e317c4
sha256:26e88ffd48262f4a03ed678d2edee35b807b4d7fe561a3aa6577eef325e317c4: Pulling from linuxkit/openntpd
Digest: sha256:26e88ffd48262f4a03ed678d2edee35b807b4d7fe561a3aa6577eef325e317c4
Status: Image is up to date for linuxkit/openntpd@sha256:26e88ffd48262f4a03ed678d2edee35b807b4d7fe561a3aa6577eef325e317c4
Tagging linuxkit/openntpd@sha256:26e88ffd48262f4a03ed678d2edee35b807b4d7fe561a3aa6577eef325e317c4 as linuxkit/openntpd:45deeb05f736162d941c9bf494983f655ab80aa5

Let us verify if it built required image or not:

Screen Shot 2017-06-03 at 9.21.56 AM

The image is just 3.62MB which is quite smaller in size.

Now, you should be able to use this OpenNTPD base image under your YAML file so that moby tool can build up LinuxKit OS image:

Screen Shot 2017-06-03 at 9.29.40 AM

The above YAML content has been picked up from docker.yml file which contains ntpd service container created out of OpenNTPD base image.

In the future blog post, I will showcase how to build your own customised Kernel for LinuxKit.

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.

Know more about the latest LinuxKit project activities clicking on this link.

When Moby Meet Kubernetes for the first time

Estimated Reading Time: 5 minutes

Moby has turned to be an open playground for collaborators. It has become a popular collaborative project for the container ecosystem to assemble container-based systems. There has been tremendous amount of effort put to containerize an application but what about the platform which runs those containers? Shouldn’t that be containerize too? Moby is the answer. With library of over 80+ components for all vital aspects of a container system: OS, container run time, orchestration, infrastructure management, networking, storage, security, build, image distribution, etc., Moby can help you package your own components as containers.  The Moby Project enables customers to plug and play their favorite technology components to create their own custom platform. Interestingly, all Moby components are containers, so creating new components is as easy as building a new OCI-compatible container.

While  Moby project provide you with a command-line tool called “moby” to assembles components, LinuxKit is a valuable toolkit which allows you for building secure, portable and lean operating systems for containers. It provides a container-based approach to building a customized  Linux subsystem for each type of container. It is based on containerd and has its own Linux kernel, system daemon and system services. 


I attended Dockercon 2017, Austin TX last month and one of coolest weekend project showcased by Docker Team was running Kubernetes on Mac using Moby and LinuxKit. In case you’re completely new to Kubernetes, it is an open-source system for automating deployment, scaling and management of containerized applications. It was originally designed by Google and donated to the Cloud Native Computing Foundation. It provide a “platform for automating deployment, scaling, and operations of application containers across clusters of hosts”. It supports a range of container tools, including Docker.






One of the main benefit of LinuxKit for Kubernetes includes reliable deployment, lower security footprint, easy customization around building own desired base image.Under this blog post, I am going to demonstrate how one can easily create minimal and immutable Kubernetes OS images with LinuxKit.


  1. Install the latest Edge Release of Docker for Mac and Engine through this link.
  2. Please note that if you are using Stable Release of Docker for Mac, you won’t be able to setup Multi-node Kubernetes cluster as the stable release lack Multi-host functionality of VPNKit. Do refer this known issue. The support for multi-host networking was introduced in the latest Edge release.


Screen Shot 2017-05-11 at 9.09.37 AM

  • Ensure that Docker for Mac Edge Release gets displayed once you have installed it properly.


Screen Shot 2017-05-11 at 8.26.34 AM


Clone the LinuxKit Repository as shown:

git clone https://github.com/linuxkit/linuxkit


Build the Moby and LinuxKit tool first using the below commands:


cd linuxkit
cp -rf bin/moby /usr/local/bin/
cp -rf bin/linuxkit /usr/local/bin/


Change directory to kubernetes project:


cd linuxkit/projects/kubernetes


You will find the below list of files and directories:

Screen Shot 2017-05-11 at 8.31.24 AM


Let us first look at kube-master.yml file. Everything under LinuxKit is just a YAML file. This files starts with a section defining the kernel configuration, init section just lists images that is used for the init system and are unpacked directly into the root filesystem, the onboot sections indicates that  these containers are run to completion sequentially, using runc before anything else is started.  As shown below,  under the service section, there is a kubelet service defined which uses errordeveloper/mobykube:master image and build Kubernetes images.

Edit kube-master.yml and add your public SSH key to files section. You can generate the SSH key using ssh-keygen command.

Screen Shot 2017-05-12 at 9.24.03 AM


Once you have added your public SSH key, go ahead and build OS images using the below command:


sudo make build-vm-images


The above command provides you with the below output:


Screen Shot 2017-05-11 at 8.48.35 AM


Few of the important files includes:

kube-node-kernel  kube-node-initrd.img  kube-node-cmdline


Under the same directory, you will find a file called “boot-master.sh” which will help us in setting up the master node.


Screen Shot 2017-05-12 at 9.28.14 AM


Boot Kubernetes master OS image using hyperkit on macOS:



This will display the following output:

Screen Shot 2017-05-11 at 8.50.11 AM

Just wait for few seconds and you will see LinuxKit OS coming up as shown:

Screen Shot 2017-05-11 at 8.52.58 AM


It’s easy to retrieve the IP address of the master node:


Screen Shot 2017-05-11 at 8.54.17 AM


Verify the kubelet process:

Screen Shot 2017-05-11 at 8.55.15 AM

Now it’s time to execute the script to manually initialize master with kubeadm:

/ # runc exec kubelet kubeadm-init.sh


Screen Shot 2017-05-11 at 8.56.48 AM


Copy / Save  the below command  and keep it handy. We are going to need it soon.

kubeadm join --token a5365b.45e88229a1548bf2


Hence, your Kubernetes master is up and ready.

You can verify the cluster node:

Screen Shot 2017-05-11 at 8.57.48 AM

This was so easy to setup. Isn’t it? Let us create 3 node cluster directly from macOS terminal. Open up 3 new separate terminal to start 3 nodes  and run the below commands:


 ajeetraina$cd linuxkit/projects/kubernetes/
 ajeetraina$ sudo ./boot-node.sh 1 --token a5365b.45e88229a1548bf2
 ajeetraina$ sudo ./boot-node.sh 2 --token a5365b.45e88229a1548bf2
 ajeetraina$ sudo ./boot-node.sh 3 --token a5365b.45e88229a1548bf2

Open up the master node terminal and verify if all the 3 nodes gets added:


/ # kubectl get nodes
NAME                STATUS    AGE       VERSION
moby-025000000003   Ready     18m       v1.6.1
moby-025000000004   Ready     13m       v1.6.1
moby-025000000004   Ready     15m       v1.6.1
 moby-025000000004   Ready     14m       v1.6.1


Screen Shot 2017-05-11 at 9.06.28 AM

Moby makes it so simple to setup Kubernetes cluster up and running. Under this demonstration, it created a bridge network inside VPNKit and hosts are added to that as they use the same VPNKit socket.

Thanks to Justin Cormack @ LinuxKit maintainer for the valuable insight regarding the multi-host networking functionality.



Did you find this blog helpful? Are you planning to explore Moby for Kubernetes? 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.

Track The Moby Project here.

Demystifying the Relationship Between Moby & Docker

Estimated Reading Time: 5 minutes

Why https://github.com/docker/docker been redirected to moby/moby?  Why Docker created the Moby project? Is Docker renamed to Moby? What it actually mean when we say Moby is going to be upstream project? – I have been reading a lot of such queries in twitter and open forums even after dozens of blogs are available to clarify the confusion. Still confused about the relationship between Moby  and Docker? –  Under this blog, I will try to clarify the relationship between “the Moby project” & “Docker product” through popular existing analogy -Fedora, RHEL & CentOS.



                   ** the only difference it holds is of Docker CE which comes before Docker EE as compared to RHEL which comes before CentOS.

Fedora is an operating system based on Linux kernel and GNU programs. It is purely a community driven project and sponsored by Red Hat. With an estimation of over 1.2 million users,  it is actually a playground for new functionality as it primarily  focus on quick releases of new features. Red Hat Enterprise Linux branches its releases from versions of Fedora. The key reason of birth of Fedora Linux was that Fedora’s repository development would be collaborative with the global volunteer community. Fedora Linux was eventually absorbed into the Fedora Project, carrying with it this collaborative approach.

RHEL (Red Hat Enteprise Linux) is  a Linux distribution developed and run by Red Hat and targeted toward the commercial market. RHEL is a downstream product and based on Fedora. 

CentOS  is very close to being RHEL without the branding and support. It is a spinoff of RHEL. It is based on the same code base.  Again, it is a community driven and a downstream product.

Let us consider this analogy and try to understand the relationship between Moby, Docker Community Edition & Docker Enterprise Edition.

 ” Moby is a project & Docker is a product”



A Birth of Moby Project – Why?

In the last 2 years, Docker experienced exponential growth . With around 6 billions Docker images pull (compared to 100 million two years back) and thousands of contributors being added month after month, Docker project saw tremendous community engagement. With such exponentially growing community, the boundaries between community and product started to look “blur” as the community was confused if they are contributing to product or the project. To bring the clarification around this debate, Docker finally decided to break its monolithic model into smaller open source components(includes containerd, libnetwork, swarmkit and LinuxKit) and hence the birth of Moby project.

As an analogy, think of Moby as community-driven Fedora project. Moby is an open-source project created by Docker to advance the software containerization movement. It is an upstream project  & perfectly a place for all container enthusiasts to experiment and exchange ideas. As Solomon rightly said “Docker uses the Moby Project as an open R&D lab”.





Think of Docker Community Edition (CE) as CentOS product. As it name suggest, it will again be community-driven, free to use and distribute. Docker CE, as a product, is is ideal for developers and small teams looking to get started with Docker and experimenting with container-based apps. Docker CE is integrated and optimized to the infrastructure so you can maintain a native app experience while getting started with Docker. Build the first container, share with team members and automate the dev pipeline, all with Docker Community Edition.

Docker Enterprise Edition(EE) would be a good analogy to RHEL. It is based on Docker CE and hence, a downstream product. It is officially driven by Docker Inc.

Moby Vs Docker – Q/A

Que:1 > Why docker/docker renamed to moby/moby?

Docker is transitioning all of its open source collaborations to the Moby project going forward and hence it is getting redirected. Docker the product will be assembled from components that are packaged by the Moby project. As the Docker Engine continues to be split up into more components the Moby project will also be the home for those components until a more appropriate location is found.

Que:2 > What is Docker – a project or a product?

Docker is, and will remain, an open source product that lets you build, ship and run containers. It is staying exactly the same from a user’s perspective. Users can download Docker from the docker.com website.

Que:3 > To  what set of users Moby is NOT recommended?

Moby is NOT recommended for application developers looking for an easy way to run their applications in containers.(use Docker CE instead), to enterprise IT and development teams looking for a ready-to-use, commercially supported container platform.(use Docker EE instead) & to anyone curious about containers and looking for an easy way to learn.(use docker.com website instead).

Que:4 > To what set of users Moby is recommended?

Moby is recommended for anyone who wants to assemble a container-based system. This includes hackers, system engineers, infrastructure provides, container enthusiast, open source developers etc.

Que:5 > Will Moby be community-driven going forward?

Yes, of-course. Just like other open source projects, the Moby Project will always be a community-run project. Docker Inc. might plan to donate it to Linux Foundation hopefully.(similar to what they did it for containerd – donated to CNCF).

Que:6 > What is Moby project made up of?

All Moby components are containers, so creating new components is as easy as building a new OCI-compatible container. However, at the core of Moby is a framework to assemble specialized container systems. It provides:

  • A library of containerized components for all vital aspects of a container system: OS, container runtime, orchestration, infrastructure management, networking, storage, security, build, image distribution, etc.
  • Tools to assemble the components into runnable artifacts for a variety of platforms and architectures: bare metal (both x86 and Arm); executables for Linux, Mac and Windows; VM images for popular cloud and virtualization providers.
  • A set of reference assemblies which can be used as-is, modified, or used as inspiration to create your own.

Que:7 > Does Moby uses containerd?

Yes, you are right. Moby uses containerd as the default container runtime.

Que:8 > What does Moby tool do? How is it related to LinuxKit?

The Moby project provides a command-line tool called moby which assembles components. Currently it assembles bootable OS images, but soon it will also be used by Docker for assembling Docker out of components, many of which will be independent projects.

If Moby is used to build ISO images, LinuxKit takes a charge of pushing it and running on diversified platforms.

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

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

Track The Moby Project @ https://github.com/moby/moby


Test-Drive LinuxKit OS on Oracle VirtualBox running on macOS Sierra

Estimated Reading Time: 4 minutes

In my last blog post, I showed how to get started with LinuxKit for Google Cloud Platform. LinuxKit is secure, lean and portable Linux Subsystem for the container movement and it is being built for various platforms which Docker runs on, for example – Azure, VMware ESXi, AWS and bare metal system. It went open source just 10 days back and you can see that the project has received over 2300+ stars in just 1 week time. That’s really appreciating figure. If you are completely new to LinuxKit, please refer my last blog post for understanding its basic concept.



Screen Shot 2017-05-01 at 2.46.43 PM


Under this blog post, I will show you how LinuxKit OS can be run over VirtualBox running on macOS Sierra. Though the entire steps can be automated( this automation script works well for Ubuntu OS and can be tweaked for macOS), I have put it in simpler way.


Ensure that  the following list of software are installed on your macOS machine:

  • go packages  from https://golang.org/dl/
  • make (using Xcode-select –install)
  • docker Version 17.03.1-ce-mac5 (16048) Channel: stable
  • VirtualBox software installed on macOS Sierra
  • git binary, if not installed


Once you have installed the above  packages, verify that they are all up and running. Ensure that Docker is up and running. Let us begin by cloning the LinuxKit repository. Open up the terminal and type the below command:


Ajeets-MacBook-Air:~ ajeetraina$ sudo git clone https://github.com/linuxkit/linuxkit

Cloning into ‘linuxkit’…

remote: Counting objects: 20097, done.

remote: Compressing objects: 100% (14/14), done.

remote: Total 20097 (delta 1), reused 0 (delta 0), pack-reused 20082

Receiving objects: 100% (20097/20097), 15.76 MiB | 441.00 KiB/s, done.

Resolving deltas: 100% (12066/12066), done.

Ajeets-MacBook-Air:~ ajeetraina$


Building the Image:


$cd linuxkit

$ sudo make


This build up two essential tools for us – moby and linuxkit.  

Next, we need to copy these tools to our PATH as shown below:


$ sudo cp bin/* /usr/local/bin


Now it’s time to use Moby to build the image:

$ sudo moby build examples/vmware.yml


Screen Shot 2017-05-01 at 3.07.17 PM


Hence, moby builds up VMware.vmdk file. To push it to VirtualBox, one can think of various option. If you are completely new to VirtualBox, all you can do is import the VMDK file directly as shown below:

Importing  VMDK into VirtualBox software directly:


Screen Shot 2017-05-01 at 3.19.12 PM


Type your preferable name under VM name(I named it as LinuxKitOS) and select VMware.vmk from your macOS to import it into VirtualBox. Click on “Create”.

Next, you can start the VM by clicking on “Start” button.


Screen Shot 2017-05-01 at 3.19.35 PM

It hardly takes few seconds for LinuxKit OS to come up. Once up, you can run runc command to see the list of services up and running.



The other option is to covert .VMDK into .VDI format and registering the VM using VBoxManage command as shown below:

$VBoxManage clonehd –format VDI vmware.vmdk vmware.vdi


Screen Shot 2017-05-01 at 3.37.38 PM

The above command converts VMDK to VDI format which is now ready to be imported into VirtualBox.

Though LinuxKit comes with QEMU tool, if you still want to use qemu-img  (2 step process) to extract only virtual disk and not complete VM, this is a way to do it as shown below:

 $brew install qemu --env=std --use-gcc

Run the below command to convert VMDK to VDI using qemu:

Ajeets-MacBook-Air$ sudo qemu-img convert vmware.vmdk swap.bin -p



Ajeets-MacBook-Air:examples ajeetraina$ sudo VBoxManage convertfromraw swap.bin output.vdi –format VDI

Converting from raw image file=”swap.bin” to file=”output.vdi”…

Creating dynamic image with size 1073741824 bytes (1024MB)…


Still I would love to see LinuxKit providing the direct way of importing it into VirtualBox , the similar way how it pushes to Google Cloud Platform. LinuxKit for AWS and Azure is under progress. In the future blog post, I will try to cover how LinuxKit works on other platform like Azure and AWS.

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

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

LinuxKit 101: Getting Started with LinuxKit for Google Cloud Platform

Estimated Reading Time: 7 minutes


“…LinuxKit? A New Beast?

     What problem does it solve for us?..”



In case you missed out Dockercon 2017 and have no idea what is LinuxKit all about, then you have arrived at the right place. For the next 30 minutes of your time, I will be talking about an open source container toolkit which Docker Inc. has recently made to the public & will help you get started with it in very easy and precise way.

What is LinuxKit?

LinuxKit is just like Docker’s other open-source container toolkits such as InfraKit and VPNkit. It is essentially a container-native toolkit that allows organizations to build their own containerized operating systems that are secure, lean, modular and portable. Essentially, it is more of a developer kit than an end-user product.This project is completely open source and  is hosted on GitHub, under an Apache 2 licence.

What problem does it solve?

Last year Docker Inc. started shipping Docker for Mac, Docker for Windows, Docker for Azure & Docker for GCP and that brought a Docker-native experience to these various platforms. One of the common problem which the community faced was non-standard Linux OS running on all those platform.  Esp. Cloud platform do not ship with a standard Linux which brought lots of concerns around portability, security and  incompatibility. This lead Docker Inc. to bundle Linux into the Docker platform to run on all of these places uniformly.

Talking about portability, Docker Inc. has always focused on product which should run anywhere. Hence, they worked with partners like HP, Intel, ARM and Microsoft to ensure that LinuxKit toolkit should flawlessly run on the desktop, server, cloud ARM, x86, virtual environment and on bare metal. LinuxKit was built with an intention of  an optimized tooling for portability which can accommodate a new architecture, a new system in very easier way.

What does LinuxKit hold?

LinuxKit includes the tooling to allow building custom Linux subsystems that only include exactly the components the runtime platform requires. All system services are containers that can be replaced, and everything that is not required can be removed.The toolkit works with Docker’s containerd. All components can be substituted with ones that match specific needs.You can optimize LinuxKit images for specific hardware platforms and host operating systems with just the drivers and other dependencies you need, and nothing more, rather than use a full-fat generic base. The toolkit basically tries to help you create your own slimline containerized operating system as painlessly as possible. The size of a LinuxKit image is in MBs ( around 35-50MB).


The above shown is YAML file which specifies a kernel and base init system, a set of containers that are built into the generated image and started at boot time. It also specifies what formats to output(shown at the last line), such as bootable ISOs and images for various platforms. Interestingly, system services are sandboxed in containers, with only the privileges they need. The configuration is designed for the container use case. The whole system is built to be used as immutable infrastructure, so it can be built and tested in your CI pipeline, deployed, and new versions are redeployed when you wish to upgrade. To know more about YAML specification, check this out.

What tool does LinuxKit uses?

There are two basic tools which LinuxKit uses – Linuxkit & Moby.


In short, the moby tool converts the yaml specification into one or more bootable images.

Let us get started with LinuxKit to understand how it builds customized ISO images and run uniformly across various platform. Under this blog post, I have chosen Google Cloud Platform. We will build LinuxKit based customized ISO image locally on my Macbook Air and push it to Google Cloud Platform to run as VM instance. I will be using forked linuxkit repository which I have built around and runs Docker container(ex. running Portainer docker container) inside VM instance too.


  1. Install LinuxKit & Moby tool on macOS
  2. Building a LinuxKit ISO Image with Moby 
  3. Create a bucket under Google Cloud Platform
  4. Upload the LinuxKit ISO image to a GCP bucket using LinuxKit tool
  5. Initiate the GCP instance from the LinuxKit ISO image placed under GCP bucket
  6. Verifying Docker running inside LinuxKitOS 
  7. Running Portainer as Docker container



– Install Google Cloud SDK on your macOS system through this link. You will need to verify your google account using the below command:

$gcloud auth login

– Ensure that the build essential tools like make are perfectly working

– Ensure that GO packages are installed on macOS..


  1. Clone the repository:


sudo git clone https://github.com/ajeetraina/linuxkit


2.  Change directory to linuxkit and run make which builds “moby” and “linuxkit” for us

cd linuxkit && sudo make


3.  Verify that these tools are built and placed under /bin:

cd bin/
moby         linuxkit

4.  Copy these tools into system PATH:

sudo cp bin/* /usr/local/bin/

5. Use moby tool to build the customized ISO image:


cd examples/
sudo moby build gcpwithdocker.yml




[Update: 6/21/2017 – With the latest release of LinuxKit, Output section is no longer allowed inside YAML file. It means that whenever you use moby build command to build an image, specify -output gcp to build an image in a format that GCP will understand. For example:

moby build -output gcp example/gcpwithdocker.yml

This will create a local gcpwithdocker.img.tar.gz compressed image file.]


6.  Create a GCE bucket “mygcp” under your Google Cloud Platform:


7. Run  linuxkit push command  to push it to GCP:


sudo linuxkit push gcp -project synthetic-diode-161714 -bucket mygcp gcpwithdocker.img.tar.gz



[Note: “synthetic-diode-161714” is my GCP project name and “mygcp” is the bucket name which I created in earlier step. Please input as per your environment.]

Please note that you might need to enable Google Cloud API using this link in case you encounter “unable to connect GCP”  error. 

8.  You can execute the image you created and this will should show up under VM instance on Google  Cloud Platform:



This will build up a LinuxKit OS which you can verify below:


You can also verify if this brings up VM instance on GCP platform:


9. You can use runc command to list out all the services which were defined under gcpwithdocker.yml file:


10. As shown above, one of the service which I am interested is called “docker”. You can use the below command to enter into docker service:


runc exec -t docker sh

Wow ! It is running the latest Docker 17.04.0-ce version.

11.  Let us try to run Portainer application and check if it works good.


You can verify the IP address running ifconfig for that specific container which in my case is


Now this is what I call ” a coolest stuff on earth”. Linuxkit allows you to build your own secure, modular, portable, lean and mean containerized OS and that too in just minutes. I am currently exploring LinuxKit in terms of bare metal OS and will share it under my next blog post.

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

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