From 00e76c1572fcc85275a2cfd2565fc760f171e311 Mon Sep 17 00:00:00 2001
From: Pete Birley <pete@port.direct>
Date: Wed, 12 Apr 2017 14:18:51 -0500
Subject: [PATCH] Kubeadm-aio container for dev and gates

This PS brings in a container for setting up a Kubeadm based
AIO environement for development and Gating purposes.

Change-Id: Ice96b03b519a380d4679d701e4bbb97024bb2fb5
---
 tools/kubeadm-aio/Dockerfile                  | 69 ++++++++++++++++
 tools/kubeadm-aio/README.md                   | 63 +++++++++++++++
 tools/kubeadm-aio/assets/etc/kube-version     |  3 +
 tools/kubeadm-aio/assets/etc/kubeapi-device   |  3 +
 .../kubeadm-aio/assets/etc/kubelet-container  |  3 +
 tools/kubeadm-aio/assets/kubeadm-aio          | 37 +++++++++
 .../opt/nfs-provisioner/deployment.yaml       | 72 +++++++++++++++++
 .../opt/nfs-provisioner/storageclass.yaml     |  5 ++
 tools/kubeadm-aio/assets/opt/rbac/dev.yaml    | 15 ++++
 tools/kubeadm-aio/assets/usr/bin/kubeadm-aio  | 48 +++++++++++
 tools/kubeadm-aio/assets/usr/bin/kubelet      | 60 ++++++++++++++
 .../usr/bin/openstack-helm-aio-network-prep   | 22 +++++
 .../assets/usr/bin/openstack-helm-demo-prep   | 34 ++++++++
 .../assets/usr/bin/openstack-helm-dev-prep    | 28 +++++++
 .../assets/usr/bin/openstack-helm-nfs-prep    | 22 +++++
 .../lib/systemd/system/container-up.target    | 20 +++++
 .../lib/systemd/system/kubeadm-aio.service    | 26 ++++++
 tools/kubeadm-aio/kubeadm-aio-launcher.sh     | 80 +++++++++++++++++++
 18 files changed, 610 insertions(+)
 create mode 100644 tools/kubeadm-aio/Dockerfile
 create mode 100644 tools/kubeadm-aio/README.md
 create mode 100644 tools/kubeadm-aio/assets/etc/kube-version
 create mode 100644 tools/kubeadm-aio/assets/etc/kubeapi-device
 create mode 100644 tools/kubeadm-aio/assets/etc/kubelet-container
 create mode 100755 tools/kubeadm-aio/assets/kubeadm-aio
 create mode 100644 tools/kubeadm-aio/assets/opt/nfs-provisioner/deployment.yaml
 create mode 100644 tools/kubeadm-aio/assets/opt/nfs-provisioner/storageclass.yaml
 create mode 100644 tools/kubeadm-aio/assets/opt/rbac/dev.yaml
 create mode 100755 tools/kubeadm-aio/assets/usr/bin/kubeadm-aio
 create mode 100755 tools/kubeadm-aio/assets/usr/bin/kubelet
 create mode 100755 tools/kubeadm-aio/assets/usr/bin/openstack-helm-aio-network-prep
 create mode 100755 tools/kubeadm-aio/assets/usr/bin/openstack-helm-demo-prep
 create mode 100755 tools/kubeadm-aio/assets/usr/bin/openstack-helm-dev-prep
 create mode 100755 tools/kubeadm-aio/assets/usr/bin/openstack-helm-nfs-prep
 create mode 100644 tools/kubeadm-aio/assets/usr/lib/systemd/system/container-up.target
 create mode 100644 tools/kubeadm-aio/assets/usr/lib/systemd/system/kubeadm-aio.service
 create mode 100755 tools/kubeadm-aio/kubeadm-aio-launcher.sh

