I have a ReplicaSet of a generic Java micro service ("DB service"), which can interface with any JDBC database, based on meta data. When an upstream micro service invokes this DB micro service, it will allocate a JDBC connection pool. Lets say the database DBA has given me 50 connections to work with for a specific use case (some meta data deployment unit my system can 'execute').
I would like to have two DB replicas each create 25 connections (MAX / 2) in a local connection pool. Henceforth the upstream micro service should now route it's invocations to these two replicas only, which now contain these 2 connection pools, while bypassing the other X DB replicas which have not created any connections.
If the upstream micro service adds an HTTP header unique to this use case ("StatefulRoute=ConnectionName"), can K8s and/or Istio be tricked to route the request to the subset of DB replicas, who have created these local JDBC connection pools for this use case?
Notice that many other use cases can by deployed by the user over time, each use case potentially also needing JDBC connections. Those use cases should be spread to other DB replicas, based on Readiness checks of already busy DB replicas.
I envision an additional Resource Manager micro service (conductor), which each DB replica will interact with to ask 1) can I allocate a connection pool for this request, 2) how many connections can I allocate.
When the very first (uninitialized) DB replica receives a new request (no route yet established) it will interact with the Resource Manager. This manager in turn should then dynamically configure K8s / Istio (REST call?) to henceforth route requests (for the specific use case) to this replica.
The Resource Manager will be a Singleton, or if it becomes a bottleneck, a ReplicaSet using a distributed cache to keep track of 'connection pool grants'. If it runs out of connections, it will ping DB replicas, which haven't sent a heart beat in a while (could've been restarted by K8s). If it finds one replica not responding, it will then allow a new fresh replica to allocate a connection pool, based on remaining available connections (on the database side).
If all previously initialized replicas are still alive and serving request (and thus the max physical db connections are thus in use), the manager will reject the connection request, and the requesting DB replica will then return an error ("no more connections available to service request") to the upstream micro service.
Has anyone ever faced this requirement?
This is not user session affinity, which typically involves ingress. This involves affinity between two micro services inside the cluster.
Thanks.
If you want to configure istio traffic routing there are few links to follow.
For start I would take a look at bookinfo example, it's very easy to install and you could try your settings on it.
Then follow this istio documentation about request routing, it explain how would you make your virtual services and destination rules to match correct subsets of your pods.
As mentioned here and here, there we can learn how to add your header which will be used to route traffic to appropriate version of your pod.
Take a look at this example
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
...
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
So we have 3 subsets of review deployment, v1,v2 and v3 and a service for them. You can look here how it's built, every review deployment have an app and version label which we can use in our virtual service and destination rules.
kubectl get pods
reviews-v1-874083890-f0qf0 2/2 Running 0 6m
reviews-v2-1343845940-b34q5 2/2 Running 0 6m
reviews-v3-1813607990-8ch52 2/2 Running 0 6m
kubectl get services
reviews 10.0.0.170 <none> 9080/TCP 6m
As you can see in above virtual service if there is a user with end-user name which is exactly jason, then it sends whole traffic to v2, if not, then by default it sends everything to v1.