I have a number of restful services within our system
- Some are our within the kubernetes cluster
- Others are on legacy infrasture and are hosted on VM's
Many of our restful services make synchronous calls to each other (so not asynchronously using message queues)
We also have a number of UI's (fat clients or web apps) that make use of these services
We might define a simple k8s manifest file like this
- Pod
- Service
- Ingress
apiVersion: v1
kind: Pod
metadata:
name: "orderManager"
spec:
containers:
- name: "orderManager"
image: "gitlab-prem.com:5050/image-repo/orderManager:orderManager_1.10.22"
---
apiVersion: v1
kind: Service
metadata:
name: "orderManager-service"
spec:
type: NodePort
selector:
app: "orderManager"
ports:
- protocol: TCP
port: 50588
targetPort: 50588
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: orderManager-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /orders
pathType: Prefix
backend:
service:
name: "orderManager-service"
port:
number: 50588
I am really not sure what the best way for restful services on the cluster to talk to each other.
- It seems like there is only one good route for callers outside the cluster which is use the url built by the ingress rule
- Two options within the cluster
This might illustrate it further with an example
Caller | Receiver | Example Url | |
---|---|---|---|
UI | On Cluster | http://clusterip/orders | The UI would use the cluster ip and the ingress rule to reach the order manager |
Service off cluster | On Cluster | http://clusterip/orders | Just like the UI |
On Cluster | On Cluster | http://clusterip/orders | Could use ingress rule like the above approach |
On Cluster | On Cluster | http://orderManager-service:50588/ | Could use the service name and port directly |
I write cluster ip a few times above but in real life we put something top so there is a friendly name like http://mycluster/orders
So when caller and reciever are both on cluster is it either
- Use the ingress rule which is also used by services and apps outside the cluster
- Use the nodeport service name which is used in the ingress rule
- Or perhaps something else!
One benefit of using nodeport service name is that you do not have to change your base URL.
- The ingress rule appends an extra elements to the route (in the above case orders)
- When I move a restful service from legacy to k8s cluster it will increase the complexity
CodePudding user response:
It depends on whether you want requests to be routed through your ingress controller or not.
Requests sent to the full URL configured in your Ingress resource will be processed by your ingress controller. The controller itself — NGINX in this case — will proxy the request to the Service. The request will then be routed to a Pod.
Sending the request directly to the Service’s URL simply skips your ingress controller. The request is directly routed to a Pod.
The trade offs between the two options depend on your setup.
Sending requests through your ingress controller will increase request latency and resource consumption. If your ingress controller does nothing other than route requests, I would recommend sending requests directly to the Service.
However, if you use your ingress controller for other purposes, like authentication, monitoring, logging, or tracing, then you may prefer that the controller process internal requests.
For example, on some of my clusters I use the NGINX ingress controller to measure request latency and track HTTP response statuses. I route requests between apps running in the same cluster through the ingress controller in order to have that information available. I pay the cost of increased latency and resource usage in order to have improved observability.
Whether the trade offs are worth it in your case depends on you. If your ingress controller does nothing more that basic routing, then my recommendation is to skip it entirely. If it does more, then you need to weigh the pros and cons of routing requests through it.