I want to deploy two apps "A" and "B" on our Kubernetes cluster (a first for me).
"A" handles traffic from outside the cluster and can request further data from "B" over http. "B" needs much more resources than "A" as it's CPU and Memory intensive.
"A" and "B" are quite tied together since the body of the HTTP calls between them is versioned and quite complex, but "B" should be free to scale independently from "A".
Today, "A" calls "B" using a dedicated Service whose url is hardcoded in "A".
During deployment earlier today, "A" and "B" were deployed simultaneously but "A" managed to call an old version of "B" (since the Service was still routing requests to old "B" for a few seconds/minutes).
What's the good practice to tie calls from newly deployed "A" to newly deployed "B" pods only?
I don't want to have a conditional processing in "A" based on the version of the payload received from "B".
Thank your for your help,
CodePudding user response:
I presume you're just working with native Kubernetes resources, so the most simple way to do this would be to deploy your new backend B
separately with different labels than the previous version. Once all pods are up, you simply change the service'es label selectors, this would instantly switch all the traffic to the newly created backend pods.
If you were to update the current backend B
this would, depending on the numbers of pods, cause a RollingUpdate by default, so there would be a timeframe where requests could reach the old and newly created backend B
's pods.
However there's special tools that solve such issues in a more "clean" way, such as Argo Rollouts. But If this is your only use-case I would recommend the first method as this causes a sudden switch of all traffic.
Let's assume your backend b
looks like the following:
apiVersion: v1
kind: Pod
metadata:
name: backend-b
labels:
app.kubernetes.io/name: backend-b
spec:
containers:
- name: nginx
image: nginx:stable
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: backend-b-service
spec:
selector:
app.kubernetes.io/name: backend-b
ports:
- protocol: TCP
port: 80
targetPort: 8080
Now you would create a second backend B, please note the different label:
apiVersion: v1
kind: Pod
metadata:
name: backend-b-new
labels:
app.kubernetes.io/name: backend-b-new
spec:
containers:
- name: nginx
image: nginx:stable
ports:
- containerPort: 80
Currently there would be no traffic hitting this new backend, in order to cause all traffic to switch instantly to the new backend, you would need to change the label selectors of the service for backend B.
apiVersion: v1
kind: Service
metadata:
name: backend-b-service
spec:
selector:
app.kubernetes.io/name: backend-b-new
ports:
- protocol: TCP
port: 80
targetPort: 8080
As I said, this isn't the best solution, but should work for your use cases, provided that your Application A
is communicating with Application B through the DNS name of the given Service.