Web Relay Ingress with Docker for Mac
Kubernetes became available in Docker for Mac 17.12 CE Edge. Kubernetes in the last year showed that it’s the most flexible and reliable option to run container workloads, all the major cloud providers now offer or are planning to offer a managed Kubernetes service to their customers:
- https://cloud.google.com/kubernetes-engine
- https://azure.microsoft.com/en-us/services/container-service
- https://aws.amazon.com/eks
- https://www.ibm.com/cloud/container-service
And some great companies that help you deploy and run your own cluster:
After visiting last KubeCon in Austin I have seen a huge increase in the number of companies that specialize in Kubernetes consulting. This list could go on and on :)
In this article we will:
- Enable Kubernetes support in your Docker for Mac.
- Create and deploy an example Node.js application.
- Use Web Relay ingress controller to share that app running inside our Mac to the world :)
Prerequisites:
- Docker for Mac 17.12 CE Edge.
- Webhook Relay account and relay client command.
kubectl
, the Kubernetes client command. It should be included and configured by the Docker for Mac.
If you are not using Mac or Docker for Mac you can still follow this tutorial step-by-step, just skip the “Enable Kubernetes in your Docker for Mac” section. This tutorial will work for ANY Kubernetes cluster as long as it has an Internet connectivity.
Getting started
Time to get our hands dirty! Feel free to skip a few things like enabling Kubernetes if you have already done it.
Enable Kubernetes in your Docker for Mac
To enable Kubernetes support inside your Docker for Mac, select Enable Kubernetes and click the Apply and restart button:
It should take a bit of time depending on the available Internet bandwidth and once it is done, it should report that the installation is complete. If you have any problems with this step, it might make sense to visit Docker documentation on this matter.
Unlike Minikube, Docker for Mac doesn’t hijack kubectl context, so you have to set it:
kubectl config use-context docker-for-desktop
Check whether your kubectl
is using the docker-for-desktop context.
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
minikube minikube minikube
* docker-for-desktop docker-for-desktop-cluster docker-for-desktop
Add ingress controller to your Docker for Mac Kubernetes
Add ingress controller:
relay ingress init
Output:
$ relay ingress init
using manifest from 'https://raw.githubusercontent.com/webrelay/ingress/master/deployment/deployment-rbac.yaml'...
namespace "webrelay-ingress" created
serviceaccount "webrelay" created
deployment "webrelay" created
clusterrolebinding "webrelay" created
clusterrole "webrelay" created
ingress added to the cluster, configuring authentication...
key and secret not supplied, generating new access credentials...
secret "webrelay-credentials" created
Yeah, some of you are probably now like:
But hold on, this command creates RBAC-enabled ingress controller in webrelay-ingress
namespace with already configured credentials for your account. You can read more about Web Relay ingress controller here.
Create your Node.js application
The next step is to write the application. Create a new directory named hello
with the filename server.js
:
var http = require('http');
var port = 8080
var handleRequest = function(request, response) {
console.log('Received request for URL: ' + request.url);
response.writeHead(200);
response.end('Hello Internet!');
};
var www = http.createServer(handleRequest);
console.log('Listening on http://localhost:' + port);
www.listen(port);
To run the application:
node server.js
You should be able to see your “Hello World!” message at http://localhost:8080/.
Stop the running Node.js server by pressing Ctrl-C.
The next step is to package your application in a Docker container.
Put your application into a Docker container
Create a file, also in the hello
directory, named Dockerfile. A Dockerfile describes the image that you want to build. You can build a Docker container image by extending an existing image. The image in this tutorial extends an existing Node.js image.
FROM node:9.2.0
EXPOSE 8080
COPY server.js .
CMD node server.js
This Dockerfile starts from the official Node.js image found in the Docker registry, exposes port 8080, copies your server.js file to the image and starts the Node.js server.
Build your Docker image:
docker build -t hello-node:v1 .
What is really nice about Docker for Mac with Kubernetes is that you can easily run locally built Docker images inside Kubernetes cluster. No need to change Docker daemons or push images to the public repositories just to test them out. Now Docker for Mac Kubernetes can run the image you built.
Create Deployment and Service
Kubernetes Deployments checks on the health of the Pods and restarts the Pod’s container if it terminates. Pod can consist of more than one containers but in this example we will only have one:
kubectl run hello-node --image=hello-node:v1 --port=8080
To view Deployments:
kubectl get deployments
Output:
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
hello-node 1 1 1 1 8s
Since by default Pod is only accessible by its internal IP address within the Kubernetes cluster, we need to expose it. Create a Service:
kubectl expose deployment hello-node --type=ClusterIP
To view created services:
kubectl get svc
Output:
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-node ClusterIP 10.102.194.95 <none> 8080/TCP 1m
Define ingress and expose your app to the Internet
Ingresses in Kubernetes provide an easy way to define routing rules between hostnames and services. Let’s get our public endpoint with relay
command client by creating a tunnel:
relay tunnel create --group webrelay-ingress hellonode
Output:
$ relay tunnel create --group webrelay-ingress hellonode
pis9izc72c1wd9i21gxqxm.webrelay.io<---->http://127.0.0.1
Parameter –group webrelay-ingress is required to let our ingress controller know which tunnels it can manage.
Note that users with paid plans can specify any custom subdomain (as long as it is not taken) without creating a tunnel first. This allows to just easily define
ingress.yaml
and ingress controller wil create a tunnel for it.
We are only interested in this pis9izc72c1wd9i21gxqxm.webrelay.io
(host) part. Every user gets a unique link to their tunnel. Edit this code with your tunnel hostname and save it in a folder named hello
with the filename ingress.yml
:
# ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: webrelay # other ingress classes will be ignored
name: relay-ingress
namespace: default
spec:
rules:
- host: pis9izc72c1wd9i21gxqxm.webrelay.io # <- host has to match tunnel host
http:
paths:
- path: /
backend:
serviceName: hello-node
servicePort: 8080
Create it:
kubectl create -f ingress.yml
Output:
$ kubectl create -f ingress.yml
ingress "relay-ingress" created
Your application is now exposed to the public Internet. See next section how to access or just enter that hostname into your browser.
Accessing your application through the Internet
To view existing ingresses:
relay ingress ls
Output:
relay ingress ls
ID NAME HOST BACKENDS CRYPTO AUTH AGE
58f26c61-8e42-45f4-a982-4cb70990d7e2 webrelay-ingress-pis9izc72c1wd9i21gxqxm.webrelay.io pis9izc72c1wd9i21gxqxm.webrelay.io default/hello-node/8080 off - 2 seconds
Backends column should show <namespace>/<service>/<port>
of the exposed service. You can access http://pis9izc72c1wd9i21gxqxm.webrelay.io with your browser (just change the link to your own tunnel address).
You can also use web UI at https://my.webhookrelay.com/tunnels to view your ingresses:
Wrapping up
In this article we created, deployed and exposed an app to the Internet that is running locally on our laptops. Some people say that this is an “actual hello world” application and not just the usual “hello localhost”.
With Docker for Mac Kubernetes support it’s now a lot easier to develop and test our applications. Build locally, run locally and demo locally. I hope Web Relay ingress controller will serve you great in developing, testing and running your apps.
As always, if you have any questions, feel free to contact me.