In the Cloud Native world, the use of proxies is growing in popularity. One such use-case for a proxy is to support API gateway functionality. Ambassador is one of these API gateways. Read on to learn more!

What is Ambassador?
Ambassador is an open-source API gateway based on the Envoy proxy and meant for k8s environments. It was created by the Datawire team to support primarily North/South traffic within a distributed architecture running on k8s. Ambassador is a configuration wrapper for Envoy. It was created because native Envoy configuration is hard to understand and configure properly.
Basics
Different Ambassador instances can run within an environment by specifying different IDs. For example, from a deployment.yaml:
...
spec:
template:
spec:
containers:
- env:
- name: AMBASSADOR_ID
value: myID
...
Configuration is done via annotations in k8s. Here is an example of a mapping:
apiVersion: v1
kind: Service
metadata:
annotations:
getambassador.io/config: |
---
apiVersion: ambassador/v0
kind: Mapping
name: test-mapping
ambassador_id: myID
prefix: /
host: test-mapping.default.svc.cluster.local
service: test-mapping.test.svc.cluster.local
...
Note, prior to version 0.50.0, configuration could also be done via configmaps, but this is no longer supported.
Ambassador can be configured to route authentication traffic to a dedicated authentication service. If this is configured then EVERY call goes to the authentication service first and must return a status code of 200 before being routed downstream:
---
apiVersion: v1
kind: Service
metadata:
annotations:
getambassador.io/config: |
---
apiVersion: ambassador/v0
kind: Module
name: ambassador
ambassador_id: myID
---
apiVersion: ambassador/v0
kind: Module
name: tls
ambassador_id: myID
config:
server:
enabled: True
...
---
apiVersion: v1
kind: Service
metadata:
annotations:
getambassador.io/config: |
---
apiVersion: ambassador/v0
ambassador_id: myID
kind: AuthService
name: authentication
auth_service: "auth:3000"
path_prefix: "/auth/api/check"
---
apiVersion: ambassador/v0
kind: Mapping
ambassador_id: myID
name: auth
prefix: /auth/
rewrite: /auth/
service: auth:3000
...
Given Ambassador is based on Envoy, it supports the majority of features that Envoy does. This includes things like tracing:
apiVersion: v1
kind: Service
metadata:
annotations:
getambassador.io/config: |
---
apiVersion: ambassador/v0
kind: Module
name: ambassador
ambassador_id: myID
---
apiVersion: ambassador/v0
kind: TracingService
name: tracing
ambassador_id: myID
service: collector.default.svc.cluster.local:9411
driver: zipkin
...
From a monitoring perspective, statsd is supported and can be converted to Prometheus format (from a deployment.yaml):
...
spec:
containers:
- env:
- name: STATSD_ENABLED
value: "true"
- args:
- --statsd.listen-udp=:8125
- --statsd.mapping-config=/statsd-exporter/mapping-config.yaml
image: prom/statsd-exporter:v0.7.0
imagePullPolicy: IfNotPresent
name: statsd-sink
ports:
- containerPort: 9102
name: metrics
protocol: TCP
- containerPort: 8125
name: listener
protocol: TCP
volumeMounts:
- mountPath: /statsd-exporter/
name: stats-exporter-mapping-config
readOnly: true
...
A Grafana dashboard exists specifically for Ambassador:

Gotchas
After using Ambassador for a while I figured I would share some gotchas I have experienced along the way:
- If configuration is not working ensure the proper
ambassador_idis specified and any configuration names are unique (e.g. if you have multiple mappings) - If you are using configmaps you should be moving off. In any case, any changes to a configmap requires a restart of all impacted Ambassador pods to take effect.
- If things are not working and you cannot track it down use the diagnostics page — the UI will highlight issues and in worst case debug logging will usually help pinpoint the issue.
- If it is not in the documentation do not expect it to work — while Ambassador is based on Envoy and certain Envoy overrides can be applied, they are limited at best. If what you are trying to do is not in the documentation then it is unlikely to be available or supported.
- I have run into issues where upgrading a deployment (not service) results in gateway timeouts — the workaround is to kick the impacted Ambassador pods (issue appears to be routing to non-existing pods).
Summary
If you are look for an API gateway optimized for north/south traffic on k8s then Ambassador is a solid choice. Ambassador is based on the production ready Envoy proxy and offers many of the same features. The latest information about Ambassador, check the documentation.
© 2019 – 2018, Steve Flanders. All rights reserved.
