You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by mr...@apache.org on 2017/05/17 17:49:33 UTC

[incubator-openwhisk-devtools] branch master updated: Able to fully deploy OpenWhisk on Kube (#31)

This is an automated email from the ASF dual-hosted git repository.

mrutkowski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-devtools.git

The following commit(s) were added to refs/heads/master by this push:
       new  3bfe674   Able to fully deploy OpenWhisk on Kube (#31)
3bfe674 is described below

commit 3bfe674a015deb658ac75c7e527a04096386c912
Author: Dan Lavine <dl...@us.ibm.com>
AuthorDate: Wed May 17 12:49:31 2017 -0500

    Able to fully deploy OpenWhisk on Kube (#31)
    
    * Deploy OpenWhisk Nginx to Kube
    
    * Build custom nginx image that include wsk cli and blackbox
    * Can only deploy with nginx certs for 'localhost'
    
    * Able to deploy routemgmt to Kube
    
    * Add extra configurations for zookeeper and kafka.
    Able to deploy kafka properly
    
    * Add troubleshooting section for Kafka
    
    * Update deployment for controller to mach new master configurations
    
    * give more time for pods to deploy
    
    * set docker0 to promiscuous mode in travis
    
    * Print logs for configure pod in ci when it passes or fails.
    
    * wait until nginx is up and running
    
    * update timeout for travis and remove extra comments
    
    * Create secrets for kube users after deployment
    
    * Update nginx image to have proper wsk location
    
    * Update CI to perform wsk actions
    
    * use sudo when setting ip link and Sleep before performing action
    
    * Update pull policy to always pull images
    
    * Fixup travis CI timeouts
    
    * Update README
---
 kubernetes/.travis/build.sh                        |  49 +++++-
 kubernetes/.travis/setup.sh                        |   4 +-
 kubernetes/Dockerfile                              |   7 +-
 kubernetes/README.md                               | 181 ++++++++++++++++-----
 kubernetes/ansible-kube/edge.yml                   |   9 +
 .../environments/kube/files/controller.yml         |  28 +++-
 .../environments/kube/files/invoker.yml            |   4 +-
 .../environments/kube/files/nginx-service.yml      |  22 +++
 .../ansible-kube/environments/kube/files/nginx.yml |  52 ++++++
 .../environments/kube/files/zookeeper-service.yml  |   6 +
 .../environments/kube/files/zookeeper.yml          |   4 +
 .../ansible-kube/environments/kube/group_vars/all  |  10 +-
 kubernetes/ansible-kube/openwhisk.yml              |   6 +-
 .../ansible-kube/roles/consul/tasks/deploy.yml     |   4 +-
 .../ansible-kube/roles/controller/tasks/deploy.yml |   6 +-
 .../ansible-kube/roles/invoker/tasks/deploy.yml    |   2 +-
 .../ansible-kube/roles/kafka/tasks/deploy.yml      |   2 +-
 .../ansible-kube/roles/nginx/tasks/deploy.yml      |  53 ++++++
 .../roles/nginx/templates/nginx.conf.j2            |  68 ++++++++
 .../roles/nginx/templates/secrets.conf.j2          |   8 +
 .../ansible-kube/roles/routemgmt/tasks/deploy.yml  |   6 +
 kubernetes/ansible-kube/tasks/initdb.yml           | 105 +++---------
 .../ansible-kube/tasks/installOpenwhiskCatalog.yml |  34 ++++
 .../ansible-kube/tasks/writeWhiskProperties.yml    |   2 +-
 .../ansible-kube/templates/whisk.properties.j2     |  15 +-
 kubernetes/configure/cleanup.sh                    |   7 +
 kubernetes/configure/configure.sh                  |  13 +-
 kubernetes/docker/build.sh                         |  64 ++++++++
 kubernetes/docker/nginx/Dockerfile                 |   4 +
 29 files changed, 617 insertions(+), 158 deletions(-)

diff --git a/kubernetes/.travis/build.sh b/kubernetes/.travis/build.sh
index 07ab7b5..2d7af55 100755
--- a/kubernetes/.travis/build.sh
+++ b/kubernetes/.travis/build.sh
@@ -15,9 +15,13 @@ cd $ROOTDIR
 kubectl apply -f configure/openwhisk_kube_namespace.yml
 kubectl apply -f configure/configure_whisk.yml
 
+sleep 5
+
+CONFIGURE_POD=$(kubectl get pods --all-namespaces -o wide | grep configure | awk '{print $2}')
+
 PASSED=false
 TIMEOUT=0
-until $PASSED || [ $TIMEOUT -eq 20 ]; do
+until $PASSED || [ $TIMEOUT -eq 25 ]; do
   KUBE_DEPLOY_STATUS=$(kubectl -n openwhisk get jobs | grep configure-openwhisk | awk '{print $3}')
   if [ $KUBE_DEPLOY_STATUS -eq 1 ]; then
     PASSED=true
@@ -30,14 +34,51 @@ until $PASSED || [ $TIMEOUT -eq 20 ]; do
   sleep 30
 done
 
-kubectl get jobs --all-namespaces -o wide --show-all
-kubectl get pods --all-namespaces -o wide --show-all
-
 if [ "$PASSED" = false ]; then
+  kubectl -n openwhisk logs $CONFIGURE_POD
+  kubectl get jobs --all-namespaces -o wide --show-all
+  kubectl get pods --all-namespaces -o wide --show-all
+
   echo "The job to configure OpenWhisk did not finish with an exit code of 1"
   exit 1
 fi
 
 echo "The job to configure OpenWhisk finished successfully"
 
+# Don't try and perform wsk actions the second it finishes deploying.
+# The CI ocassionaly fails if you perform actions to quickly.
+sleep 30
+
+AUTH_SECRET=$(kubectl -n openwhisk get secret openwhisk-auth-tokens -o yaml | grep 'auth_whisk_system:' | awk '{print $2}' | base64 --decode)
+WSK_PORT=$(kubectl -n openwhisk describe service nginx | grep https-api | grep NodePort| awk '{print $3}' | cut -d'/' -f1)
+
+# download the wsk cli from nginx
+wget --no-check-certificate https://127.0.0.1:$WSK_PORT/cli/go/download/linux/amd64/wsk
+chmod +x wsk
+
+# setup the wsk cli
+./wsk property set --auth $AUTH_SECRET --apihost https://127.0.0.1:$WSK_PORT
+
+# create wsk action
+cat > hello.js << EOL
+function main() {
+  return {payload: 'Hello world'};
+}
+EOL
+
+./wsk -i action create hello hello.js
+
+
+sleep 5
+
+# run the new hello world action
+RESULT=$(./wsk -i action invoke --blocking hello | grep "\"status\": \"success\"")
+
+if [ -z "$RESULT" ]; then
+  echo "FAILED! Could not invoked custom action"
+  exit 1
+fi
+
+echo "PASSED! Deployed openwhisk and invoked custom action"
+
 # push the images to an official repo
diff --git a/kubernetes/.travis/setup.sh b/kubernetes/.travis/setup.sh
index 554ea64..96d5f4d 100755
--- a/kubernetes/.travis/setup.sh
+++ b/kubernetes/.travis/setup.sh
@@ -3,6 +3,9 @@
 
 TAG=v1.5.5
 
+# set docker0 to promiscuous mode
+sudo ip link set docker0 promisc on
+
 # install etcd
 wget https://github.com/coreos/etcd/releases/download/v3.0.14/etcd-v3.0.14-linux-amd64.tar.gz
 tar xzf etcd-v3.0.14-linux-amd64.tar.gz
@@ -10,7 +13,6 @@ sudo mv etcd-v3.0.14-linux-amd64/etcd /usr/local/bin/etcd
 rm etcd-v3.0.14-linux-amd64.tar.gz
 rm -rf etcd-v3.0.14-linux-amd64
 
-
 # download kubectl
 wget https://storage.googleapis.com/kubernetes-release/release/$TAG/bin/linux/amd64/kubectl
 chmod +x kubectl
diff --git a/kubernetes/Dockerfile b/kubernetes/Dockerfile
index 5bbbdad..e4671b8 100644
--- a/kubernetes/Dockerfile
+++ b/kubernetes/Dockerfile
@@ -9,6 +9,7 @@ RUN apt-get -y update && \
     apt-get install -y \
       git \
       curl \
+      wget \
       apt-transport-https \
       ca-certificates \
       python-pip \
@@ -33,14 +34,10 @@ RUN git clone https://github.com/openwhisk/openwhisk && \
 # Change this to https://github.com/openwhisk/openwhisk-devtools when committing to master
 COPY ansible-kube /openwhisk-devtools/kubernetes/ansible-kube
 COPY configure /openwhisk-devtools/kubernetes/configure
+COPY wsk /openwhisk/bin/wsk
 
 # install kube dependencies
 # Kubernetes assumes that the version is 1.5.0+
 RUN wget https://storage.googleapis.com/kubernetes-release/release/v1.5.0/bin/linux/amd64/kubectl && \
     chmod +x kubectl && \
     mv kubectl /usr/local/bin/kubectl
-
-# install wsk cli
-RUN wget https://openwhisk.ng.bluemix.net/cli/go/download/linux/amd64/wsk && \
-    chmod +x wsk && \
-    mv wsk /openwhisk/bin/wsk
diff --git a/kubernetes/README.md b/kubernetes/README.md
index 9c59105..0ce66bc 100644
--- a/kubernetes/README.md
+++ b/kubernetes/README.md
@@ -19,27 +19,51 @@ The scripts and Docker images should be able to:
 1. Build the Docker image used for deploying OpenWhisk.
 2. Uses a Kubernetes job to deploy OpenWhisk.
 
-Currently, not all of the OpenWhisk components are deployed.
-So far, it will create Kube Deployments for:
-
-* couchdb
-* consul
-* controller
-* invoker
-
-To track the process, check out this [issue](https://github.com/openwhisk/openwhisk-devtools/issues/14).
-
-## Kubernetes Requirements
-
-* Kubernetes needs to be version 1.5+
-* Kubernetes has [Kube-DNS](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/) deployed
+## Requirements and Limitations
+#### Limitations
+
+As part of the deployment process, OpenWhisk needs to generate a CA-cert
+for Nginx and currently it has a static dns entry. Because of this, you
+will need to connect to OpenWhisk using the insecure mode (e.g. `wsk -i`).
+There is future work to make this CA-cert configurable.
+
+For now, OpenWhisk relies on part of the underlying infrastructure that Kube
+is running on. When deploying the Invoker for OpenWhisk, it mounts the hosts
+Docker socket. This way OpenWhisk can quickly provision actions and does not
+have to run Docker inside of Docker.
+
+A couple of components for OpenWhisk on Kube deployment strategy requires custom
+built Docker images. One such component is Nginx and currently resides at
+[danlavine/whisk_nginx](https://hub.docker.com/r/danlavine/whisk_nginx/). There
+is currently and open [issue](https://github.com/openwhisk/openwhisk/issues/2152)
+to make a public image and once it is resolved, then we can switch to the public image.
+
+The second Docker image this deployment strategy relies on is the OpenWhisk
+configuration image. For now, it is hosted at
+[danlavine/whisk_config](https://hub.docker.com/r/danlavine/whisk_config/),
+but ideally an official images can be built an maintained at some point.
+If you would like to build your own deployment image, see
+[Manually Build Custom Docker Files](#manually-building-custom-docker-files)
+
+Lastly, since OpenWhisk is configured/deployed via a Kubernetes Pod it requires
+the correct kubectl version to be built into `danlavine/whisk_config`. For now,
+there is only a version for Kube 1.5, and one can be built for 1.6, but there
+is no CI to test it against at the moment.
+
+#### Requirements
+
+Because of the limitations mentioned above, all requirments to deploy OpenWhisk
+on Kubernetes need to be met.
+
+**Kubernetes**
+* Kube version 1.5.0-1.5.5
+* Kubernetes has [KubeDNS](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/) deployed
 * (Optional) Kubernetes Pods can receive public addresses.
   This will be required if you wish to reach Nginx from outside
   of the Kubernetes cluster's network.
 
-At this time, we are not sure as to the total number of resources required
-to deploy OpenWhisk On Kubernetes. Once all of the process are running in
-Pods we will be able to list those.
+**OpenWhisk**
+* Docker version 1.12+
 
 ## Quick Start
 
@@ -61,44 +85,115 @@ setup the OpenWhisk environment.
 kubectl apply -f configure/configure_whisk.yml
 ```
 
+To see what is happening during the deployment process,
+you should be able to see the logs from the configuration VM.
 
-## Manually Building Custom Docker Files
-#### Building the Docker File That Deploys OpenWhisk
+```
+kubectl -n openwhisk logs configure-openwhisk-XXXXX
+```
+
+Once the configuration job sucessfuly finishes, you should will need to
+get the auth tokens used to setup OpenWhisk. As part of the deployment
+process, we store these tokens in Kubernetes
+[secrets](https://kubernetes.io/docs/concepts/configuration/secret/).
+To get these tokens, you can run the following command:
+
+```
+kubectl -n openwhisk get secret openwhisk-auth-tokens -o yaml
+```
+
+To use the secrets you will need to base64 decode them. E.g:
+
+```
+export AUTH_SECRET=$(kubectl -n openwhisk get secret openwhisk-auth-tokens -o yaml | grep 'auth_whisk_system:' | awk '{print $2}' | base64 --decode)
+```
+
+From here, you will now need to get the publicly available address
+of Nginx.
+ 1. Obtain the IP address of the Kubernetes nodes.
+
+ ```
+ kubectl get nodes
+ ```
+
+ 2. Obtain the public port for the Kubernetes Nginx Service
+
+ ```
+ kubectl -n openwhisk describe service nginx
+ ```
 
-The Docker image responsible for deploying OpenWhisk can be built using following command:
+ From here you should note the port used for the api endpoint. E.g:
+
+ ```
+ export WSK_PORT=$(kubectl -n openwhisk describe service nginx | grep https-api | grep NodePort| awk '{print $3}' | cut -d'/' -f1)
+ ```
+
+Now you should be able to setup the wsk cli like normal and interact with
+Openwhisk.
 
 ```
-docker build .
+wsk property set --auth $AUTH_SECRET --apihost https://[nginx_ip]:$WSK_PORT
 ```
 
-This image must then be re-tagged and pushed to a public
-docker repo. Currently, while this project is in development,
-the docker image is built and published [here](https://hub.docker.com/r/danlavine/whisk_config/),
-until an official repo is set up. If you would like to change
-this image to one you created, then make sure to update the
-[configure_whisk.yml](./configure/configure_whisk.yml) with your image.
+## Manually Building Custom Docker Files
+
+There are two images that are required when deploying OpenWhisk on Kube,
+Nginx and the OpenWhisk configuration image.
+
+To build these images, there is a helper script to build the
+required dependencies and build the docker images itself. For example,
+the wsk cli is built locally and then coppied into these images.
 
-## Manually building Kube Files
-#### Deployments and Services
+The script takes in 2 arguments:
+1. (Required) The first argument is the Docker account to push the built images
+   to. For Nginx, it will tag the image as `account_name/whisk_nginx:latest`
+   and the OpenWhisk configuration image will be tagged `account_name/whisk_config:dev`.
+
+   NOTE:  **log into Docker** before running the script or it will
+   fail to properly upload the docker images.
+
+2. (Optional) The second argument is the location of where the
+   [OpenWhisk](https://github.com/openwhisk/openwhisk) repo is installed
+   locally. By default it assumes that this repo exists at
+   `$HOME/workspace/openwhisk`.
+
+If you plan on building your own images and would like to change from `danlavine's`,
+then make sure to update the
+[configure_whisk.yml](configure/configure_whisk.yml) and
+[nginx](ansible-kube/environments/kube/files/nginx.yml) with your images.
+
+To run the script, use the command:
+
+```
+docker/build <username> <(optional) openwhisk dir>
+```
+
+## Editing the Openwhisk Kube Deployment
+#### Kubernetes Deployments and Services
 
 The current Kube Deployment and Services files that define the OpenWhisk
-cluster can be found [here](ansible/environments/kube/files). Only one
+cluster can be found [here](ansible-kube/environments/kube/files). Only one
 instance of each OpenWhisk process is created, but if you would like
 to increase that number, then this would be the place to do it. Simply edit
-the appropriate file and rebuild the
-[Docker File That Deploys OpenWhisk](#building-the-docker-file-that-deploys-openWhisk)
+the appropriate file and
+[Manually Build Custom Docker Files](#manually-building-custom-docker-files)
 
 ## Development
 #### Local Kube Development
 
 There are a couple ways to bring up Kubernetes locally and currently we
-are using [kubeadm](https://kubernetes.io/docs/getting-started-guides/kubeadm/)
-with [Callico](https://www.projectcalico.org/) for the
+are using the common `local-up-cluster.sh` script. Take a look at what
+[travis](.travis/setup.sh) does to bring everything up with KubeDNS support.
+
+[Kubeadm](https://kubernetes.io/docs/getting-started-guides/kubeadm/)
+can be deployed with [Callico](https://www.projectcalico.org/) for the
 [network](http://docs.projectcalico.org/v2.1/getting-started/kubernetes/installation/hosted/kubeadm/).
-By default kubeadm runs with Kube-DNS already enabled and the instructions
-will install a Kube version greater the v1.5. Using this deployment method
-everything is running on one host and nothing special has to be
-done for network configurations when communicating with Kube Pods.
+By default kubeadm runs with KubeDNS already enabled, but please make sure
+to install Kubeadm for Kube version 1.5.
+
+**Minikube is not supported** at this time because it uses an old version
+of docker (1.11.x). See the the [Requirements and Limitations](#requirements-and-limitations)
+section for more info.
 
 #### Deploying OpenWhisk on Kubernetes
 
@@ -118,3 +213,13 @@ services and jobs. For this, you can run the following script:
 ```
 ./kube_environment/cleanup.sh
 ```
+## Troubleshooting
+#### Kafka
+
+When deploying Kubernetes on Ubuntu 14.04 with the `local_up_cluster.sh` scripts,
+you might need to allow kube pods to communicate with themselves over KubeDNS.
+To enable this on the Docker network, you will need to run the following command:
+
+```
+ip link set docker0 promisc on
+```
diff --git a/kubernetes/ansible-kube/edge.yml b/kubernetes/ansible-kube/edge.yml
new file mode 100644
index 0000000..5a0a387
--- /dev/null
+++ b/kubernetes/ansible-kube/edge.yml
@@ -0,0 +1,9 @@
+---
+# This playbook deploys Openwhisk Edge servers.
+# The edge is usually populated with NGINX serving as proxy.
+# The CLI also gets built and published for downloading from NGINX.
+# SDKs for blackbox and iOS get published to NGINX also.
+
+- hosts: edge
+  roles:
+  - nginx
diff --git a/kubernetes/ansible-kube/environments/kube/files/controller.yml b/kubernetes/ansible-kube/environments/kube/files/controller.yml
index d53ade6..4b27d74 100644
--- a/kubernetes/ansible-kube/environments/kube/files/controller.yml
+++ b/kubernetes/ansible-kube/environments/kube/files/controller.yml
@@ -17,8 +17,9 @@ spec:
 
       containers:
       - name: controller
-        imagePullPolicy: IfNotPresent
+        imagePullPolicy: Always
         image: openwhisk/controller
+        command: ["/bin/bash", "-c", "/controller/bin/controller"]
         ports:
         - name: controller
           containerPort: 8080
@@ -39,3 +40,28 @@ spec:
           value: "15s"
         - name: "PORT"
           value: "8080"
+        - name: "WHISK_VERSION_NAME"
+          valueFrom:
+            configMapKeyRef:
+              name: controller
+              key: whisk.version.name
+        - name: "WHISK_VERSION_DATE"
+          valueFrom:
+            configMapKeyRef:
+              name: controller
+              key: whisk.version.date
+        - name: "WHISK_VERSION_BUILDNO"
+          valueFrom:
+            configMapKeyRef:
+              name: controller
+              key: whisk.version.buildno
+        - name: "JAVA_OPTS"
+          valueFrom:
+            configMapKeyRef:
+              name: controller
+              key: java.opts
+        - name: "CONTROLLER_OPTS"
+          valueFrom:
+            configMapKeyRef:
+              name: controller
+              key: controller.opts
diff --git a/kubernetes/ansible-kube/environments/kube/files/invoker.yml b/kubernetes/ansible-kube/environments/kube/files/invoker.yml
index 201e58e..7ae579e 100644
--- a/kubernetes/ansible-kube/environments/kube/files/invoker.yml
+++ b/kubernetes/ansible-kube/environments/kube/files/invoker.yml
@@ -35,9 +35,9 @@ spec:
 
       containers:
       - name: invoker
-        imagePullPolicy: IfNotPresent
+        imagePullPolicy: Always
         image: openwhisk/invoker
-        command: [ "/bin/bash", "-c", "/invoker/bin/invoker `hostname | cut -d'-' -f2`" ]
+        command: [ "/bin/bash", "-c", "COMPONENT_NAME=$(hostname | cut -d'-' -f2) /invoker/bin/invoker `hostname | cut -d'-' -f2`" ]
         env:
           - name: "CONSULSERVER_HOST"
             value: "consul.openwhisk"
diff --git a/kubernetes/ansible-kube/environments/kube/files/nginx-service.yml b/kubernetes/ansible-kube/environments/kube/files/nginx-service.yml
new file mode 100644
index 0000000..c1758d3
--- /dev/null
+++ b/kubernetes/ansible-kube/environments/kube/files/nginx-service.yml
@@ -0,0 +1,22 @@
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: nginx
+  namespace: openwhisk
+  labels:
+    name: nginx
+spec:
+  type: NodePort
+  selector:
+    name: nginx
+  ports:
+    - port: 80
+      targetPort: 80
+      name: http
+    - port: 443
+      targetPort: 443
+      name: https-api
+    - port: 8443
+      targetPort: 8443
+      name: https-admin
diff --git a/kubernetes/ansible-kube/environments/kube/files/nginx.yml b/kubernetes/ansible-kube/environments/kube/files/nginx.yml
new file mode 100644
index 0000000..d9780b2
--- /dev/null
+++ b/kubernetes/ansible-kube/environments/kube/files/nginx.yml
@@ -0,0 +1,52 @@
+---
+apiVersion: extensions/v1beta1
+kind: Deployment
+metadata:
+  name: nginx
+  namespace: openwhisk
+  labels:
+    name: nginx
+spec:
+  replicas: 1
+  template:
+    metadata:
+      labels:
+        name: nginx
+    spec:
+      restartPolicy: Always
+      volumes:
+      - name: nginx-certs
+        configMap:
+          name: nginx
+          items:
+          - key: "openwhisk-cert.pem"
+            path: openwhisk-cert.pem
+          - key: "openwhisk-key.pem"
+            path: openwhisk-key.pem
+      - name: nginx-conf
+        configMap:
+          name: nginx
+          items:
+          - key: "nginx.conf"
+            path: nginx.conf
+      - name: logs
+        emptyDir: {}
+      containers:
+      - name: nginx
+        imagePullPolicy: Always
+        image: danlavine/whisk_nginx
+        ports:
+        - name: http
+          containerPort: 80
+        - name: http-api
+          containerPort: 443
+        - name: https-admin
+          containerPort: 8443
+        volumeMounts:
+        - name: nginx-conf
+          mountPath: "/etc/nginx/nginx.conf"
+          subPath: "nginx.conf"
+        - name: nginx-certs
+          mountPath: "/etc/nginx/certs"
+        - name: logs
+          mountPath: "/logs"
diff --git a/kubernetes/ansible-kube/environments/kube/files/zookeeper-service.yml b/kubernetes/ansible-kube/environments/kube/files/zookeeper-service.yml
index f2f5a6c..f48773c 100644
--- a/kubernetes/ansible-kube/environments/kube/files/zookeeper-service.yml
+++ b/kubernetes/ansible-kube/environments/kube/files/zookeeper-service.yml
@@ -13,3 +13,9 @@ spec:
     - port: 2181
       targetPort: 2181
       name: zookeeper
+    - port: 2888
+      targetPort: 2888
+      name: server
+    - port: 3888
+      targetPort: 3888
+      name: leader-election
diff --git a/kubernetes/ansible-kube/environments/kube/files/zookeeper.yml b/kubernetes/ansible-kube/environments/kube/files/zookeeper.yml
index 219d132..cd292c5 100644
--- a/kubernetes/ansible-kube/environments/kube/files/zookeeper.yml
+++ b/kubernetes/ansible-kube/environments/kube/files/zookeeper.yml
@@ -22,3 +22,7 @@ spec:
         ports:
         - name: zookeeper
           containerPort: 2181
+        - name: server
+          containerPort: 2888
+        - name: leader-election
+          containerPort: 3888
diff --git a/kubernetes/ansible-kube/environments/kube/group_vars/all b/kubernetes/ansible-kube/environments/kube/group_vars/all
index 9b13574..80dee7e 100644
--- a/kubernetes/ansible-kube/environments/kube/group_vars/all
+++ b/kubernetes/ansible-kube/environments/kube/group_vars/all
@@ -18,6 +18,7 @@ db_username: couch_user
 db_password: couch_password
 db_auth: "subjects"
 db_prefix: "ubuntu_kube-1-4-1_"
+db_split_actions_and_activations: true
 
 # apigw db credentials minimum read/write
 db_apigw_username: "couch_user"
@@ -28,18 +29,19 @@ apigw_initdb: true
 # API GW connection configuration
 apigw_auth_user: ""
 apigw_auth_pwd: ""
-apigw_host: "http://edge.openwhisk:9000/v1"
-apigw_host_v2: "http://edge.openwhisk:9000/v2"
+apigw_host: "nginx.openwhisk"
+apigw_host_v2: "nginx.openwhisk"
+whisk_api_host_name: "nginx.openwhisk"
 
 
 # consul properties
 consul_host: consul.openwhisk
 consul_conf_dir: /tmp/consul
 
-# edge properties
+# nginx properties
 nginx_conf_dir: /tmp/nginx
 cli_nginx_dir: "/tmp/nginx/cli/go/download"
-edge_host: edge.openwhisk
+nginx_host: nginx.openwhisk
 
 # controller properties
 controller_host: controller.openwhisk
diff --git a/kubernetes/ansible-kube/openwhisk.yml b/kubernetes/ansible-kube/openwhisk.yml
index a5beaa3..94dfcfe 100644
--- a/kubernetes/ansible-kube/openwhisk.yml
+++ b/kubernetes/ansible-kube/openwhisk.yml
@@ -11,6 +11,6 @@
 
 - include: invoker.yml
 
-#- include: edge.yml
-#
-#- include: routemgmt.yml
+- include: edge.yml
+
+- include: routemgmt.yml
diff --git a/kubernetes/ansible-kube/roles/consul/tasks/deploy.yml b/kubernetes/ansible-kube/roles/consul/tasks/deploy.yml
index 54c47a0..c7f61e4 100644
--- a/kubernetes/ansible-kube/roles/consul/tasks/deploy.yml
+++ b/kubernetes/ansible-kube/roles/consul/tasks/deploy.yml
@@ -30,8 +30,8 @@
     body: 'true'
   register: result
   until: result.status == 200
-  retries: 12
-  delay: 5
+  retries: 20
+  delay: 10
   when: "'consul_servers' in group_names"
 
 - name: delete is alive token from Consul Server/Agent
diff --git a/kubernetes/ansible-kube/roles/controller/tasks/deploy.yml b/kubernetes/ansible-kube/roles/controller/tasks/deploy.yml
index aaba253..43c7407 100644
--- a/kubernetes/ansible-kube/roles/controller/tasks/deploy.yml
+++ b/kubernetes/ansible-kube/roles/controller/tasks/deploy.yml
@@ -1,5 +1,7 @@
 ---
 # This role will install Controller in group 'controllers' in the environment inventory
+- name: create controller config map
+  shell: "kubectl create configmap controller --from-literal=whisk.version.name={{whisk_version_name}} --from-literal=whisk.version.date={{whisk.version.date}} --from-literal=whisk.version.buildno={{docker_image_tag}} --from-literal=java.opts=-Xmx{{controller.heap}} --from-literal=controller.opts={{controller.arguments}}"
 
 - name: create controller deployment
   shell: "kubectl apply -f {{kube_pod_dir}}/controller.yml"
@@ -19,7 +21,7 @@
   shell: "kubectl -n openwhisk exec {{ item[0] }} -- bash -c 'curl -I http://0.0.0.0:8080/ping'"
   register: result
   until: (result.rc == 0) and (result.stdout.find("200 OK") != -1)
-  retries: 12
-  delay: 5
+  retries: 20
+  delay: 10
   with_items:
     - ["{{ controller_pods }}"]
diff --git a/kubernetes/ansible-kube/roles/invoker/tasks/deploy.yml b/kubernetes/ansible-kube/roles/invoker/tasks/deploy.yml
index f943f24..aea853b 100644
--- a/kubernetes/ansible-kube/roles/invoker/tasks/deploy.yml
+++ b/kubernetes/ansible-kube/roles/invoker/tasks/deploy.yml
@@ -10,6 +10,6 @@
     url: "http://invoker-{{ item }}.invoker.openwhisk:{{ invoker_port }}/ping"
   register: result
   until: result.status == 200
-  retries: 20
+  retries: 50
   delay: 20
   with_sequence: start=0 count={{ invoker_count }}
diff --git a/kubernetes/ansible-kube/roles/kafka/tasks/deploy.yml b/kubernetes/ansible-kube/roles/kafka/tasks/deploy.yml
index 1b15158..4b46c37 100644
--- a/kubernetes/ansible-kube/roles/kafka/tasks/deploy.yml
+++ b/kubernetes/ansible-kube/roles/kafka/tasks/deploy.yml
@@ -64,7 +64,7 @@
   with_sequence: start=0 count={{ invoker_count }}
 
 - name: create the invoker topics
-  shell: " kubectl exec {{ item[0] }} -c kafka -- bash -c 'unset JMX_PORT; kafka-topics.sh --create --topic invoke{{ item[1] }} --replication-factor 1 --partitions 1 --zookeeper {{ zookeeper_host }}:{{ zookeeper.port }}'"
+  shell: " kubectl exec {{ item[0] }} -c kafka -- bash -c 'unset JMX_PORT; kafka-topics.sh --create --topic invoker{{ item[1] }} --replication-factor 1 --partitions 1 --zookeeper {{ zookeeper_host }}:{{ zookeeper.port }}'"
   register: command_result
   failed_when: "not ('Created topic' in command_result.stdout or 'already exists' in command_result.stdout)"
   with_nested:
diff --git a/kubernetes/ansible-kube/roles/nginx/tasks/deploy.yml b/kubernetes/ansible-kube/roles/nginx/tasks/deploy.yml
new file mode 100644
index 0000000..f70934d
--- /dev/null
+++ b/kubernetes/ansible-kube/roles/nginx/tasks/deploy.yml
@@ -0,0 +1,53 @@
+---
+# This role starts a nginx component
+
+- name: ensure nginx config directory exists
+  file:
+    path: "{{ nginx_conf_dir }}"
+    state: directory
+
+- name: copy template from local to remote in nginx config directory
+  template:
+    src: nginx.conf.j2
+    dest: "{{ nginx_conf_dir }}/nginx.conf"
+
+- name: copy cert files from local to remote in nginx config directory
+  copy:
+    src: "files/"
+    dest: "{{ nginx_conf_dir }}"
+
+- name: create configmap
+  shell: "kubectl create configmap nginx --from-file={{ nginx_conf_dir }}/nginx.conf --from-file={{ nginx_conf_dir }}/genssl.sh --from-file={{ nginx_conf_dir }}/openwhisk-key.pem --from-file={{ nginx_conf_dir }}/openwhisk-cert.pem --from-file={{ nginx_conf_dir }}/openwhisk-request.csr"
+
+- name: create nginx pod
+  shell: "kubectl create -f {{kube_pod_dir}}/nginx.yml"
+
+# TODO Rebplace this with a proper uri request once certs have been configured correctly
+- name: wait until nginx is up and running
+  shell: "curl -k https://{{ nginx_host }}:{{ nginx.port.api }}"
+  register: result
+  until: (result.rc == 0) and (result.stdout != "")
+  retries: 20
+  delay: 10
+
+- name: get whisk system key
+  shell: "cat {{ playbook_dir }}/files/auth.whisk.system | base64 --wrap=0"
+  register: auth_whisk_system_var
+
+- name: get whisk system key
+  shell: "cat {{ playbook_dir }}/files/auth.guest | base64 --wrap=0"
+  register: auth_guest_var
+
+- name: set facts
+  set_fact:
+    auth_whisk_system: "{{ auth_whisk_system_var.stdout }}"
+    auth_guest: "{{ auth_guest_var.stdout }}"
+
+- name: fill secret template
+  template:
+    src: secrets.conf.j2
+    dest: "{{ nginx_conf_dir }}/secrets.yml"
+
+- name: create the secrets yaml
+  shell: "kubectl apply -f {{ nginx_conf_dir }}/secrets.yml"
+
diff --git a/kubernetes/ansible-kube/roles/nginx/templates/nginx.conf.j2 b/kubernetes/ansible-kube/roles/nginx/templates/nginx.conf.j2
new file mode 100644
index 0000000..ddd1fc1
--- /dev/null
+++ b/kubernetes/ansible-kube/roles/nginx/templates/nginx.conf.j2
@@ -0,0 +1,68 @@
+{# this template is used to generate a nginx.conf for booting a nginx server based on the given environment inventory #}
+
+events {
+{# default: 1024 #}
+    worker_connections  4096;
+}
+
+http {
+{# allow large uploads, need to thread proper limit into here #}
+    client_max_body_size 50M;
+
+    rewrite_log on;
+{# change log format to display the upstream information #}
+    log_format combined-upstream '$remote_addr - $remote_user [$time_local] '
+        '$request $status $body_bytes_sent '
+        '$http_referer $http_user_agent $upstream_addr';
+    access_log /logs/nginx_access.log combined-upstream;
+
+    server {
+        listen 443 default ssl;
+
+        # match namespace, note while OpenWhisk allows a richer character set for a
+        # namespace, not all those characters are permitted in the (sub)domain name;
+        # if namespace does not match, no vanity URL rewriting takes place.
+        server_name ~^(?<namespace>[0-9a-zA-Z-]+)\.{{ whisk_api_localhost_name | default(whisk_api_host_name) | default(whisk_api_localhost_name_default) }}$;
+
+        ssl_session_cache    shared:SSL:1m;
+        ssl_session_timeout  10m;
+        ssl_certificate      /etc/nginx/certs/openwhisk-cert.pem;
+        ssl_certificate_key  /etc/nginx/certs/openwhisk-key.pem;
+        ssl_verify_client off;
+        ssl_protocols        TLSv1 TLSv1.1 TLSv1.2;
+        ssl_ciphers RC4:HIGH:!aNULL:!MD5;
+        ssl_prefer_server_ciphers on;
+        proxy_ssl_session_reuse off;
+
+        # proxy to the web action path
+        location / {
+            if ($namespace) {
+              rewrite    /(.*) /api/v1/web/${namespace}/$1 break;
+            }
+            proxy_pass http://{{ controller_host }}:{{ controller.port }};
+            proxy_read_timeout 70s; # 60+10 additional seconds to allow controller to terminate request
+        }
+
+        # proxy to 'public/html' web action by convention
+        location = / {
+            if ($namespace) {
+              rewrite    ^ /api/v1/web/${namespace}/public/index.html break;
+            }
+            proxy_pass http://{{ controller_host }}:{{ controller.port }};
+            proxy_read_timeout 70s; # 60+10 additional seconds to allow controller to terminate request
+        }
+
+        location /blackbox-0.1.0.tar.gz {
+            root /etc/nginx;
+        }
+
+        location /OpenWhiskIOSStarterApp.zip {
+            return 301 https://github.com/openwhisk/openwhisk-client-swift/releases/download/0.2.3/starterapp-0.2.3.zip;
+        }
+
+        location /cli/go/download {
+            autoindex on;
+            root /etc/nginx;
+        }
+    }
+}
diff --git a/kubernetes/ansible-kube/roles/nginx/templates/secrets.conf.j2 b/kubernetes/ansible-kube/roles/nginx/templates/secrets.conf.j2
new file mode 100644
index 0000000..ab252c3
--- /dev/null
+++ b/kubernetes/ansible-kube/roles/nginx/templates/secrets.conf.j2
@@ -0,0 +1,8 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  name: openwhisk-auth-tokens
+type: Opaque
+data:
+  auth_whisk_system: {{ auth_whisk_system }}
+  auth_guest: {{ auth_guest }}
diff --git a/kubernetes/ansible-kube/roles/routemgmt/tasks/deploy.yml b/kubernetes/ansible-kube/roles/routemgmt/tasks/deploy.yml
new file mode 100644
index 0000000..a797e7b
--- /dev/null
+++ b/kubernetes/ansible-kube/roles/routemgmt/tasks/deploy.yml
@@ -0,0 +1,6 @@
+---
+# Install the API Gateway route management actions.
+- name: install route management actions
+  shell: ./installRouteMgmt.sh {{ catalog_auth_key }} {{ nginx_host }} {{ catalog_namespace }} {{ cli_path }} chdir="{{ openwhisk_home }}/ansible/roles/routemgmt/files"
+  environment:
+    OPENWHISK_HOME: "{{ openwhisk_home }}"
diff --git a/kubernetes/ansible-kube/tasks/initdb.yml b/kubernetes/ansible-kube/tasks/initdb.yml
index 20151fa..f20356d 100644
--- a/kubernetes/ansible-kube/tasks/initdb.yml
+++ b/kubernetes/ansible-kube/tasks/initdb.yml
@@ -1,94 +1,31 @@
 ---
 # This task will initialize the immortal DBs in the database account.
-# This step is usually done only once per account.
+# This step is usually done only once per deployment.
 
-- name: check if the immortal {{ db.whisk.auth }} db with {{ db_provider }} exists?
-  uri:
-    url: "{{ db_protocol }}://{{ db_host }}:{{ db_port }}/{{ db.whisk.auth }}"
-    method: GET
-    status_code: 200,404
-    user: "{{ db_username }}"
-    password: "{{ db_password }}"
-    force_basic_auth: yes
-  register: dbexists
-
-# create only the missing db.whisk.auth
-- name: create immortal {{ db.whisk.auth }} db with {{ db_provider }}
-  uri:
-    url: "{{ db_protocol }}://{{ db_host }}:{{ db_port }}/{{ db.whisk.auth }}"
-    method: PUT
-    status_code: 200,201,202
-    user: "{{ db_username }}"
-    password: "{{ db_password }}"
-    force_basic_auth: yes
-  when: dbexists is defined and dbexists.status == 404
-
-# fetches the revision of previous view (to update it) if it exists
-- name: check for previous view in "auth" database
+- include: db/recreateDb.yml
   vars:
-    auth_index: "{{ lookup('file', '{{ openwhisk_home }}/ansible/files/auth_index.json') }}"
-  uri:
-    url: "{{ db_protocol }}://{{ db_host }}:{{ db_port }}/{{ db.whisk.auth }}/{{ auth_index['_id'] }}"
-    return_content: yes
-    method: GET
-    status_code: 200, 404
-    user: "{{ db_username }}"
-    password: "{{ db_password }}"
-    force_basic_auth: yes
-  register: previousView
-  when: dbexists is defined and dbexists.status != 404 #and mode=="updateview"
-
-- name: extract revision from previous view
-  vars:
-    previousContent: "{{ previousView['content']|from_json }}"
-    revision: "{{ previousContent['_rev'] }}"
-    auth_index: "{{ lookup('file', '{{ openwhisk_home }}/ansible/files/auth_index.json') }}"
-  set_fact:
-    previousContent: "{{ previousContent }}"
-    updateWithRevision: "{{ auth_index | combine({'_rev': revision}) }}"
-  when: previousView is defined and previousView.status != 404
-
-- name: check if a view update is required
-  set_fact:
-    updateView: "{{ updateWithRevision }}"
-  when: previousContent is defined and previousContent != updateWithRevision
+    dbName: "{{ db.whisk.auth }}"
+    forceRecreation: False
 
-- name: recreate or update the index on the "auth" database
+- include: db/recreateDoc.yml
   vars:
-    auth_index: "{{ lookup('file', '{{ openwhisk_home }}/ansible/files/auth_index.json') }}"
-  uri:
-    url: "{{ db_protocol }}://{{ db_host }}:{{ db_port }}/{{ db.whisk.auth }}"
-    method: POST
-    status_code: 200, 201
-    body_format: json
-    body: "{{ updateView | default(auth_index) }}"
-    user: "{{ db_username }}"
-    password: "{{ db_password }}"
-    force_basic_auth: yes
-  when: (dbexists is defined and dbexists.status == 404) or (updateView is defined)
+    dbName: "{{ db.whisk.auth }}"
+    doc: "{{ lookup('file', '{{ item }}') }}"
+  with_items:
+    - "{{ openwhisk_home }}/ansible/files/auth_index.json"
+    - "{{ openwhisk_home }}/ansible/files/filter_design_document.json"
 
-- name: recreate necessary "auth" keys
+- name: create necessary "auth" keys
+  include: db/recreateDoc.yml
   vars:
     key: "{{ lookup('file', 'files/auth.{{ item }}') }}"
-  uri:
-    url: "{{ db_protocol }}://{{ db_host }}:{{ db_port }}/{{ db.whisk.auth }}"
-    method: POST
-    status_code: 200,201
-    body_format: json
-    body: >
-          {
-            "_id": "{{ item }}",
-            "subject": "{{ item }}",
-            "namespaces": [
-              {
-                "name": "{{ item }}",
-                "uuid": "{{ key.split(":")[0] }}",
-                "key": "{{ key.split(":")[1] }}"
-              }
-            ]
-          }
-    user: "{{ db_username }}"
-    password: "{{ db_password }}"
-    force_basic_auth: yes
+    dbName: "{{ db.whisk.auth }}"
+    doc: >
+      {
+        "_id": "{{ item }}",
+        "subject": "{{ item }}",
+        "uuid": "{{ key.split(":")[0] }}",
+        "key": "{{ key.split(":")[1] }}",
+        "namespaces": []
+      }
   with_items: "{{ db.authkeys }}"
-  when: dbexists is defined and dbexists.status == 404
diff --git a/kubernetes/ansible-kube/tasks/installOpenwhiskCatalog.yml b/kubernetes/ansible-kube/tasks/installOpenwhiskCatalog.yml
new file mode 100644
index 0000000..7064e27
--- /dev/null
+++ b/kubernetes/ansible-kube/tasks/installOpenwhiskCatalog.yml
@@ -0,0 +1,34 @@
+---
+# This task will install the standard actions and packages available in openwhisk-catalog repos.
+
+- set_fact:
+    catalog_location={{ item.value.location }}
+    catalog_repo_url={{ item.value.url }}
+    api_host={{ nginx_host }}
+    version="HEAD"
+    repo_update="yes"
+
+- set_fact:
+    version={{ item.value.version }}
+  when: item.value.version is defined
+
+- set_fact:
+    repo_update={{ item.value.repo_update }}
+  when: item.value.repo_update is defined
+
+- name: "ensure catalog_location directory exists"
+  file:
+    path: "{{ catalog_location }}"
+    state: directory
+
+- name: download the catalog repository to the catalog location if necessary
+  git:
+    repo: "{{ catalog_repo_url }}"
+    dest: "{{ catalog_location }}"
+    update: "{{ repo_update }}"
+    version: "{{ version }}"
+
+- name: install the catalog from the catalog location
+  shell: ./installCatalog.sh {{ catalog_auth_key }} {{ api_host }} {{ catalog_namespace }} {{ cli_path }} chdir="{{ catalog_location }}/packages"
+  environment:
+    OPENWHISK_HOME: "{{ openwhisk_home }}"
diff --git a/kubernetes/ansible-kube/tasks/writeWhiskProperties.yml b/kubernetes/ansible-kube/tasks/writeWhiskProperties.yml
index 97ec01f..d066c86 100644
--- a/kubernetes/ansible-kube/tasks/writeWhiskProperties.yml
+++ b/kubernetes/ansible-kube/tasks/writeWhiskProperties.yml
@@ -8,7 +8,7 @@
 
 - name: update the invoker domains
   set_fact:
-    invoker_hosts: "{{invoker_hosts}} + ['invoker-{{item}}.invoker.openwhisk]"
+    invoker_hosts: "{{ invoker_hosts }} + [ 'invoker-{{item}}.invoker.openwhisk' ]"
   with_sequence: start=0 count={{ invoker_count }}
 
 - name: write whisk.properties template to openwhisk_home
diff --git a/kubernetes/ansible-kube/templates/whisk.properties.j2 b/kubernetes/ansible-kube/templates/whisk.properties.j2
index c983fd7..1ab149d 100644
--- a/kubernetes/ansible-kube/templates/whisk.properties.j2
+++ b/kubernetes/ansible-kube/templates/whisk.properties.j2
@@ -52,10 +52,9 @@ invoker.hosts={{ invoker_hosts | join(",") }}
 controller.host={{ controller_host }}
 kafka.host={{ kafka_host }}
 zookeeper.host={{ zookeeper_host }}
-
-edge.host={{ groups["edge"]|first }}
-loadbalancer.host={{ groups["controllers"]|first }}
-router.host={{ groups["edge"]|first }}
+edge.host={{ nginx_host }}
+loadbalancer.host={{ controller_host }}
+router.host={{ nginx_host }}
 
 {#
  # replaced host entries
@@ -65,6 +64,9 @@ router.host={{ groups["edge"]|first }}
  # controller.host={{ groups["controllers"]|first }}
  # kafka.host={{ groups["kafka"]|first }}
  # zookeeper.host={{ groups["kafka"]|first }}
+ # edge.host={{ groups["edge"]|first }}
+ # loadbalancer.host={{ groups["controllers"]|first }}
+ # router.host={{ groups["edge"]|first }}
  #}
 
 edge.host.apiport=443
@@ -100,12 +102,11 @@ edge.docker.endpoint={{ groups["edge"]|first }}:{{ docker.port }}
 kafka.docker.endpoint={{ groups["kafka"]|first }}:{{ docker.port }}
 main.docker.endpoint={{ groups["controllers"]|first }}:{{ docker.port }}
 
-docker.registry={{ docker_registry }}
-
 # configure to use the public docker images
 docker.image.prefix=openwhisk
-#docker.image.prefix={{ docker_image_prefix }}
 
+docker.registry={{ docker_registry }}
+#docker.image.prefix={{ docker_image_prefix }}
 #use.docker.registry=false
 docker.port={{ docker.port }}
 docker.timezone.mount=
diff --git a/kubernetes/configure/cleanup.sh b/kubernetes/configure/cleanup.sh
index 84728f2..581d859 100755
--- a/kubernetes/configure/cleanup.sh
+++ b/kubernetes/configure/cleanup.sh
@@ -14,9 +14,12 @@ kubectl -n openwhisk delete deployment zookeeper
 kubectl -n openwhisk delete deployment kafka
 kubectl -n openwhisk delete deployment controller
 kubectl -n openwhisk delete statefulsets invoker
+kubectl -n openwhisk delete deployment nginx
 
 # delete configmaps
 kubectl -n openwhisk delete cm consul
+kubectl -n openwhisk delete cm controller
+kubectl -n openwhisk delete cm nginx
 
 # delete services
 kubectl -n openwhisk delete service couchdb
@@ -25,3 +28,7 @@ kubectl -n openwhisk delete service zookeeper
 kubectl -n openwhisk delete service kafka
 kubectl -n openwhisk delete service controller
 kubectl -n openwhisk delete service invoker
+kubectl -n openwhisk delete service nginx
+
+# delete secrets
+kubectl -n openwhisk delete secret openwhisk-auth-tokens
diff --git a/kubernetes/configure/configure.sh b/kubernetes/configure/configure.sh
index 89dfa94..a1e72bf 100755
--- a/kubernetes/configure/configure.sh
+++ b/kubernetes/configure/configure.sh
@@ -30,6 +30,10 @@ sed -ie "s/REPLACE_INVOKER_COUNT/$INVOKER_COUNT/g" /openwhisk-devtools/kubernete
 # copy the ansible playbooks and tools to this repo
 cp -R /openwhisk/ansible/ /openwhisk-devtools/kubernetes/ansible
 cp -R /openwhisk/tools/ /openwhisk-devtools/kubernetes/tools
+cp -R /openwhisk/bin/ /openwhisk-devtools/kubernetes/bin
+
+mkdir -p /openwhisk-devtools/kubernetes/core
+cp -R /openwhisk/core/routemgmt /openwhisk-devtools/kubernetes/core/routemgmt
 
 # overwrite the default openwhisk ansible with the kube ones.
 cp -R /openwhisk-devtools/kubernetes/ansible-kube/. /openwhisk-devtools/kubernetes/ansible/
@@ -38,6 +42,8 @@ cp -R /openwhisk-devtools/kubernetes/ansible-kube/. /openwhisk-devtools/kubernet
 kubectl proxy -p 8001 &
 
 pushd /openwhisk-devtools/kubernetes/ansible
+  ansible-playbook -i environments/kube setup.yml
+
   # Create all of the necessary services
   kubectl apply -f environments/kube/files/db-service.yml
   kubectl apply -f environments/kube/files/consul-service.yml
@@ -45,15 +51,18 @@ pushd /openwhisk-devtools/kubernetes/ansible
   kubectl apply -f environments/kube/files/kafka-service.yml
   kubectl apply -f environments/kube/files/controller-service.yml
   kubectl apply -f environments/kube/files/invoker-service.yml
+  kubectl apply -f environments/kube/files/nginx-service.yml
 
   if deployCouchDB; then
-    # Create the CouchDB deployment
+    # Create and configure the CouchDB deployment
     ansible-playbook -i environments/kube couchdb.yml
-    # configure couch db
     ansible-playbook -i environments/kube initdb.yml
     ansible-playbook -i environments/kube wipe.yml
   fi
 
   # Run through the openwhisk deployment
   ansible-playbook -i environments/kube openwhisk.yml
+
+  # Post deploy step
+  ansible-playbook -i environments/kube postdeploy.yml
 popd
diff --git a/kubernetes/docker/build.sh b/kubernetes/docker/build.sh
index 0c1340d..f1dc30e 100755
--- a/kubernetes/docker/build.sh
+++ b/kubernetes/docker/build.sh
@@ -15,5 +15,69 @@ EndOfMessage
 exit 1
 fi
 
+
+OPENWHISK_DIR=""
+if [ -z "$2" ]; then
+cat <<- EndOfMessage
+  Second argument should be location of the OpenWhisk repo on the local
+  file system. By default, it is assumed to be at $HOME/workspace/openwhisk.
+EndOfMessage
+  OPENWHISK_DIR=$HOME/workspace/openwhisk
+else
+  OPENWHISK_DIR="$2"
+exit 1
+fi
+
+
 SOURCE="${BASH_SOURCE[0]}"
 SCRIPTDIR="$( dirname "$SOURCE" )"
+
+# build nginx
+pushd $SCRIPTDIR/nginx
+ pushd $OPENWHISK_DIR
+   ./gradlew tools:cli:distDocker
+ popd
+
+ # copy whisk cli to nginx directory
+ cp $OPENWHISK_DIR/bin/wsk .
+
+ mkdir -p blackbox
+ pushd blackbox
+   # copy docker sdk to dockerSkeleton in scratch space
+   cp $OPENWHISK_DIR/sdk/docker/buildAndPush.sh .
+   cp $OPENWHISK_DIR/sdk/docker/Dockerfile .
+   cp $OPENWHISK_DIR/sdk/docker/example.c .
+   cp $OPENWHISK_DIR/sdk/docker/README.md .
+
+   # rename base image in Dockerfile
+   sed -i "s|FROM dockerskeleton|FROM openwhisk/dockerskeleton|g" Dockerfile
+
+   # fix file permissions
+   chmod 0755 buildAndPush.sh
+
+   # build blackbox container artifact
+   tar -czf ../blackbox-0.1.0.tar.gz .
+ popd
+
+ NGINX_IMAGE=$(docker build . | grep "Successfully built" | awk '{print $3}')
+ docker tag $NGINX_IMAGE "$1"/whisk_nginx
+ docker push "$1"/whisk_nginx
+
+ # cleanup
+ rm wsk
+ rm blackbox-0.1.0.tar.gz
+ rm -rf blackbox
+popd
+
+# build the OpenWhisk deploy image
+pushd $SCRIPTDIR/..
+ # copy whisk cli
+ cp $OPENWHISK_DIR/bin/wsk .
+
+ WHISK_DEPLOY_IMAGE=$(docker build . | grep "Successfully built" | awk '{print $3}')
+ docker tag $WHISK_DEPLOY_IMAGE "$1"/whisk_config:dev
+ docker push "$1"/whisk_config:dev
+
+ # rm the whisk cli to keep things clean
+ rm wsk
+popd
diff --git a/kubernetes/docker/nginx/Dockerfile b/kubernetes/docker/nginx/Dockerfile
new file mode 100644
index 0000000..3a4e47b
--- /dev/null
+++ b/kubernetes/docker/nginx/Dockerfile
@@ -0,0 +1,4 @@
+FROM nginx:1.11
+
+COPY wsk /etc/nginx/cli/go/download/linux/amd64/wsk
+COPY blackbox-0.1.0.tar.gz /etc/nginx/blackbox-0.1.0.tar.gz

-- 
To stop receiving notification emails like this one, please contact
['"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>'].