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_id
is 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.