Wednesday, July 3, 2024
HomeServerContainersInstall Ambassador Ingress Controller on Kubernetes

Install Ambassador Ingress Controller on Kubernetes

Kubernetes has afforded many enterprises the robustness, the resilience, the efficiency, reliability, scale and all of those sweet words that were literally difficult to achieve in the past. What is worth mentioning is that it has significantly reduced operational expenses while bringing more to the table. With this, everyone is happy. The developers enjoy the simplicity and speed it provides while the finance department has no reason to lament because they are spared from spending on extra servers quite often.

As you know, applications on your Kubernetes cluster can be accessed by outside clients in three avenues. You can configure your services to be exposed through NodePorts, LoadBalancers or by employing an Ingress Controller in your Cluster. In this guide, we are going to setup one of the many Ingress Controllers available. We are going to install Ambassador API Gateway & Ingress Controller then use it to access services deployed in your cluster. It is going to be a wonderful errand. Make sure your juices are ready for sipping along the way.

To begin, we shall acquaint ourselves with this tool then go ahead and leverage it powerful features. From its GitHub Page, Ambassador API Gateway is an open-source Kubernetes-native API Gateway + Layer 7 load balancer + Kubernetes Ingress built on Envoy Proxy. The Ambassador Edge Stack is a complete superset of the OSS Ambassador API Gateway that offers additional functionality. Ambassador is designed to easily expose, secure, and manage traffic to your Kubernetes microservices of any type. Ambassador was built around the ideas of self-service (enabling GitOps-style management) and comprehensiveness (so it works with your situations and technology solutions).

Briefly, the Ambassador API Gateway enables its users to:

  • Manage ingress traffic with load balancing, protocol support(gRPC and HTTP/2, TCP, and web sockets), and Kubernetes integration
  • Manage changes to routing with an easy to use declarative policy engine and self-service configuration, via Kubernetes CRDs or annotations
  • Secure microservices with authentication, rate limiting, TLS, automatic HTTPS, and custom request fiters
  • Ensure high availability with sticky sessions, rate limiting, and circuit breaking
  • Leverage observability with integrations with Grafana, Prometheus, and Datadog, and comprehensive metrics support
  • Set up shared development environments with Service Preview
  • Onboard developers with a Developer Portal
  • Enable progressive delivery with canary releases
  • Connect service meshes including Consul, Linkerd, and Istio
  • Knative serverless integration

If you prefer Traefik / Nginx Ingress controllers see guides below:

Pre-requisites

For us to be able to install Ambassador API Gateway & Ingress Controller, we are assuming you already have a running Kubernetes cluster. In case you do not have one already running, you can use our previous guides below to bootstrap one as quickly as you can.

Also ensure that you can run kubectl command on your user account.

Step 1: Get Ambassador Installation files

Once we download Ambassador manifest files, there are two ways that we can install Ambassador Ingress. One way is installing and exposing it via a NodePort and the other way is installing and exposing it via a LoadBalancer. As you can guess, if you are within an infrastructure that has a LoadBalancer such as in AWS, GCP and others, the best approach is utilizing the LoadBalancer Type. For on-premise setup check out our guide on installing MetalLB:

On the other hand, if you have a cluster without any Load Balancer, then using a NodePort to expose your Ingress Controller is still fine. Download the files as follows

mkdir ~/ambassador && cd ~/ambassador 
wget https://app.getambassador.io/yaml/edge-stack/latest/aes-crds.yaml
wget https://app.getambassador.io/yaml/edge-stack/latest/aes.yaml

Now edit the “aes.yaml” file by changing LoadBalancer to NodePort in case you have no LoadBalancer resource. Look for the ambassador service beginning at around line 206. In the spec section, you have the liberty to choose NodePort or leave is as LoadBalancer. For this example, we are going to use NodePort.

$ vim aes.yaml
apiVersion: v1
kind: Service
metadata:
  name: edge-stack
  namespace: ambassador
....
spec:
  #type: LoadBalancer
  type: NodePort
  ports:
....

Edit the file accordingly, save it then exit

Step 2: Deploy Ambassador on Kubernetes

Once the edits are done to your satisfaction, what remains is to simply apply the manifests into out Kubernetes Setup.

Create custom resources:

