Explore the Ambassador API Gateway with MicroK8s

Alvaro Saurin
Ambassador Labs
Published in
4 min readJul 30, 2020

--

While there are multiple strategies for getting traffic into a Kubernetes cluster, the most common approach involves using an Ingress Controller. In this approach, traffic from outside the cluster is routed to an Ingress Controller, which then forwards packets to the appropriate in-cluster pods. This way, pods do not need to be directly exposed outside the cluster since the Ingress Controller provides a central point for observing and authenticating traffic into the cluster.

Ambassador API Gateway is an open-source ingress controller based on Envoy Proxy. Envoy Proxy is a Cloud-Native Computing Foundation project, with hundreds of contributors from companies such as Amazon, Airbnb, Google, Pinterest, and VMware. Ambassador exposes many of Envoy Proxy’s core features to Kubernetes users, including zero-downtime reloads, advanced traffic management, service mesh integrations (with support for Consul, Linkerd, and Istio), observability, TLS termination, and flexible APIs for rate limiting and authentication.

MicroK8s and Ambassador

MicroK8s is a lightweight upstream Kubernetes made by Canonical. MicroK8s is easy to install on a variety of platforms including Linux, Windows, Raspberry Pi, and macOS. With MicroK8s v1.19+ Ambassador API Gateway can be enabled with a single command allowing users to take advantage of its features. Ambassador has a lightweight resource footprint, making it a great fit for MicroK8s.

Enabling Ambassador on MicroK8s

You can install MicroK8s and enable Ambassador with:

$ sudo snap install microk8s --classic
$ sudo microk8s enable ambassador

Ambassador is now ready for use and acts as an Ingress Controller in your local cluster. You can try to expose any Service in your cluster by creating an Ingress resource for it. Note that Ambassador will only serve Ingress resources annotated with kubernetes.io/ingress.class: ambassador (otherwise they are just ignored).

Using Ambassador

In the following example, we create a app-v1 pod that serves a web page with app-v1. This pod is accessible through the app-v1-service and exposed to the outside world with a app-v1-ingress:

$ cat<<EOF | sudo microk8s.kubectl apply -f -
---
kind: Pod
apiVersion: v1
metadata:
name: app-v1-app
labels:
app: app-v1
spec:
containers:
- name: app-v1
image: hashicorp/http-echo:0.2.3
args:
- "-text={ \"version\": \"1\" }"
---
kind: Service
apiVersion: v1
metadata:
name: app-v1-service
spec:
selector:
app: app-v1
ports:
# Default port used by the image
- port: 5678
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app-v1-ingress
annotations:
kubernetes.io/ingress.class: ambassador
spec:
rules:
- http:
paths:
- path: /app
backend:
serviceName: app-v1-service
servicePort: 5678
EOF

You can now verify that the Ingress works with curl localhost/app:

While the Ingress resource is a good way to get started, the standard is fairly limited and also tightly couples the ingress configuration with routes. Most Ambassador users rely on a Mapping to describe routes. As you will see Mapping resources are fully decoupled from Ambassador configuration.

Mappings are key in implementing canary deployments, circuit breakers, automatic retries and more. In what follows we show how to employ canary deployments in upgrading our application from v1 to v2. We would be testing if both coexisting versions of our application work with our client before running a canary in a production environment.

We will first deploy the new version of our application, app-v2, with the following code:

$ cat<<EOF | sudo microk8s.kubectl apply -f -
---
kind: Pod
apiVersion: v1
metadata:
name: app-v2-app
labels:
app: app-v2
spec:
containers:
- name: app-v2-app
image: hashicorp/http-echo:0.2.3
args:
- "-text={ \"version\": \"2\" }"
---
kind: Service
apiVersion: v1
metadata:
name: app-v2-service
spec:
selector:
app: app-v2
ports:
- port: 5678
EOF

Now we create two Mappings for the same path, /app. One of the mappings leads to the app-v1 service while the other one takes 10% of the requests to the app-v2 Service. Ambassador balances weights to make sure that, for every resource, the Mappings for that path has weights adding to 100%

We load these mappings with:

$ cat<<EOF | sudo microk8s.kubectl apply -f -
---
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
name: app-v1
spec:
prefix: /app
service: app-v1-service:5678
---
apiVersion: getambassador.io/v2
kind: Mapping
metadata:
name: app-v2
spec:
prefix: /app
service: app-v2-service:5678
weight: 10
EOF

Now we can test that our client (in this case, it will be a simple curl) can continue working while a canary is running in the cluster:

Conclusion

Using a lightweight environment like MicroK8s, developers can easily replicate their production environments on their laptops. Ambassador is an easy-to-use ingress controller and API Gateway that completes this application-ready environment by providing the tools necessary to manage traffic routing, feature releases, and the full lifecycle of applications. Do not waste any more time, try it out now!

--

--

Senior Software Engineer specialized in delivering experimental projects into real products.