I am using springboot microservices and Kubernetes for our application development and deployments. We are using stateful sets for deployments. We have a need to generate unique identifiers that can be used in the services across pods deployed on nodes across clusters.
I am using twitter snowflake format for the generation of unique Id with K8s stateful sets. Format: 64 bit java long: 1 bit reserved 41 bit timestamp 10 bits nodeId 12 bits counter
Its a simple problem to solve if we are talking about say 5 replicas deployed on the same cluster (across different nodes). I could easily generate unique orderId that will serve as nodeId in the format above. But the moment I deploy the pods on multiple clusters, it duplicates the nodeIds since it generated similar orders across the clusters.
example: 5 replicas in a single cluster create pods like: service-0, service-1, service-2, service-3 service-4
I could get the unique pod numbers (0,1,2,3..) that will serve as nodeId in my uniqueId generator and hence I could derive a unique identifier. But if I deploy the application (via stateful set) to 2 clusters, it will generate similar services in the second cluster too:
service-0, service-1, service-2, service-3 service-4
now if my GLB routes my calls randomly across the 10 pods in the 2 cluster, the probability of generating duplicate Unique Id (for calls made during the same milisecond) is pretty high and hence my solution might not work.
Need inputs on how to solve the problem. Any help will be highly appreciated
CodePudding user response:
Hi WhizKid
I can give a work around for this try to include your cluster name included in the naming convention (e.g: cluster1-service-0) instead of just going with nodeID. Since we have generated unique IDs for each cluster now even if they lie on the same nodes or same servers it won’t become a problem. Hope this helps you.
CodePudding user response:
Thanks for all the suggestions. We figured out a way to retrieve the cluster Id from the code. We are setting the cluster Id in the Jules file (since using jules for deployment to Kubernetes), and then using the cluster variable in the deployment. That way we are able to retrieve the cluster name in the code. something like this:
Deployment.yml:
......
env:
- name: INFO_KUBE_ENV
value: ${environment}
- name: INFO_KUBE_CLUSTER
value: ${cluster}
and then using the env variable INFO_KUBE_CLUSTER in the code like this:
System.getenv("INFO_KUBE_CLUSTER")