From 6b699689f301a8bb275078fb76a34f7dcb40907a Mon Sep 17 00:00:00 2001
From: mozhulee <21621232@zju.edu.cn>
Date: Tue, 18 Jul 2017 11:02:45 +0800
Subject: [PATCH] Containerize cni network plugin

including
* build cni plugin image
* deploy via kubernetes daemonsets

Change-Id: I9f8c3239aa91c77bfec38728151eeeee5084c20d
Implements: blueprint containerize-cni
Signed-off-by: mozhuli <21621232@zju.edu.cn>
---
 Makefile                                    |  11 +-
 deployment/kubestack/10-kubestack.conf      |   6 +
 deployment/kubestack/Dockerfile             |  12 ++
 deployment/kubestack/install-cni.sh         |  59 ++++++++++
 deployment/kubestack/kubestack.conf.default |  10 ++
 deployment/kubestack/kubestack.yaml         | 115 ++++++++++++++++++++
 6 files changed, 212 insertions(+), 1 deletion(-)
 create mode 100644 deployment/kubestack/10-kubestack.conf
 create mode 100644 deployment/kubestack/Dockerfile
 create mode 100755 deployment/kubestack/install-cni.sh
 create mode 100644 deployment/kubestack/kubestack.conf.default
 create mode 100644 deployment/kubestack/kubestack.yaml

diff --git a/Makefile b/Makefile
index c5c3d88..3ffab48 100644
--- a/Makefile
+++ b/Makefile
@@ -7,6 +7,8 @@
 GIT_HOST = git.openstack.org
 SHELL := /bin/bash
 
+KUBESTACK_VERSION=0.1
+
 PWD := $(shell pwd)
 BASE_DIR := $(shell basename $(PWD))
 # Keep an existing GOPATH, make a private one if it is undefined
@@ -39,13 +41,20 @@ depend-update: work
 build: depend
 	cd $(DEST)
 	go build $(GOFLAGS) -a -o $(OUTPUT)/stackube-controller ./cmd/stackube-controller
-	go build $(GOFLAGS) -a -o $(OUTPUT)/kubestack ./cmd/kubestack
+	go build $(GOFLAGS) -a -o $(OUTPUT)/kubestack -ldflags "-X main.VERSION=$(KUBESTACK_VERSION) -s -w" ./cmd/kubestack
 
 .PHONY: install
 install: depend
 	cd $(DEST)
 	install -D -m 755 $(OUTPUT)/stackube-controller /usr/local/bin/stackube-controller
 	install -D -m 755 $(OUTPUT)/kubestack /opt/cni/bin/kubestack
+	kubectl create -f ./deployment/kubestack/kubestack.yaml
+
+.PHONY: docker
+docker: depend
+	cd $(DEST)
+	KUBESTACK_VERSION?=$(shell ./$(OUTPUT)/kubestack -v)
+	docker build -t stackube/kubestack:v$(KUBESTACK_VERSION) ./deployment/kubestack/
 
 .PHONY: test
 test: test-unit
