We're Entering the Age of AI Connectivity

## Kubernetes Microservice Architecture

Digital transformation has led to a high velocity of data moving through APIs to applications and devices. Companies with legacy infrastructures are experiencing inconsistencies, failures and increased costs. And most importantly, dissatisfied customers.

All this has led to significant restructuring and [modernization of API technologies](/content/blog/evolution-apis-cloud-age-beyond/index.html), especially within IT. A primary strategy is to embrace Kubernetes and decouple [monolithic systems](/content/blog/learning-center/monolith-vs-microservices/index.html). On top of that, IT leadership is tasking DevOps teams to find systems, like an [API gateway](/content/blog/learning-center/what-is-an-api-gateway/index.html) or [Kubernetes ingress controller](/content/blog/learning-center/what-is-a-kubernetes-ingress-controller/index.html), to support API traffic growth while minimizing costs.

API gateways are crucial components of [microservice architectures](/content/blog/learning-center/what-are-microservices/index.html). The API gateway acts as a single entry point into a distributed system, providing a unified interface for clients who don’t need to care (or know) that the system aggregates their API call response from multiple microservices.

### Some everyday use cases for API gateways include:

- Routing inbound requests to the appropriate microservice
- Presenting a unified interface to a distributed architecture by aggregating responses from multiple backend services
- Transforming microservice responses into the format required by the caller
- Implementing non-functional/policy concerns such as authentication, logging, monitoring and observability, [API rate limiting](/content/blog/learning-center/what-is-api-rate-limiting/index.html), IP filtering, and attack mitigation
- Facilitating deployment strategies such as blue/green or canary releases

