The official Kubernetes walkthrough guides often points to the guestbook application as a quintessential example of how a simple, but complete multi-tier web application can be deployed with Kubernetes. As described in the README, it consists of a web frontend, a redis master (for storage), and a replicated set of redis 'slaves'.

This seemed like an ideal starting point for deploying my Flask applications with a similar stack, and also makes use of redis master/slaves. The difficulty I found with readily making use of this example as a starting point is that the frontend is implemented in PHP, which is considerably different to modern paradigms (Node.js, Flask/Django, Rails, etc.) As described in the README:

A frontend pod is a simple PHP server that is configured to talk to either the slave or master services, depending on whether the client request is a read or a write. It exposes a simple AJAX interface, and serves an Angular-based UX. Again we'll create a set of replicated frontend pods instantiated by a Deployment — this time, with three replicas.

I figured re-implementing the frontend pod in with Flask would require minimal changes - the UI would remain mostly the same, and the actual interaction with the redis master/slaves is quite trivial.

Perhaps the biggest challenge is that the PHP server can be served with a HTTP server (the example uses Apache), alongside the static assets ( index.html , controller.js , etc.) while Flask will require a WSGI server, in addition to a HTTP/reverse proxy server. This means the frontend pod will have multiple containers. A common practice for deploying Flask applications is to use uWSGI as the WSGI server with NGINX as the reverse proxy.

First we fork from the official Kubernetes repo and create an exact copy of the guestbook example:

$ git clone https://github.com/ltiao/kubernetes $ cd kubernetes/examples/ $ cp -r guestbook guestbook-flask

The current directory structure looks like this:

$ tree guestbook-flask guestbook-flask ├── README.md ├── all-in-one │ ├── frontend.yaml │ ├── guestbook-all-in-one.yaml │ └── redis-slave.yaml ├── frontend-deployment.yaml ├── frontend-service.yaml ├── legacy │ ├── frontend-controller.yaml │ ├── redis-master-controller.yaml │ └── redis-slave-controller.yaml ├── php-redis │ ├── Dockerfile │ ├── controllers.js │ ├── guestbook.php │ └── index.html ├── redis-master-deployment.yaml ├── redis-master-service.yaml ├── redis-slave │ ├── Dockerfile │ └── run.sh ├── redis-slave-deployment.yaml └── redis-slave-service.yaml 4 directories, 19 files

Let's track these files:

$ git add guestbook-flask/

Updating the Frontend Deployment Lastly, we modify the frontend Deployment to replace the existing container in the frontend Pod with the containers we just created and pushed. $ vim guestbook-flask/frontend-deployment.yaml Under .spec.template.spec.containers , add the following containers: containers : - name : flask-redis image : tiao/gb-frontend-flask-redis resources : requests : cpu : 100m memory : 100Mi env : - name : GET_HOSTS_FROM value : dns # If your cluster config does not include a dns service, then to # instead access environment variables to find service host # info, comment out the 'value: dns' line above, and uncomment the # line below. # value: env ports : - containerPort : 8080 - name : nginx image : tiao/gb-frontend-nginx ports : - containerPort : 80 The change should look exactly like this: --- guestbook/frontend-deployment.yaml 2016-06-02 14:01:30.000000000 +1000 +++ guestbook-flask/frontend-deployment.yaml 2016-06-02 16:56:24.000000000 +1000 @@ -24,8 +24,8 @@ tier: frontend spec: containers: - - name: php-redis - image: gcr.io/google-samples/gb-frontend:v4 + - name: flask-redis + image: tiao/gb-frontend-flask-redis resources: requests: cpu: 100m @@ -39,4 +39,8 @@ # line below. # value: env ports: + - containerPort: 8080 + - name: nginx + image: tiao/gb-frontend-nginx + ports: - containerPort: 80 We also update the "all-in-one" variants of these configurations in exactly the same way: $ vim guestbook-flask/all-in-one/frontend.yaml $ vim guestbook-flask/all-in-one/guestbook-all-in-one.yaml At last, we can create all related Deployments and Services: $ kubectl create -f guestbook-flask deployment "frontend" created service "frontend" created deployment "redis-master" created service "redis-master" created deployment "redis-slave" created service "redis-slave" created Now you should be able to see a live, running Guestbook example with functionality and behavior identical to that of the original PHP implementation.