$ kubectl apply -f aes-crds.yaml
customresourcedefinition.apiextensions.k8s.io/filterpolicies.getambassador.io created
customresourcedefinition.apiextensions.k8s.io/filters.getambassador.io created
customresourcedefinition.apiextensions.k8s.io/ratelimits.getambassador.io created
customresourcedefinition.apiextensions.k8s.io/authservices.getambassador.io created
customresourcedefinition.apiextensions.k8s.io/consulresolvers.getambassador.io created
customresourcedefinition.apiextensions.k8s.io/devportals.getambassador.io created
customresourcedefinition.apiextensions.k8s.io/hosts.getambassador.io created
customresourcedefinition.apiextensions.k8s.io/kubernetesendpointresolvers.getambassador.io created
customresourcedefinition.apiextensions.k8s.io/kubernetesserviceresolvers.getambassador.io created
customresourcedefinition.apiextensions.k8s.io/listeners.getambassador.io created
customresourcedefinition.apiextensions.k8s.io/logservices.getambassador.io created
customresourcedefinition.apiextensions.k8s.io/mappings.getambassador.io created
customresourcedefinition.apiextensions.k8s.io/modules.getambassador.io created
customresourcedefinition.apiextensions.k8s.io/ratelimitservices.getambassador.io created
customresourcedefinition.apiextensions.k8s.io/tcpmappings.getambassador.io created
customresourcedefinition.apiextensions.k8s.io/tlscontexts.getambassador.io created
customresourcedefinition.apiextensions.k8s.io/tracingservices.getambassador.io created
namespace/emissary-system created
serviceaccount/emissary-apiext created
clusterrole.rbac.authorization.k8s.io/emissary-apiext created
clusterrolebinding.rbac.authorization.k8s.io/emissary-apiext created
role.rbac.authorization.k8s.io/emissary-apiext created
rolebinding.rbac.authorization.k8s.io/emissary-apiext created
service/emissary-apiext created
deployment.apps/emissary-apiext created

Then other objects

$ kubectl apply -f aes.yaml
namespace/ambassador created
serviceaccount/edge-stack-agent created
serviceaccount/edge-stack created
secret/edge-stack created
clusterrole.rbac.authorization.k8s.io/edge-stack-agent created
clusterrole.rbac.authorization.k8s.io/edge-stack-agent-pods created
clusterrole.rbac.authorization.k8s.io/edge-stack-agent-deployments created
clusterrole.rbac.authorization.k8s.io/edge-stack-agent-endpoints created
clusterrole.rbac.authorization.k8s.io/edge-stack-agent-configmaps created
clusterrole.rbac.authorization.k8s.io/edge-stack-agent-rollouts created
clusterrole.rbac.authorization.k8s.io/edge-stack-agent-applications created
clusterrole.rbac.authorization.k8s.io/edge-stack created
clusterrole.rbac.authorization.k8s.io/edge-stack-crd created
clusterrole.rbac.authorization.k8s.io/edge-stack-watch created
clusterrole.rbac.authorization.k8s.io/edge-stack-aes created
clusterrolebinding.rbac.authorization.k8s.io/edge-stack-agent created
clusterrolebinding.rbac.authorization.k8s.io/edge-stack created
role.rbac.authorization.k8s.io/edge-stack-agent-config created
rolebinding.rbac.authorization.k8s.io/edge-stack-agent-config created
service/edge-stack-admin created
service/edge-stack created
service/edge-stack-redis created
deployment.apps/edge-stack-agent created
deployment.apps/edge-stack created
deployment.apps/edge-stack-redis created
authservice.getambassador.io/edge-stack-auth created
mapping.getambassador.io/edge-stack-devportal created
mapping.getambassador.io/edge-stack-devportal-assets created
mapping.getambassador.io/edge-stack-devportal-demo created
mapping.getambassador.io/edge-stack-devportal-api created
ratelimitservice.getambassador.io/edge-stack-ratelimit created

Confirm that the pods were deployed Successfully

$ kubectl get pods -n ambassador
NAME                                READY   STATUS    RESTARTS   AGE
edge-stack-66ff55b978-vjm4m         1/1     Running   0          33m
edge-stack-agent-776cf8fbcd-gffl7   1/1     Running   0          33m
edge-stack-redis-75d95f7cdf-7xg8j   1/1     Running   0          33m

Check the CRDs. Note that the list below has been truncated