Many companies select a [Kubernetes API gateway](https://docs.konghq.com/kubernetes-ingress-controller/latest/concepts/gateway-api/) at the beginning or partway through their transition to multi-cloud. Doing so makes it necessary to choose a solution that can function with on-prem services and the cloud.

## **What is Kubernetes?**

[Kubernetes](/content/blog/learning-center/what-is-kubernetes/index.html) is becoming the hosting platform of choice for distributed architectures. It offers auto-scaling, fault tolerance, and zero-downtime deployments out of the box.

By providing a widely accepted, standard approach with a carefully designed API gateway, Kubernetes has spawned a thriving ecosystem of products and tools that make it much easier to deploy and maintain complex systems.

## **Kong Kubernetes Ingress Controller**

As a native Kubernetes application, Kong is installed and managed precisely as any other Kubernetes resource. It integrates well with other [CNCF](https://www.cncf.io) projects and automatically updates itself with zero downtime in response to cluster events like pod deployments. There’s also a great [plugin ecosystem](https://docs.konghq.com/hub/) and native [gRPC](https://grpc.io) support.

This tutorial will walk through how easy it is to set up the open source [Kong Ingress Controller](/content/products/kong-ingress-controller/index.html) as a Kubernetes API gateway on a cluster.

## Use Case: Routing API Calls to Backend Services

To keep this article to a manageable size, I will only cover a single, straightforward use case.

I will create a Kubernetes cluster, deploy two dummy microservices, "foo" and "bar," install and configure Kong to route inbound calls to /foo to the foo microservice and send calls to /bar to the bar microservice.

### **Prerequisites**

There are a few things you’ll need to work through in this article.

In this tutorial, I'm going to create a "real" Kubernetes cluster on [DigitalOcean](https://digitalocean.com) because it’s quick and easy, and I like to keep things as close to real-world scenarios as possible. If you want to work locally, you can use [minikube](https://minikube.sigs.k8s.io/docs) or [KinD](https://kind.sigs.k8s.io). You will need to fake a load-balancer, though, either using the [minikube tunnel](https://minikube.sigs.k8s.io/docs/handbook/accessing/#loadbalancer-access) or setting up a port forward to the API gateway.

For DigitalOcean, you will need:

- A DigitalOcean account
- A [DigitalOcean API token](https://cloud.digitalocean.com/account/api/tokens) with read and write scopes
- The [doctl](https://www.digitalocean.com/docs/apis-clis/doctl) command-line tool

To build and push docker images representing our microservices, you will need:

- [Docker](https://docker.io)
- An account on [Docker Hub](https://hub.docker.com)

You will also need [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl) to access the Kubernetes cluster.

### **Setting Up doctl**

After installing doctl, you’ll need to authenticate using the DigitalOcean API token:

```text
$ doctl auth init
...
Enter your access token:  <-- paste your API token, when prompted
Validating token... OK
```

### **Create Kubernetes Cluster**

Now that you have authenticated doctl, you can create your Kubernetes cluster with this command:

```text
$ doctl kubernetes cluster create mycluster --size s-1vcpu-2gb --count 1
```

The command creates a cluster with a single worker node of the smallest viable size in the New York data center. It's the smallest and simplest cluster (and also the cheapest to run). You can explore other options by running doctl kubernetes –help.

The command will take several minutes to complete, and you should see an output like this:

```text
$ doctl kubernetes cluster create mycluster --size s-1vcpu-2gb --count 1
Notice: Cluster is provisioning, waiting for cluster to be running
....................................................
Notice: Cluster created, fetching credentials
Notice: Adding cluster credentials to kubeconfig file found in "/Users/david/.kube/config"
Notice: Setting current-context to do-nyc1-mycluster
ID                                      Name         Region    Version        Auto Upgrade    Status     Node Pools
4cf2159a-01c1-423c-907d-51f19c3f9a01    mycluster    nyc1      1.20.2-do.0    false           running    mycluster-default-pool
```

### **Create Dummy Microservices**

To represent backend microservices, I’m going to use a trivial [Python Flask](https://pypi.org/project/Flask) application that returns a JSON string:

```text
from flask import Flask
app = Flask(__name__)

@app.route('/foo')
def hello():
    return '{"msg":"Hello from the foo microservice"}'

if __name__ == "__main__":
    app.run(debug=True, host='0.0.0.0')
```

This Dockerfile builds a docker image you can deploy:

```text
FROM python:3-alpine

WORKDIR /app

RUN echo "Flask==1.1.1" > requirements.txt
RUN pip install -r requirements.txt
COPY foo.py .

EXPOSE 5000

CMD ["python", "foo.py"]
```

### **Deploy Dummy Microservices**

You’ll need a manifest that defines a [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment) and a [Service](https://kubernetes.io/docs/concepts/services-networking/service) for each microservice, both for "foo" and "bar." The manifest for "foo" would look like this:

```text
apiVersion: apps/v1
kind: Deployment
metadata:
  name: foo-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: foo
  template:
    metadata:
      labels:
        app: foo
    spec:
      containers:
      - name: api
        image: digitalronin/foo-microservice:0.1
        ports:
        - containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
  name: foo-service
  labels:
    app: foo-service
spec:
  ports:
  - port: 5000
    name: http
    targetPort: 5000
  selector:
    app: foo
```

### **Access the Services**

You can check that the microservices are running correctly using a port forward:

```text
$ kubectl port-forward service/foo-service 5000:5000
```

Then, in a different terminal:

```text
$ curl http://localhost:5000/foo
{"msg":"Hello from the foo microservice"}
```

### **Install Kong for Kubernetes**

Now that you have our two microservices running in our Kubernetes cluster, let’s [install Kong](/content/install/index.html).

There are several options for this, which you will find in the [documentation](https://docs.konghq.com/kubernetes-ingress-controller/1.1.x/deployment/minikube). I’m going to apply the manifest directly, like this:

```text
$ kubectl create -f https://bit.ly/k4k8s
```

The last few lines of output should look like this:

```text
...
service/kong-proxy created
service/kong-validation-webhook created
deployment.apps/ingress-kong created
```

Installing Kong will create a DigitalOcean [load balancer](https://www.digitalocean.com/products/load-balancer). It's the internet-facing endpoint to which you will make API calls to access our microservices.

### **Configure Kong Gateway**

You can use [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress) resources to configure Kong to route API calls to the microservices:

```text
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: foo
  namespace: default

spec:
  ingressClassName: kong
  rules:
  - http:
      paths:
      - path: /foo
        pathType: Prefix
        backend:
          service:
            name: foo-service
            port:
              number: 5000
```

Now, Kong will route calls to /foo to the foo microservice and /bar to bar. You can check this using curl:

```text
$ curl $PROXY_IP/foo
{"msg":"Hello from the foo microservice"}

$ curl $PROXY_IP/bar
{"msg":"Hello from the bar microservice"}
```

## What Else Can You Do?

In this article, I have:

- Deployed a Kubernetes cluster on DigitalOcean
- Created Docker images for two dummy microservices, “foo” and “bar”
- Deployed the microservices to the Kubernetes cluster
- Installed the Kong Ingress Controller
- Configured Kong to route API calls to the appropriate backend microservice

I've demonstrated one simple use of Kong, but it’s only a starting point. With [Kong for Kubernetes](/content/products/kong-enterprise/kong-kubernetes/index.html), here are several examples of other things you can do:

### **Authentication**

By adding an [authentication](https://docs.konghq.com/kubernetes-ingress-controller/1.1.x/guides/configure-acl-plugin) plugin to Kong, you can require your API callers to provide a valid JSON Web Token ( [JWT](https://en.wikipedia.org/wiki/JSON_Web_Token)) and check each call against an Access Control List ( [ACL](https://en.wikipedia.org/wiki/Access-control_list)) to ensure callers are entitled to perform the relevant operations.

### **Certificate management**

You can enable [integration with cert-manager](https://docs.konghq.com/kubernetes-ingress-controller/1.1.x/guides/cert-manager) to provision and auto-renew SSL certificates for your API endpoints so that all your API traffic is encrypted as it travels over the public internet.

### **gRPC support**

Kong natively supports [gRPC](https://grpc.io), so it’s easy to [add gRPC support](https://docs.konghq.com/kubernetes-ingress-controller/1.1.x/guides/using-ingress-with-grpc) to your API.

You can do a lot more with Kong, and I’d encourage you to look at the [documentation](https://docs.konghq.com/kubernetes-ingress-controller/1.1.x/deployment/minikube) and start to explore some of the other features.

The API gateway is a crucial part of a microservices architecture, and the Kong Ingress Controller is well suited for this role in a Kubernetes cluster. You can manage it in the same way as any other Kubernetes resource.

## Cleanup

Don’t forget to destroy your Kubernetes cluster when you are finished with it so that you don’t incur unnecessary charges:

```text
$ kubectl delete -f https://bit.ly/k4k8s  # <-- this will destroy the load-balancer

$ doctl kubernetes cluster delete mycluster
Warning: Are you sure you want to delete this Kubernetes cluster? (y/N) ? y
Notice: Cluster deleted, removing credentials
...
```
