Kubernetes - Exposing Two Services Using Ingress
Prerequisites
- kubectl
- minikube
- Docker
Description
In the previous posts Containerizing an ML Model - Part 1 and Containerizing an ML Model - Part 2 I showed how to create the docker container for a single machine learning model.
In this post we will deploy that service along with an additional service in Kubernetes and expose them outside the cluster so users can use them to process their data. To do that we must use Ingress - an API object that defines rules which allow external access to services in a cluster.
Before Beginning
Make sure you have installed minikube and configured the kubectl command-line tool to communicate with your cluster.
Also to speed up development you should re-use the docker daemon within minikube. This way when you build your docker containers they will be directly accessible to the kubernetes deployments and you don’t have to go through the extra steps of pushing, then pulling them from an external container registry. To get the command for your shell run minikube docker-env
.
For example on Windows we use the following command
For more information plese refer to the section Use local images by re-using the Docker daemon
Finally, make note of the minikube IP address by running this command. You will need this IP later when testing the docker containers.
Service 1 - NER
This is the NER service from previous posts. You can find the code to build the docker container here.
- Build using
docker build . -t ner
- Run using
docker run -p 5001:5000 ner:latest
- Test by sending the sample text from file
test-text.txt
in the body of the POST request. You should get the following response. Remember to send it to the minikube IP - your URL should look like192.168.100.148:5001/entities
In Postman the request is like this (your IP and port may be different).
The response should look like this:
[
{
"end": 24,
"label": "PERSON",
"start": 13,
"text": "John Smith'"
}
]
Service 2 - OCR
As our second service we will build an application that performs OCR on JPEG images of text and returns the text.
Download the code from here.
- Build using
docker build . -t ocr
- Run using
docker run -p 5002:5000 ocr:latest
- Test by sending the sample image file
test-image.jpg
as form-data in the body of the POST request. Specify the key asfile
and the value as the image file. Remember to send it to the minikube IP - your URL should look like192.168.100.148:5002/ocr
In Postman the request should look like this (your IP and port may be different).
The response should look like this:
{
"file": "test-image.jpg",
"pages": {
"1": "From today's featured list\n‘American actress and singer Jennifer Love Hewitt has released four studio albums, a compilation album, seven music videos, and\nthirteen singles, as well as five promotional singles. She released her debut studio album, Love Songs, under the name \"Love Hewitt\"\nin March 1992; it included three singles: \"Dancing Queen\", \"What's It Gonna Take\", and \"Please Save Us the World”. Hewitt received\nattention for her performance in the family drama Party of Five. During this success, she signed with Atlantic and released two studio\nalbums: Let's Go Bang in September 1995 and a self-titled album in September 1996. Hewitt recorded the single \"How Do | Deal\" for\nthe soundtrack of the 1998 slasher film / Still Know What You Did Last Summer, in which she had a starring role. The song reached\nnumber 59 on the Billboard Hot 100, as well as number 8 on the Australian songs chart and number 5 on the New Zealand songs\nchart. It received a gold certification from the Australian Recording Industry Association and is the best-selling song of her career.\n(Full list...)\n"
}
}
Enable Ingress
Before you can use ingress in minikube, you must first enable it. Do so by running the following command. For more details refer to the documentation Enable the Ingress controller
Create deployments
There will be three deployment files, one for each service and one for the ingress.
NER Service Deployment
apiVersion: v1
kind: Service
metadata:
name: ner-service
spec:
selector:
run: ner
ports:
- port: 80
targetPort: 5000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ner-deployment
spec:
replicas: 1
selector:
matchLabels:
run: ner
template:
metadata:
labels:
run: ner
spec:
containers:
- name: ner
image: ner:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5000
OCR Service Deployment
apiVersion: v1
kind: Service
metadata:
name: ocr-service
spec:
selector:
run: ocr
ports:
- port: 80
targetPort: 5000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ocr-deployment
spec:
replicas: 1
selector:
matchLabels:
run: ocr
template:
metadata:
labels:
run: ocr
spec:
containers:
- name: ocr
image: ocr:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5000
Ingress
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress
spec:
rules:
- host: demo.local
http:
paths:
- path: /ocr
backend:
serviceName: ocr-service
servicePort: 80
- path: /entities
backend:
serviceName: ner-service
servicePort: 80
NOTE: you need to edit your hosts file to create a mapping between a domain name of your choosing and the IP address of minikube. In this example I set the domain name to demo.local
and assigned it to the minikube ip address.
The hosts file is located here on Windows
C:\Windows\System32\drivers\etc
On Linux you can find the hosts file under
/etc/hosts
Apply deployments
Run kubectl apply
to update the kubernetes cluster to match the state defined in the above configuration .yaml
files.
Check that pods are running with kubectl get pods --all-namespaces
. Your output should look similar to the following.
Test
You should now be able to access the NER service from this URL - demo.local\entities
and the OCR Service from this URL - demo.local\ocr
Sample Code
References
Salvatore S. © 2020