Draft for Kubernetes - A Prototyping Tool
By
Jack Zampolin /
Developer
Jun 06, 2017
Navigate to:
Overview
Draft for Kubernetes is a tool to help prototype microservices and expose them on a publicly available domain. This makes quickly iterating on things like webhooks or APIs quick and painless. Draft utilizes docker, Helm, and Kubernetes Ingress Controllers to make your ‘drafts’ publicly available in a hurry. Under the hood, it generates a generic Dockerfile
and helm chart for your application to get you up and running quickly. The helm chart creates an ingress resource to expose your chart at a url. You will need the following running for this walkthrough:
- A Kubernetes Cluster
- I've developed this walkthrough on GKE.
- It's pretty easy to get up and running there.
- A domain name you can add A or CNAME records to
- An account at quay.io or hub.docker
- A working Helm installation
- Install instructions can be found here.
- A golang development environment
- Draft also supports basic python, ruby, php, node, and java applications.
In this walkthrough, we are going to first install the dependencies for Draft, then create our sample application, install Draft and deploy our app.
Installing Draft Dependencies
An Ingress Controller creates a loadBalancer with a Public IP (or a CNAME record on AWS) to expose your applications to the internet. It is a quick and secure abstraction for routing traffic into the applications running on your cluster. To install an Ingress Controller, use the Nginx Ingress provided by helm:
# Install Ingress Controller
$ helm install stable/nginx-ingress --namespace=kube-system --name=nginx-ingress
# Wait for load balancer to have IP
$ kubectl --namespace kube-system get services -w nginx-ingress-nginx-ingress-controller
# If you have an existing ingress controller find its IP
echo $(kubectl get svc --namespace kube-system nginx-ingress-nginx-ingress-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
Once you get the IP or CNAME you can create the appropriate DNS record. Make it something like *.draft.mydomain.mytld
. The steps to do this will vary depending on where your domain is registered. I use What’s My DNS to check propagation. Once you see that the change has propagated, you should get the following response from curl:
$ curl foo.draft.mydomain.mytld
default backend - 404
Note: If you want to know more about default backends, I've found this article scintillating reading.
Prepare Golang App
Make a new project directory and create a golang application. I’ve used a simple server:
// main.go
package main
import (
"log"
"net/http"
)
func sayHello(w http.ResponseWriter, r *http.Request) {
message := "hello world\n"
w.Write([]byte(message))
}
func main() {
http.HandleFunc("/", sayHello)
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
You will also want to add some type of dependency management to your application. This is because of the script Draft uses to detect different application types. The golang pack looks to see if there is a glide.yaml
, Godeps/Godeps.json
, or vendor/vendor.json
file in your project. If you are using glide, a simple glide create
will satisfy this requirement.
Install Draft
Download the draft binary for your OS and move it into your path. After that you will need to run draft init
with some arguments:
draft init --set
registry.url=docker.io,
registry.org=mydockerorg,
registry.authtoken=$(echo '{"username":"myDockerUsername","password":"myDockerPassword","email":"[email protected]"}' | base64),
basedomain=mydomain.mytld
Note: Be sure to run the above command all on one line with no spaces between the different key=value
pairs! Also, I had some trouble getting the Google Container Registry to work, but it seems to be supported.
This spins up a draftd
deployment and some draft pods in your kube-system namespace. These help manage the connection with the docker image repository.
Deploy Your App!
Phew! That was a lot of setup! Now that this is done, it’s time to use Draft! The first command to run is draft create
. That will scaffold out your helm chart (/chart
) and /Dockerfile
. It will also create a draft.toml
that allows you to control different environments for your application as well as where it is installed in your cluster. To give your app a name (the default works just fine too!) edit draft.toml
:
[environments]
[environments.development]
name = "cool-beans"
namespace = "draft"
watch = true
watch_delay = 2
Then run draft up
and watch the magic happen:
$ draft up
--> Building Dockerfile
Step 1 : FROM golang:onbuild
# Executing 3 build triggers...
Step 1 : COPY . /go/src/app
Step 1 : RUN go-wrapper download
---> Running in 825771ecaf59
...
# Some docker output...
...
--> Deploying to Kubernetes
--> Status: DEPLOYED
--> Notes:
http://cool-beans.mydomain.mytld to access your application
Watching local files for changes...
This will build your docker image, push your docker image to the configured container registry under the {{ .environments.development.name }}
repository, and run helm install
on the preconfigured helm chart at the root of the repo! It might take a second for all the resources to spin up and for the Ingress to register your new application, but you will be able to curl your application at that address:
$ curl http://cool-beans.mydomain.mytld
hello world
But, to see the real magic, make a change to your application:
// main.go
func sayHello(w http.ResponseWriter, r *http.Request) {
message := "I don't know Margo...\n"
w.Write([]byte(message))
}
Draft will rebuild your image and push those changes live with a helm upgrade
:
$ curl http://cool-beans.mydomain.mytld
I don't know Margo...
Hooking in a datasource or performing more advanced actions is just a handler edit away now!