|
| 1 | +# Deis Router v2 |
| 2 | + |
| 3 | +Deis (pronounced DAY-iss) is an open source PaaS that makes it easy to deploy and manage applications on your own servers. Deis builds on [Kubernetes](http://kubernetes.io/) to provide a lightweight, [Heroku-inspired](http://heroku.com) workflow. |
| 4 | + |
| 5 | +The router component, specifically, handles ingress and routing of HTTP/S traffic bound for the Deis API and for your own applications. This component is 100% Kubernetes native and is useful even without the rest of Deis! |
| 6 | + |
| 7 | +## Work in Progress |
| 8 | + |
| 9 | + |
| 10 | + |
| 11 | +Deis Router v2 is changing quickly. Your feedback and participation are more than welcome, but be aware that this project is considered a work in progress. |
| 12 | + |
| 13 | +## Hacking Router |
| 14 | + |
| 15 | +The only dependencies for hacking on / contributing to this component are: |
| 16 | + |
| 17 | +* `git` |
| 18 | +* `make` |
| 19 | +* `docker` |
| 20 | +* `kubectl`, properly configured to manipulate a healthy Kubernetes cluster that you presumably use for development |
| 21 | +* Your favorite text editor |
| 22 | + |
| 23 | +Although the router is written in Go, you do _not_ need Go or any other development tools installed. Any parts of the developer workflow requiring tools not listed above are delegated to a containerized Go development environment. |
| 24 | + |
| 25 | +### Registry |
| 26 | + |
| 27 | +If your Kubernetes cluster is running locally on one or more virtual machines, it's advisable to also run your own local Docker registry. This provides a place where router images built from source-- possibly containing your own experimental hacks-- can be pushed relatively quickly and can be accessed readily by your Kubernetes cluster. |
| 28 | + |
| 29 | +Fortunately, this is very easy to set up as long as you have Docker already functioning properly: |
| 30 | + |
| 31 | +``` |
| 32 | +$ make dev-registry |
| 33 | +``` |
| 34 | + |
| 35 | +This will produce output containing further instructions such as: |
| 36 | + |
| 37 | +``` |
| 38 | +59ba57a3628fe04016634760e039a3202036d5db984f6de96ea8876a7ba8a945 |
| 39 | +
|
| 40 | +To use a local registry for Deis development: |
| 41 | + export DEIS_REGISTRY=192.168.99.102:5000 |
| 42 | +``` |
| 43 | + |
| 44 | +Following those instructions will make your local registry usable by the various `make` targets mentioned in following sections. |
| 45 | + |
| 46 | +If you do not want to run your own local registry or if the Kubernetes cluster you will be deploying to is remote, then you can easily make use of a public registry such as [hub.docker.com](http://hub.docker.com), provided you have an account. To do so: |
| 47 | + |
| 48 | +``` |
| 49 | +$ export DEIS_REGISTRY=registry.hub.docker.com |
| 50 | +$ export IMAGE_PREFIX=your-username/ |
| 51 | +``` |
| 52 | + |
| 53 | +__Do not miss the trailing slash in the `IMAGE_PREFIX`!__ |
| 54 | + |
| 55 | + |
| 56 | +### If I can `make` it there, I'll `make` it anywhere... |
| 57 | + |
| 58 | +The entire developer workflow for anyone hacking on the router is implemented as a set of `make` targets. They are simple and easy to use, and collectively provide a workflow that should feel familiar to anyone who has hacked on Deis v1.x in the past. |
| 59 | + |
| 60 | +#### Setup: |
| 61 | + |
| 62 | +To "bootstrap" the development environment: |
| 63 | + |
| 64 | +``` |
| 65 | +$ make bootstrap |
| 66 | +``` |
| 67 | + |
| 68 | +In router's case, this step carries out some extensive dependency management using glide within the containerized development environment. Because the router leverages the Kubernetes API, which in turn has in excess of one hundred dependencies, this step can take quite some time. __Be patient, and allow up to 20 minutes. You generally only ever have to do this once.__ |
| 69 | + |
| 70 | + |
| 71 | +#### To build: |
| 72 | + |
| 73 | +``` |
| 74 | +$ make build |
| 75 | +``` |
| 76 | + |
| 77 | +Built images will be tagged with the sha of the latest git commit. __This means that for a new image to have its own unique tag, experimental changes should be committed _before_ building. Do this in a branch. Commits can be squashed later when you are done hacking.__ |
| 78 | + |
| 79 | +#### To deploy: |
| 80 | + |
| 81 | +``` |
| 82 | +$ make deploy |
| 83 | +``` |
| 84 | + |
| 85 | +The deploy target will implicitly build first, then push the built image (which has its own unique tags) to your development registry (i.e. that specified by `DEIS_REGISTRY`). A Kubernetes manifest is prepared, referencing the uniquely tagged image, and that manifest is submitted to your Kubernetes cluster. If a router component is already running in your Kubernetes cluster, it will be deleted and replaced with your build. |
| 86 | + |
| 87 | +To see that the router is running, you can look for its pod(s): |
| 88 | + |
| 89 | +``` |
| 90 | +$ kubectl get pods --namespace=deis |
| 91 | +``` |
| 92 | + |
| 93 | +## Trying it Out |
| 94 | + |
| 95 | +To deploy some sample routable applications: |
| 96 | + |
| 97 | +``` |
| 98 | +$ make examples |
| 99 | +``` |
| 100 | + |
| 101 | +This will deploy Nginx and Apache to your Kubernetes cluster as if they were user applications. |
| 102 | + |
| 103 | +To test, first modify your `/etc/hosts` such that the following four hostnames are resolvable to the IP of the Kubernetes node that is hosting the router: |
| 104 | + |
| 105 | +* nginx.example.com |
| 106 | +* apache.example.com |
| 107 | +* httpd.example.com |
| 108 | +* unknown.example.com |
| 109 | + |
| 110 | +By requesting the following three URLs from your browser, you should find that one is routed to a pod running Nginx, while the other two are routed to a pod running Apache: |
| 111 | + |
| 112 | +* http://nginx.example.com |
| 113 | +* http://apache.example.com |
| 114 | +* http://httpd.example.com |
| 115 | + |
| 116 | +Requesting http://unknown.example.com should result in a 404 from the router since no route exists for that domain name. |
| 117 | + |
| 118 | +## How it Works |
| 119 | + |
| 120 | +The router is implemented as a simple Go program that manages Nginx and Nginx configuration. It regularly queries the Kubernetes API for services labeled with `routable=true`. Such services are compared to known services resident in memory. If there are differences, new Nginx configuration is generated and Nginx is reloaded. |
| 121 | + |
| 122 | +When generating configuration, the program parses structured data (JSON) found in each service's `routerConfig` annotation. This data describes all the configuration options that allow the program to dynamically construct Nginx configuration, including virtual hosts for all the domain names associated with each routable application. |
| 123 | + |
| 124 | +Similarly, the router watches its _own_ `routerConfig` annotations to dynamically construct global Nginx configuration. |
| 125 | + |
| 126 | +## License |
| 127 | + |
| 128 | +Copyright 2013, 2014, 2015 Engine Yard, Inc. |
| 129 | + |
| 130 | +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> |
| 131 | + |
| 132 | +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. |
0 commit comments