$ kubectl get crd -n ambassador                                                                           
NAME                                                  CREATED AT
addresspools.metallb.io                               2022-12-17T17:00:21Z
alertmanagerconfigs.monitoring.coreos.com             2022-12-21T08:38:12Z
alertmanagers.monitoring.coreos.com                   2022-12-21T08:38:12Z
authservices.getambassador.io                         2023-03-10T10:57:21Z
awxbackups.awx.ansible.com                            2023-02-08T22:48:20Z
awxrestores.awx.ansible.com                           2023-02-08T22:48:20Z
awxs.awx.ansible.com                                  2023-02-08T22:48:20Z
bfdprofiles.metallb.io                                2022-12-17T17:00:21Z
bgpadvertisements.metallb.io                          2022-12-17T17:00:21Z
bgpconfigurations.crd.projectcalico.org               2022-12-14T00:13:23Z
bgppeers.crd.projectcalico.org                        2022-12-14T00:13:23Z
bgppeers.metallb.io                                   2022-12-17T17:00:21Z
blockaffinities.crd.projectcalico.org                 2022-12-14T00:13:23Z
caliconodestatuses.crd.projectcalico.org              2022-12-14T00:13:23Z
clusterinformations.crd.projectcalico.org             2022-12-14T00:13:23Z
communities.metallb.io                                2022-12-17T17:00:21Z
consulresolvers.getambassador.io                      2023-03-10T10:57:21Z
devportals.getambassador.io                           2023-03-10T10:57:21Z
felixconfigurations.crd.projectcalico.org             2022-12-14T00:13:23Z
filterpolicies.getambassador.io                       2023-03-10T10:57:21Z
filters.getambassador.io                              2023-03-10T10:57:21Z
globalnetworkpolicies.crd.projectcalico.org           2022-12-14T00:13:23Z
globalnetworksets.crd.projectcalico.org               2022-12-14T00:13:23Z
hostendpoints.crd.projectcalico.org                   2022-12-14T00:13:23Z
hosts.getambassador.io                                2023-03-10T10:57:21Z
ingressroutes.traefik.containo.us                     2023-03-08T14:32:55Z
ingressroutetcps.traefik.containo.us                  2023-03-08T14:32:55Z
ingressrouteudps.traefik.containo.us                  2023-03-08T14:32:55Z
ipaddresspools.metallb.io                             2022-12-17T17:00:22Z
ipamblocks.crd.projectcalico.org                      2022-12-14T00:13:23Z
ipamconfigs.crd.projectcalico.org                     2022-12-14T00:13:23Z
ipamhandles.crd.projectcalico.org                     2022-12-14T00:13:23Z
ippools.crd.projectcalico.org                         2022-12-14T00:13:24Z
ipreservations.crd.projectcalico.org                  2022-12-14T00:13:24Z
kubecontrollersconfigurations.crd.projectcalico.org   2022-12-14T00:13:24Z
kubernetesendpointresolvers.getambassador.io          2023-03-10T10:57:21Z
kubernetesserviceresolvers.getambassador.io           2023-03-10T10:57:21Z
l2advertisements.metallb.io                           2022-12-17T17:00:22Z
listeners.getambassador.io                            2023-03-10T10:57:21Z
logservices.getambassador.io                          2023-03-10T10:57:21Z
mappings.getambassador.io                             2023-03-10T10:57:21Z
middlewares.traefik.containo.us                       2023-03-08T14:32:55Z
middlewaretcps.traefik.containo.us                    2023-03-08T14:32:55Z
modules.getambassador.io                              2023-03-10T10:57:21Z
networkpolicies.crd.projectcalico.org                 2022-12-14T00:13:24Z
networksets.crd.projectcalico.org                     2022-12-14T00:13:24Z
podmonitors.monitoring.coreos.com                     2022-12-21T08:38:12Z
probes.monitoring.coreos.com                          2022-12-21T08:38:12Z
prometheuses.monitoring.coreos.com                    2022-12-21T08:38:12Z
prometheusrules.monitoring.coreos.com                 2022-12-21T08:38:12Z
ratelimits.getambassador.io                           2023-03-10T10:57:21Z
ratelimitservices.getambassador.io                    2023-03-10T10:57:21Z
serverstransports.traefik.containo.us                 2023-03-08T14:32:55Z
servicemonitors.monitoring.coreos.com                 2022-12-21T08:38:12Z
tcpmappings.getambassador.io                          2023-03-10T10:57:21Z
thanosrulers.monitoring.coreos.com                    2022-12-21T08:38:12Z
tlscontexts.getambassador.io                          2023-03-10T10:57:21Z
tlsoptions.traefik.containo.us                        2023-03-08T14:32:55Z
tlsstores.traefik.containo.us                         2023-03-08T14:32:55Z
tracingservices.getambassador.io                      2023-03-10T10:57:21Z
traefikservices.traefik.containo.us                   2023-03-08T14:32:55Z

As well as the Services

$ kubectl get svc -n ambassador
NAME               TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)                      AGE
edge-stack         LoadBalancer   10.233.62.180   192.168.1.35   80:32437/TCP,443:32522/TCP   33m
edge-stack-admin   ClusterIP      10.233.3.10     <none>         8877/TCP,8005/TCP            33m
edge-stack-redis   ClusterIP      10.233.62.70    <none>         6379/TCP                     33m

You can also determin the IP address or hostname of your cluster by running the following command:

kubectl get -n ambassador service edge-stack -o "go-template={{range .status.loadBalancer.ingress}}{{or .ip .hostname}}{{end}}"

If you are using NodePort, you will notice two ports assigned to ambassador service. One is for pure http and another is for https.