diff --git a/tools/kubeadm-aio/Dockerfile b/tools/kubeadm-aio/Dockerfile
new file mode 100644
index 0000000000..aab4c33f36
--- /dev/null
+++ b/tools/kubeadm-aio/Dockerfile
@@ -0,0 +1,69 @@
+FROM ubuntu:16.04
+MAINTAINER pete.birley@att.com
+
+ARG HELM_VERSION=v2.3.0
+
+ENV container="docker" \
+    DEBIAN_FRONTEND="noninteractive"
+
+RUN set -x \
+    && cd /tmp \
+    && apt-get update \
+    && apt-get install -y \
+        apt-transport-https \
+        ca-certificates \
+        curl \
+# Add Kubernetes repo
+    && curl -sSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - \
+    && echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" > /etc/apt/sources.list.d/kubernetes.list \
+    && apt-get update \
+    && apt-get install -y \
+        docker.io \
+        iptables \
+        kubectl \
+        kubelet \
+        kubernetes-cni \
+# Install Kubeadm without running postinstall script as it expects systemd to be running.
+    && apt-get download kubeadm \
+    && dpkg --unpack kubeadm*.deb \
+    && mv /var/lib/dpkg/info/kubeadm.postinst /opt/kubeadm.postinst \
+    && dpkg --configure kubeadm \
+    && apt-get install -yf kubeadm \
+    && mkdir -p /etc/kubernetes/manifests \
+# Move kubelet binary as we will run containerised
+    && mv /usr/bin/kubelet /usr/bin/kubelet-real \
+# Install helm binary
+    && curl -sSL https://storage.googleapis.com/kubernetes-helm/helm-${HELM_VERSION}-linux-amd64.tar.gz | tar -zxv --strip-components=1 \
+    && mv /tmp/helm /usr/bin/helm \
+# Install openstack-helm dev utils
+    && apt-get install -y \
+        make \
+        git \
+        vim \
+# Install nfs utils for development PVC provisioner
+        nfs-common \
+# Tweak Systemd units and targets for running in a container
+    && find /lib/systemd/system/sysinit.target.wants/ ! -name 'systemd-tmpfiles-setup.service' -type l -exec rm -fv {} + \
+    && rm -fv \
+        /lib/systemd/system/multi-user.target.wants/* \
+        /etc/systemd/system/*.wants/* \
+        /lib/systemd/system/local-fs.target.wants/* \
+        /lib/systemd/system/sockets.target.wants/*udev* \
+        /lib/systemd/system/sockets.target.wants/*initctl* \
+        /lib/systemd/system/basic.target.wants/* \
+# Clean up apt cache
+    && rm -rf /var/lib/apt/lists/* \
+# Clean up tmp dir
+    && cd / \
+    && rm -rf /tmp/*
+
+# Load assets into place, setup startup target & units
+COPY ./assets/ /
+RUN set -x \
+    && ln -s /usr/lib/systemd/system/container-up.target /etc/systemd/system/default.target \
+    && mkdir -p /etc/systemd/system/container-up.target.wants \
+    && ln -s /usr/lib/systemd/system/kubeadm-aio.service /etc/systemd/system/container-up.target.wants/kubeadm-aio.service
+
+VOLUME /sys/fs/cgroup
+
+CMD /kubeadm-aio
diff --git a/tools/kubeadm-aio/README.md b/tools/kubeadm-aio/README.md
new file mode 100644
index 0000000000..f4822bcc0f
--- /dev/null
+++ b/tools/kubeadm-aio/README.md
@@ -0,0 +1,63 @@
+# Kubeadm AIO Container
+
+This container builds a small AIO Kubeadm based Kubernetes deployment for Development and Gating use.
+
+## Instructions
+
+### OS Specific Host setup:
+
+#### Ubuntu:
+
+From a freshly provisioned Ubuntu 16.04 LTS host run:
+``` bash
+sudo apt-get update -y
+sudo apt-get install -y \
+        docker.io \
+        nfs-common
+```
+
+### Build and deploy the AIO environment
+
+From the root directory of the OpenStack-Helm repo run:
+
+``` bash
+export KUBEADM_IMAGE=openstack-helm/kubeadm-aio:v1.6
+sudo docker build --pull -t ${KUBEADM_IMAGE} tools/kubeadm-aio
+```
+
+To launch the environment then run:
+
+``` bash
+export KUBEADM_IMAGE=openstack-helm/kubeadm-aio:v1.6
+export KUBE_VERSION=v1.6.0
+./tools/kubeadm-aio/kubeadm-aio-launcher.sh
+export KUBECONFIG=${HOME}/.kubeadm-aio/admin.conf
+```
+
+One this has run, you should hopefully have a Kubernetes single node environment
+running, with Helm, Calico, a NFS PVC provisioner and appropriate RBAC rules and
+node labels to get developing.
+
+If you wish to use this environment at the primary Kubernetes environment on
+your host you may run the following, but note that this will wipe any previous
+client configuration you may have.
+
+``` bash
+mkdir -p  ${HOME}/.kube
+cat ${HOME}/.kubeadm-aio/admin.conf > ${HOME}/.kube/config
+```
+
+If you wish to create dummy network devices for Neutron to manage there is a
+helper script that can set them up for you:
+
+``` bash
+sudo docker exec kubelet /usr/bin/openstack-helm-aio-network-prep
+```
+
+### Logs
+
+You can get the logs from your `kubeadm-aio` container by running:
+
+``` bash
+sudo docker logs -f kubeadm-aio
+```
diff --git a/tools/kubeadm-aio/assets/etc/kube-version b/tools/kubeadm-aio/assets/etc/kube-version
new file mode 100644
index 0000000000..a353de8bdd
--- /dev/null
+++ b/tools/kubeadm-aio/assets/etc/kube-version
@@ -0,0 +1,3 @@
+# If KUBE_VERSION is set 'default' kubeadm will use the default version of K8s
+# otherwise the version specified here will be used.
+KUBE_VERSION=default
diff --git a/tools/kubeadm-aio/assets/etc/kubeapi-device b/tools/kubeadm-aio/assets/etc/kubeapi-device
new file mode 100644
index 0000000000..a9118c4cdd
--- /dev/null
+++ b/tools/kubeadm-aio/assets/etc/kubeapi-device
@@ -0,0 +1,3 @@
+# If KUBE_BIND_DEV is set to 'autodetect' we will use kubeadm's autodetect logic
+# otherwise use the device specified to find the IP address to bind to.
+KUBE_BIND_DEV=autodetect
diff --git a/tools/kubeadm-aio/assets/etc/kubelet-container b/tools/kubeadm-aio/assets/etc/kubelet-container
new file mode 100644
index 0000000000..557545e4e9
--- /dev/null
+++ b/tools/kubeadm-aio/assets/etc/kubelet-container
@@ -0,0 +1,3 @@
+# If KUBELET_CONTAINER is set 'to_this' one we will not attempt to launch a new
+# container for the kubelet process, otherwise use the image tag specified
+KUBELET_CONTAINER=this_one
diff --git a/tools/kubeadm-aio/assets/kubeadm-aio b/tools/kubeadm-aio/assets/kubeadm-aio
new file mode 100755
index 0000000000..304caa24fa
--- /dev/null
+++ b/tools/kubeadm-aio/assets/kubeadm-aio
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+# Copyright 2017 The Openstack-Helm Authors.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+set -xe
+
+echo "Checking cgroups"
+if ls -dZ /sys/fs/cgroup | grep -q :svirt_sandbox_file_t: ; then
+  echo "Invocation error: use -v /sys/fs/cgroup:/sys/fs/cgroup:ro parameter to docker run."
+  exit 1
+fi
+
+echo "Setting up K8s version to deploy"
+: ${KUBE_VERSION:="default"}
+sed -i "s|KUBE_VERSION=.*|KUBE_VERSION=${KUBE_VERSION}|g" /etc/kube-version
+
+echo "Setting up device image to use for kube-api"
+: ${KUBE_BIND_DEV:="autodetect"}
+sed -i "s|KUBE_BIND_DEV=.*|KUBE_BIND_DEV=${KUBE_BIND_DEV}|g" /etc/kubeapi-device
+
+echo "Setting up container image to use for kubelet"
+: ${KUBELET_CONTAINER:="this_one"}
+sed -i "s|KUBELET_CONTAINER=.*|KUBELET_CONTAINER=${KUBELET_CONTAINER}|g" /etc/kubelet-container
+
+echo "Starting Systemd"
+exec /bin/systemd --system
diff --git a/tools/kubeadm-aio/assets/opt/nfs-provisioner/deployment.yaml b/tools/kubeadm-aio/assets/opt/nfs-provisioner/deployment.yaml
new file mode 100644
index 0000000000..e13f7a441b
--- /dev/null
+++ b/tools/kubeadm-aio/assets/opt/nfs-provisioner/deployment.yaml
@@ -0,0 +1,72 @@
+kind: Service
+apiVersion: v1
+metadata:
+  name: nfs-provisioner
+  labels:
+    app: nfs-provisioner
+spec:
+  ports:
+    - name: nfs
+      port: 2049
+    - name: mountd
+      port: 20048
+    - name: rpcbind
+      port: 111
+    - name: rpcbind-udp
+      port: 111
+      protocol: UDP
+  selector:
+    app: nfs-provisioner
+---
+kind: Deployment
+apiVersion: extensions/v1beta1
+metadata:
+  name: nfs-provisioner
+spec:
+  replicas: 1
+  strategy:
+    type: Recreate
+  template:
+    metadata:
+      labels:
+        app: nfs-provisioner
+    spec:
+      containers:
+        - name: nfs-provisioner
+          image: quay.io/kubernetes_incubator/nfs-provisioner:v1.0.3
+          ports:
+            - name: nfs
+              containerPort: 2049
+            - name: mountd
+              containerPort: 20048
+            - name: rpcbind
+              containerPort: 111
+            - name: rpcbind-udp
+              containerPort: 111
+              protocol: UDP
+          securityContext:
+            capabilities:
+              add:
+                - DAC_READ_SEARCH
+          args:
+            - "-provisioner=example.com/nfs"
+            - "-grace-period=10"
+          env:
+            - name: POD_IP
+              valueFrom:
+                fieldRef:
+                  fieldPath: status.podIP
+            - name: SERVICE_NAME
+              value: nfs-provisioner
+            - name: POD_NAMESPACE
+              valueFrom:
+                fieldRef:
+                  fieldPath: metadata.namespace
+          imagePullPolicy: "IfNotPresent"
+          volumeMounts:
+            - name: export-volume
+              mountPath: /export
+      volumes:
+        - name: export-volume
+          hostPath:
+            path: /var/lib/nfs-provisioner
diff --git a/tools/kubeadm-aio/assets/opt/nfs-provisioner/storageclass.yaml b/tools/kubeadm-aio/assets/opt/nfs-provisioner/storageclass.yaml
new file mode 100644
index 0000000000..35a297f148
--- /dev/null
+++ b/tools/kubeadm-aio/assets/opt/nfs-provisioner/storageclass.yaml
@@ -0,0 +1,5 @@
+kind: StorageClass
+apiVersion: storage.k8s.io/v1
+metadata:
+  name: general
+provisioner: example.com/nfs
diff --git a/tools/kubeadm-aio/assets/opt/rbac/dev.yaml b/tools/kubeadm-aio/assets/opt/rbac/dev.yaml
new file mode 100644
index 0000000000..77b5313c48
--- /dev/null
+++ b/tools/kubeadm-aio/assets/opt/rbac/dev.yaml
@@ -0,0 +1,15 @@
+apiVersion: rbac.authorization.k8s.io/v1alpha1
+kind: ClusterRoleBinding
+metadata:
+  name: cluster-admin
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: cluster-admin
+subjects:
+- kind: Group
+  name: system:masters
+- kind: Group
+  name: system:authenticated
+- kind: Group
+  name: system:unauthenticated
diff --git a/tools/kubeadm-aio/assets/usr/bin/kubeadm-aio b/tools/kubeadm-aio/assets/usr/bin/kubeadm-aio
new file mode 100755
index 0000000000..58d0f6eda6
--- /dev/null
+++ b/tools/kubeadm-aio/assets/usr/bin/kubeadm-aio
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+# Copyright 2017 The Openstack-Helm Authors.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+set -xe
+
+# Define k8s version
+source /etc/kube-version
+if [[ "${KUBE_VERSION}" == "default" ]]; then
+  KUBE_VERSION_FLAG=""
+else
+  KUBE_VERSION_FLAG="--kubernetes-version=${KUBE_VERSION}"
+  echo "We will use K8s ${KUBE_VERSION}"
+fi
+
+echo "Setting up K8s"
+source /etc/kubeapi-device
+if [[ "$KUBE_BIND_DEV" != "autodetect" ]]; then
+  KUBE_BIND_IP=$(ip addr list ${KUBE_BIND_DEV} |grep "inet " |cut -d' ' -f6|cut -d/ -f1)
+  echo "We are going to bind the K8s API to: ${KUBE_BIND_IP}"
+  kubeadm init --skip-preflight-checks ${KUBE_VERSION_FLAG} --api-advertise-addresses ${KUBE_BIND_IP}
+else
+  kubeadm init --skip-preflight-checks ${KUBE_VERSION_FLAG}
+fi
+
+echo "Setting up K8s client"
+cp /etc/kubernetes/admin.conf /root/
+export KUBECONFIG=/root/admin.conf
+
+echo "Marking master node as sceduleable"
+kubectl taint nodes --all node-role.kubernetes.io/master-
+
+echo "Installing Calico CNI"
+kubectl create -f http://docs.projectcalico.org/v2.1/getting-started/kubernetes/installation/hosted/kubeadm/1.6/calico.yaml
+
+echo "Setting Up Cluser for OpenStack-Helm dev use"
+/usr/bin/openstack-helm-dev-prep
diff --git a/tools/kubeadm-aio/assets/usr/bin/kubelet b/tools/kubeadm-aio/assets/usr/bin/kubelet
new file mode 100755
index 0000000000..f40a821985
--- /dev/null
+++ b/tools/kubeadm-aio/assets/usr/bin/kubelet
@@ -0,0 +1,60 @@
+#!/bin/bash
+
+# Copyright 2017 The Openstack-Helm Authors.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+set -xe
+
+# Set the KUBELET_CONTAINER env var
+source /etc/kubelet-container
+
+# Detrmine the Cgroup driver in use by Docker
+CGROUP_DRIVER=$(docker info | awk '/^Cgroup Driver:/ { print $NF }')
+
+if [[ "${KUBELET_CONTAINER}" == "this_one" ]]; then
+  exec kubelet-real \
+        --containerized=true \
+        --enable-cri=false \
+        --cgroup-driver=${CGROUP_DRIVER} "${@}"
+else
+  # Lets remove any old containers
+  docker rm -f kubelet || true
+
+  # Launch the container
+  exec docker run \
+        --name kubelet \
+        --restart=always \
+        --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro \
+        --volume=/:/rootfs:ro \
+        --volume=/dev/net:/dev/net:rw \
+        --volume=/var/run/netns:/var/run/netns:rw \
+        --volume=/sys:/sys:ro \
+        --volume=/etc/machine-id:/etc/machine-id:ro \
+        --volume=/opt/cni:/opt/cni:rw \
+        --volume=/etc/cni/net.d:/etc/cni/net.d:rw \
+        --volume=/var/lib/docker/:/var/lib/docker:rw \
+        --volume=/var/lib/kubelet/:/var/lib/kubelet:rshared \
+        --volume=/var/run:/var/run:rw \
+        --volume=/etc/kubernetes:/etc/kubernetes:rw \
+        --volume=/etc/hosts:/etc/hosts:rw \
+        --volume=/etc/resolv.conf:/etc/resolv.conf:rw \
+        --net=host \
+        --privileged=true \
+        --pid=host \
+        --ipc=host \
+        ${KUBELET_CONTAINER} \
+          kubelet \
+            --containerized=true \
+            --enable-cri=false \
+            --cgroup-driver=${CGROUP_DRIVER} "${@}"
+fi
diff --git a/tools/kubeadm-aio/assets/usr/bin/openstack-helm-aio-network-prep b/tools/kubeadm-aio/assets/usr/bin/openstack-helm-aio-network-prep
new file mode 100755
index 0000000000..e6d1c290ba
--- /dev/null
+++ b/tools/kubeadm-aio/assets/usr/bin/openstack-helm-aio-network-prep
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+# Copyright 2017 The Openstack-Helm Authors.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+set -xe
+
+echo "Setting up virtual network devices"
+ip link add neutron-ext type dummy || true
+ip link set neutron-ext up
+ip link add neutron-phys type dummy || true
+ip link set neutron-phys up
diff --git a/tools/kubeadm-aio/assets/usr/bin/openstack-helm-demo-prep b/tools/kubeadm-aio/assets/usr/bin/openstack-helm-demo-prep
new file mode 100755
index 0000000000..e18fb62aeb
--- /dev/null
+++ b/tools/kubeadm-aio/assets/usr/bin/openstack-helm-demo-prep
@@ -0,0 +1,34 @@
+#!/bin/bash
+
+# Copyright 2017 The Openstack-Helm Authors.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+set -xe
+
+echo "Setting Kubecfg Location"
+export KUBECONFIG=/root/admin.conf
+
+echo "Cloning OpenStack-Helm"
+git clone --depth 1 https://github.com/openstack/openstack-helm.git /opt/openstack-helm
+
+echo "Starting helm local repo"
+helm serve &
+until curl -sSL --connect-timeout 1 http://localhost:8879 > /dev/null; do
+  echo "Waiting for helm serve to start"
+  sleep 2
+done
+helm repo add local http://localhost:8879/charts
+
+echo "Building OpenStack-Helm"
+cd /opt/openstack-helm
+make
diff --git a/tools/kubeadm-aio/assets/usr/bin/openstack-helm-dev-prep b/tools/kubeadm-aio/assets/usr/bin/openstack-helm-dev-prep
new file mode 100755
index 0000000000..5c935a5774
--- /dev/null
+++ b/tools/kubeadm-aio/assets/usr/bin/openstack-helm-dev-prep
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# Copyright 2017 The Openstack-Helm Authors.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+set -xe
+
+echo "Setting Kubecfg Location"
+export KUBECONFIG=/root/admin.conf
+
+echo "Labeling the nodes for Openstack-Helm deployment"
+kubectl label nodes openstack-control-plane=enabled --all --namespace=openstack --overwrite
+kubectl label nodes openvswitch=enabled --all --namespace=openstack --overwrite
+kubectl label nodes openstack-compute-node=enabled --all --namespace=openstack --overwrite
+
+
+echo "RBAC: applying development rules (totally open!)"
+kubectl update -f /opt/rbac/dev.yaml
diff --git a/tools/kubeadm-aio/assets/usr/bin/openstack-helm-nfs-prep b/tools/kubeadm-aio/assets/usr/bin/openstack-helm-nfs-prep
new file mode 100755
index 0000000000..a888a88c2e
--- /dev/null
+++ b/tools/kubeadm-aio/assets/usr/bin/openstack-helm-nfs-prep
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+# Copyright 2017 The Openstack-Helm Authors.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+set -xe
+
+echo "Setting Kubecfg Location"
+export KUBECONFIG=/root/admin.conf
+
+echo "Deploying NFS Provisioner"
+kubectl create -R -f /opt/nfs-provisioner/
diff --git a/tools/kubeadm-aio/assets/usr/lib/systemd/system/container-up.target b/tools/kubeadm-aio/assets/usr/lib/systemd/system/container-up.target
new file mode 100644
index 0000000000..2620c9d708
--- /dev/null
+++ b/tools/kubeadm-aio/assets/usr/lib/systemd/system/container-up.target
@@ -0,0 +1,20 @@
+# Copyright 2017 The Openstack-Helm Authors.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+[Unit]
+Description=Minimal target for containerized applications
+DefaultDependencies=false
+AllowIsolate=yes
+Requires=systemd-tmpfiles-setup.service systemd-journald.service dbus.service
+After=systemd-tmpfiles-setup.service systemd-journald.service dbus.service
diff --git a/tools/kubeadm-aio/assets/usr/lib/systemd/system/kubeadm-aio.service b/tools/kubeadm-aio/assets/usr/lib/systemd/system/kubeadm-aio.service
new file mode 100644
index 0000000000..68dd04d3d1
--- /dev/null
+++ b/tools/kubeadm-aio/assets/usr/lib/systemd/system/kubeadm-aio.service
@@ -0,0 +1,26 @@
+# Copyright 2017 The Openstack-Helm Authors.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+[Unit]
+Description=Start Kubeadm AIO Cluster
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/kubeadm-aio
+FailureAction=poweroff
+StandardOutput=tty
+TimeoutStartSec=0
+
+[Install]
+WantedBy=container-up.target
diff --git a/tools/kubeadm-aio/kubeadm-aio-launcher.sh b/tools/kubeadm-aio/kubeadm-aio-launcher.sh
new file mode 100755
index 0000000000..77f848ecd3
--- /dev/null
+++ b/tools/kubeadm-aio/kubeadm-aio-launcher.sh
@@ -0,0 +1,80 @@
+#!/bin/bash
+
+# Copyright 2017 The Openstack-Helm Authors.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+set -xe
+
+# Setup shared mounts for kubelet
+sudo mkdir -p /var/lib/kubelet
+sudo mount --bind /var/lib/kublet /var/lib/kubelet
+sudo mount --make-shared /var/lib/kubelet
+
+# Cleanup any old deployment
+sudo docker rm -f kubeadm-aio || true
+sudo docker rm -f kubelet || true
+sudo docker ps -aq | xargs -l1 sudo docker rm -f || true
+sudo rm -rfv \
+    /etc/cni/net.d \
+    /etc/kubernetes \
+    /var/lib/etcd \
+    /var/lib/kubelet/* \
+    /run/openvswitch \
+    ${HOME}/.kubeadm-aio/admin.conf \
+    /var/lib/nfs-provisioner || true
+
+# Launch Container
+sudo docker run \
+    -dt \
+    --name=kubeadm-aio \
+    --net=host \
+    --security-opt=seccomp:unconfined \
+    --cap-add=SYS_ADMIN \
+    --tmpfs=/run \
+    --tmpfs=/run/lock \
+    --volume=/etc/machine-id:/etc/machine-id:ro \
+    --volume=${HOME}:${HOME}:rw \
+    --volume=${HOME}/.kubeadm-aio:/root:rw \
+    --volume=/etc/kubernetes:/etc/kubernetes:rw \
+    --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro \
+    --volume=/var/run/docker.sock:/run/docker.sock \
+    --env KUBELET_CONTAINER=${KUBEADM_IMAGE} \
+    --env KUBE_VERSION=${KUBE_VERSION} \
+    ${KUBEADM_IMAGE}
+
+# Wait for kubeconfig
+while [[ ! -f ${HOME}/.kubeadm-aio/admin.conf ]]; do
+  echo "Waiting for kubeconfig"
+  sleep 2
+done
+
+# Set perms of kubeconfig and set env-var
+sudo chown $(id -u):$(id -g) ${HOME}/.kubeadm-aio/admin.conf
+export KUBECONFIG=${HOME}/.kubeadm-aio/admin.conf
+
+# Wait for node to be ready before continuing
+NODE_STATUS="Unknown"
+while [[ $NODE_STATUS != "Ready" ]]; do
+  NODE_STATUS=$(kubectl get nodes --no-headers=true | awk "{ print \$2 }" | head -1)
+  echo "Current node status: ${NODE_STATUS}"
+  sleep 2
+done
+
+# Initialize Helm
+helm init
+
+# Initialize Environment for Development
+sudo docker exec kubeadm-aio openstack-helm-dev-prep
+
+# Deploy NFS provisioner into enviromment
+sudo docker exec kubeadm-aio openstack-helm-nfs-prep