diff --git a/deployment/kubestack/10-kubestack.conf b/deployment/kubestack/10-kubestack.conf
new file mode 100644
index 0000000..52622b0
--- /dev/null
+++ b/deployment/kubestack/10-kubestack.conf
@@ -0,0 +1,6 @@
+{
+   "cniVersion": "0.3.1",
+   "name": "net",
+   "type": "kubestack",
+   "kubestack-config": "/etc/kubestack.conf"
+}
diff --git a/deployment/kubestack/Dockerfile b/deployment/kubestack/Dockerfile
new file mode 100644
index 0000000..50f545c
--- /dev/null
+++ b/deployment/kubestack/Dockerfile
@@ -0,0 +1,12 @@
+FROM busybox:1.26.2
+
+MAINTAINER stackube team
+
+ADD _output/kubestack /opt/cni/bin/kubestack
+ADD deployment/kubestack/install-cni.sh /install-cni.sh
+ADD deployment/kubestack/10-kubestack.conf /etc/cni/net.d/10-kubestack.conf
+ADD deployment/kubestack/kubestack.conf.default /kubestack.conf.tmp
+
+ENV PATH=$PATH:/opt/cni/bin
+VOLUME /opt/cni
+WORKDIR /opt/cni/bin
diff --git a/deployment/kubestack/install-cni.sh b/deployment/kubestack/install-cni.sh
new file mode 100755
index 0000000..1cc8f8b
--- /dev/null
+++ b/deployment/kubestack/install-cni.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+# Script to install kubestack CNI on a Kubernetes host.
+# - Expects the host CNI binary path to be mounted at /host/opt/cni/bin.
+# - Expects the host CNI network config path to be mounted at /host/etc/cni/net.d.
+# - Expects the desired CNI config in the /host/etc/cni/net.d/10-kubestack.conf.
+# - Expects the desired kubestack config in the KUBESTACK_CONFIG env variable.
+
+# Ensure all variables are defined.
+set -u
+
+# Clean up any existing binaries / config / assets.
+rm -f /host/opt/cni/bin/kubestack
+rm -f /host/etc/cni/net.d/10-kubestack.conf
+rm -f /etc/kubestack.conf
+
+# Place the new binaries if the directory is writeable.
+if [ -w "/host/opt/cni/bin/" ]; then
+	cp /opt/cni/bin/kubestack /host/opt/cni/bin/
+	echo "Wrote kubestack CNI binaries to /host/opt/cni/bin/"
+	echo "CNI plugin version: $(/host/opt/cni/bin/kubestack -v)"
+fi
+
+# Place the new CNI network config if the directory is writeable.
+if [ -w "/host/etc/cni/net.d/" ]; then
+	cp /etc/cni/net.d/10-kubestack.conf /host/etc/cni/net.d/
+	echo "Wrote CNI network config to /host/etc/cni/net.d/"
+	echo "CNI config: $(cat /host/etc/cni/net.d/10-kubestack.conf)"
+fi
+
+TMP_CONF='/kubestack.conf.tmp'
+# Check environment variables before any real actions.
+for i in 'AUTH_URL' 'USERNAME' 'PASSWORD' 'TENANT_NAME' 'REGION' 'EXT_NET_ID' 'PLUGIN_NAME' 'INTEGRATION_BRIDGE';do
+	if [ "${!i}" ];then
+	 echo "environment variable $i = ${!i}"
+	else
+	 echo "environment variable $i has not been setted or is empty,exit..."
+	 exit
+	fi
+done
+
+# Insert parameters.
+sed -i s~_AUTH_URL_~${AUTH_URL:-}~g $TMP_CONF
+sed -i s/_USERNAME_/${USERNAME:-}/g $TMP_CONF
+sed -i s/_PASSWORD_/${PASSWORD:-}/g $TMP_CONF
+sed -i s/_TENANT_NAME_/${TENANT_NAME:-}/g $TMP_CONF
+sed -i s/_REGION_/${REGION:-}/g $TMP_CONF
+sed -i s/_EXT_NET_ID_/${EXT_NET_ID:-}/g $TMP_CONF
+sed -i s/_PLUGIN_NAME_/${PLUGIN_NAME:-}/g $TMP_CONF
+sed -i s/_INTEGRATION_BRIDGE_/${INTEGRATION_BRIDGE:-}/g $TMP_CONF
+
+# Move the temporary kubestack config into place.
+KUBESTACK_CONFIG_PATH='/host/etc/kubestack.conf'
+mv $TMP_CONF $KUBESTACK_CONFIG_PATH
+echo "Wrote kubestack config: $(cat ${KUBESTACK_CONFIG_PATH})"
+
+while true; do
+	sleep 3600;
+done
diff --git a/deployment/kubestack/kubestack.conf.default b/deployment/kubestack/kubestack.conf.default
new file mode 100644
index 0000000..32cb677
--- /dev/null
+++ b/deployment/kubestack/kubestack.conf.default
@@ -0,0 +1,10 @@
+[Global]
+auth-url = _AUTH_URL_
+username = _USERNAME_
+password = _PASSWORD_
+tenant-name = _TENANT_NAME_
+region = _REGION_
+ext-net-id = _EXT_NET_ID_
+[Plugin]
+plugin-name = _PLUGIN_NAME_
+integration-bridge = _INTEGRATION_BRIDGE_
\ No newline at end of file
diff --git a/deployment/kubestack/kubestack.yaml b/deployment/kubestack/kubestack.yaml
new file mode 100644
index 0000000..457f076
--- /dev/null
+++ b/deployment/kubestack/kubestack.yaml
@@ -0,0 +1,115 @@
+# This ConfigMap is used to configure a self-hosted kubestack installation.
+kind: ConfigMap
+apiVersion: v1
+metadata:
+  name: kubestack-config
+  namespace: kube-system
+data:
+  auth-url: "<Your-openstack-authentication-endpoint>"
+  username: "admin"
+  password: "password"
+  tenant-name: "admin"
+  region: "RegionOne"
+  ext-net-id: "<Your-external-network-id>"
+  plugin-name: "ovs"
+  integration-bridge: "br-int"
+
+---
+
+# This manifest installs kubestack CNI plugins and network config
+# on each master and worker node in a Kubernetes cluster.
+kind: DaemonSet
+apiVersion: extensions/v1beta1
+metadata:
+  name: kubestack
+  namespace: kube-system
+  labels:
+    k8s-app: kubestack
+spec:
+  selector:
+    matchLabels:
+      k8s-app: kubestack
+  template:
+    metadata:
+      labels:
+        k8s-app: kubestack
+      annotations:
+        scheduler.alpha.kubernetes.io/critical-pod: ''
+        scheduler.alpha.kubernetes.io/tolerations: |
+          [{"key": "dedicated", "value": "master", "effect": "NoSchedule" },
+           {"key":"CriticalAddonsOnly", "operator":"Exists"}]
+    spec:
+      hostNetwork: true
+      containers:
+        # This container installs the kubestack CNI binaries
+        # and CNI network config file on each node.
+        - name: install-cni
+          image: stackube/kubestack:v0.1
+          command: ["/install-cni.sh"]
+          env:
+            # The endpoint of openstack authentication.
+            - name: AUTH_URL
+              valueFrom:
+                configMapKeyRef:
+                  name: kubestack-config
+                  key: auth-url
+            # The username for openstack authentication.
+            - name: USERNAME
+              valueFrom:
+                configMapKeyRef:
+                  name: kubestack-config
+                  key: username
+            # The password for openstack authentication.
+            - name: PASSWORD
+              valueFrom:
+                configMapKeyRef:
+                  name: kubestack-config
+                  key: password
+            # The tenant name for openstack authentication.
+            - name: TENANT_NAME
+              valueFrom:
+                configMapKeyRef:
+                  name: kubestack-config
+                  key: tenant-name
+            # The region for openstack authentication.
+            - name: REGION
+              valueFrom:
+                configMapKeyRef:
+                  name: kubestack-config
+                  key: region
+            # The id of openstack external network.
+            - name: EXT_NET_ID
+              valueFrom:
+                configMapKeyRef:
+                  name: kubestack-config
+                  key: ext-net-id
+            # The name of openstack neutron plugin.
+            - name: PLUGIN_NAME
+              valueFrom:
+                configMapKeyRef:
+                  name: kubestack-config
+                  key: plugin-name
+            # The name of openstack neutron integration bridge.
+            - name: INTEGRATION_BRIDGE
+              valueFrom:
+                configMapKeyRef:
+                  name: kubestack-config
+                  key: integration-bridge
+          volumeMounts:
+            - mountPath: /host/opt/cni/bin
+              name: cni-bin-dir
+            - mountPath: /host/etc/cni/net.d
+              name: cni-net-dir
+            - mountPath: /host/etc
+              name: kubestack-config-dir
+      volumes:
+        # Used to install CNI.
+        - name: cni-bin-dir
+          hostPath:
+            path: /opt/cni/bin
+        - name: cni-net-dir
+          hostPath:
+            path: /etc/cni/net.d
+        - name: kubestack-config-dir
+          hostPath:
+            path: /etc
\ No newline at end of file