You can access Ambassador Dashboard by pointing your browser to

https://anynodeip-or-FQDN:NodePort

Ambassador

The ingress resource will now make it possible to expose multiple services using a singular external endpoint, a load balancer, or both at once. Taking this approach, teams can enact host, prefix, and other rules to route traffic to defined services however they prefer.

Step 3: Install Sample application and expose via Ingresss Controller

In this step, we are going to deploy httpbin and nginx applications then use our installed Ambassador Ingress controller to access them.

Fetch httpbin as follows

wget https://github.com/istio/istio/raw/master/samples/httpbin/httpbin.yaml

httpbin service is a NodePort by default. But since we now have an Ingress Controller, let us edit this file and remove the NodePort. Look for the Service kind then check under spec. Comment “type: NodePort” as shown below

$ vim httpbin.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: httpbin
  labels:
    app: httpbin
    service: httpbin
spec:
  #type: NodePort    ##Comment this line
  ports:
  - name: http
    port: 8000
    targetPort: 80
  selector:
    app: httpbin

Then install using kubectl

kubectl apply -f httpbin.yaml

In case you would wish it to be deployed in a different namespace, simply edit the file before applying it.

Create a custom Nginx deployment and service as follows:
We shall have three pods here. You can reduce them depending on your needs.

$ vim nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3     ##Three pods to be deployed
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.4
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
    service: nginx
spec:
  ports:
  - name: http
    port: 8511
    targetPort: 80
  selector:
    app: nginx

Then install it in your cluster

kubectl apply -f nginx.yaml

Confirm that both deployments are running

$ kubectl get deploy -n ambassador
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
edge-stack         1/1     1            1           57m
edge-stack-agent   1/1     1            1           57m
edge-stack-redis   1/1     1            1           57m
httpbin            0/1     1            0           105s
nginx-deployment   0/3     3            0           35s

As well as both services

NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
httpbin      ClusterIP   10.233.23.90    <none>        8000/TCP   176m
kubernetes   ClusterIP   10.233.0.1      <none>        443/TCP    5d22h
nginx        ClusterIP   10.233.25.235   <none>        8511/TCP   4h25m

Step 4: Create Ambassador Mappings for both Applications

Until now, we have a working ingress controller and two sample deployments (nginx and httpbin) that we shall use to test how it works. Create the following Ambassador Ingress Mapping resource that will target httpbin and nginx. If you read the manifests we fetched earlier, you will notice that it creates a service called “httpbin” and “nginx” respectively. Moreover, they will be listening at ports 8000 and 8511 respectively. Armed with this information, let us create an Ingress thus:

$ vim httpbin-nginx-mapping.yaml
##For httpbin
---
apiVersion: getambassador.io/v2
kind:  Mapping
metadata:
  name:  httpbin-backend
spec:
  prefix: "/"
  timeout_ms: 4000
  service: httpbin:8000  ##Service name and its port

##For Nginx
---
apiVersion: getambassador.io/v2
kind:  Mapping
metadata:
  name:  nginx-backend
spec:
  prefix: "/nginx/"
  timeout_ms: 4000
  service: nginx:8511    ##Service name and its port

Once done, save the file then apply it in your cluster.

kubectl apply -f httpbin-nginx-mapping.yaml

What is happening here is that, any traffic that will come from “https://hostip:nodeport/” root url (/), will be routed to the httpbin service automatically. Similarly, any traffic hitting the https://hostip:nodeport/nginx/ url will be routed to your nginx pod. Note that hostip is any of your Kubernetes nodes IPs and NodePort is the port created when Ambassador was installed. If you are using a LoadBalancer, you will access your services using https://LoadBalancerIP/ for httpbin and https://LoadBalancerIP/nginx/ for nginx.

What else are we left to do than to test if we can reach our serivice?

Ensure that your NodePort has been allowed in the firewall of any node of your choice then open your browser and point it to ant of your urls. You can also use a FQDN resolving to any of your Kubernetes nodes if you are using NodePort

You should see something eye popping as shown below:

For Nginx:

Ambassador

For httpbin:

Ambassador

Conclusion

Installing Ambassador is as simple and as exciting as it has been discussed. There are lots of features that Ambassador ships with and we encourage you to check out its Official Documentation so that you can fully utilize its power.

Otherwise, we continue to appreciate your enormous support and we hope that your year will flourish, your endeavour bear good fruits and your investments pay off handsomely.

Other guides you might enjoy:

Thapelo Manthata
I’m a desktop support specialist transitioning into a SharePoint developer role by day and Software Engineering student by night. My superpowers include customer service, coding, the Microsoft office 365 suite including SharePoint and power platform.
RELATED ARTICLES

Most Popular

Recent Comments