Ambassador is an open-source API Gateway and Ingress controller based on Envoy Proxy.
In this repository, we have pre-configured a number of Kubernetes manifests so that you can quickly get a deployment of Ambassador up and running to test.
To get started, clone the repository:
git clone https://github.com/datawire/amb-config-
Add repository.
helm repo add datawire https://getambassador.io && helm repo update -
Install Ambassador API Gateway.
Helm v3:
helm install ambassador datawire/ambassador --set image.repository=datawire/ambassador --set enableAES=false --set namespace.name=default
Helm v2: (assumes you already have tiller)
helm install --name ambassador --namespace default datawire/ambassador --set image.repository=datawire/ambassador --set enableAES=false
-
Test that Ambassador is working by navigating to the Diagnostics page. Navigate to
http://{{AMBASSADOR_HOST}}/ambassador/v0/diag/in your browser. Note this endpoint can be disabled by settingdiagnostics.enabled: falsein an Ambassador Module.
Now, we will be deploying a sample service that outputs a simple Quote of the Moment. We will then create an Ingress that connects to this service to test Ambassador's capacity as an Ingress controller.
-
Deploy the Quote microservice.
kubectl apply -f ingress/quote.yaml
-
Deploy a simple Ingress. Note this Ingress applies both pathtypes, a Prefix:
/quoteand an Exact Match:/exact-quote/to show the support Ambassador has for the Kubernetes 1.18 ingress enhancements.kubectl apply -f ingress/simple-ingress.yaml
-
Test with curl.
curl http://{{ambassador_host}}/quote/and
curl http://{{ambassador_host}}/backend/get-quote/
In this tutorial, we will deploy a basic Auth service for user validation to Microservices.
-
Deploy the external
auth-service. This is a simple auth service that listens on port 3000, uses only username: username, pw: password, and only implements auth on/backend/get-quote/. See implementation at: https://github.com/datawire/ambassador-auth-service.kubectl apply -f auth/auth-service.yaml
-
Configure Ambassador to communicate with the external
auth-serviceover HTTP/REST. This is done with theAuthServiceCRD.kubectl apply -f auth/amb-auth-service.yaml
-
Test implementation. Without credentials, we'll get an HTTP 401 error:
curl -Lv http://{{ambassador_host}}/backend/get-quote/We can successfully authenticate to the service by supplying credentials:
curl -Lv -u username:password http://{{ambassador_host}}/backend/get-quote/
Up until this point, we have been running Ambassador in a totally unencrypted http environment. Naturally this is not a good practice
in a production environment, so we will want to start generating certificates and terminating TLS. To manage our certificates, we
will be using cert-manager with an http-01 challenge. If you can't easily register a domain, nip.io will let you create an FQDN with just an IP address.
-
Add repository.
helm repo add jetstack https://charts.jetstack.io && helm repo update -
Install
cert-manager.Helm v3:
helm install cert-manager jetstack/cert-manager --namespace default --version v0.15.0 --set installCRDs=true
Helm v2:
helm install --name cert-manager --namespace default --version v0.15.0 jetstack/cert-manager --set installCRDs=true
-
Create a ClusterIssuer.
kubectl apply -f cert-manager/cluster-issuer.yaml
-
Create a Certificate.
kubectl apply -f cert-manager/certificate.yaml
-
Tell Ambassador where to send the challenge.
kubectl apply -f cert-manager/cert-ingress.yaml
-
Create Host.
kubectl apply -f cert-manager/host.yaml
-
Test TLS.
curl -Lv -u username:password http://{{ambassador_host}}/backend/get-quote/You will notice that it redirects from HTTP to HTTPS automatically. To configure more advanced routing behaviours, see Host documentation.
Ambassador can route TCP traffic directly from specified ports to services in your cluster. To demonstrate this, we will use a busybox deployment to netcat from our local machine to the cluster, creating a direct TCP route.
-
Deploy busybox.
kubectl apply -f layer4/busybox.yaml
-
Update the Ambassador deployment to open the new port, in this case 30080.
helm upgrade ambassador -f layer4/values.yaml datawire/ambassador
-
Apply TCPMapping.
kubectl apply -f layer4/tcp-mapping.yaml
-
Start netcat listener on the busybox pod in a separate terminal.
kubectl exec -it {{busybox_pod}} -- nc -lvnp 30080 -
Start netcat client.
nc -v {{ambassador IP}} 30080 -
Type away! Any line typed into stdin can be seen in the other terminal that's listening.
Ambassador natively supports gRPC routing. In this example, we will deploy a simple gRPC hello service and connect to it. The example client requires clear-text routing, so an additional Host is also needed. This example also assumes you have the relevant Python pip modules installed for gRPC.
-
Deploy the gRPC server.
kubectl apply -f layer7/hello-grpc.yaml
-
Create a new host for cleartext. I used a different hostname than previous examples (i.e. cleartext.ip.nip.io).
kubectl apply -f layer7/host.yaml
-
Start client service, make sure to edit greeter_client.py with your hostname.
python layer7/greeter_client.py
A successful response will return 'Hello, you!'.
SNI support is also natively supported by Ambassador. In this example we will deploy a hello service alongside the existing quote service. Two separate hostnames will be used to route traffic to the respective service using Ingresses.
-
Deploy hello service.
kubectl apply -f sni/hello.yaml
-
Create new certificates for your hosts.
kubectl apply -f sni/certificate-sni.yaml
-
Once the certs are updated, create new hosts.
kubectl apply -f sni/host-sni.yaml
-
Create Ingresses to map the services.
kubectl apply -f sni/ingress-sni.yaml
-
Test each hostname to see them resolve to different services.
curl -Lv https://host1.example.com/
And
curl -Lv https://host2.example.com/
