This is third blog post as part of a series exploring service to service call patterns in different application runtimes in Google Cloud.
The first post explored Service to Service call pattern in a GKE runtime using a Kubernetes Service abstraction
The second post explored Service to Service call pattern in a GKE runtime with Anthos Service mesh.
This post will explore the call pattern across multiple GKE runtimes with Multi-Cluster Service providing a way for calls to be made across clusters.
Mind you, the preferred way for service to service call ACROSS clusters is using Anthos Service Mesh, which will be covered in the next blog post, however Multi-Cluster service is also a perfectly valid approach in the absence of Anthos Service Mesh.
Target Architecture
A target architecture that I am aiming for is the following:
Here two different applications are hosted on two separate Kubernetes clusters in different availability zones and the Service(called "Caller") in one cluster invokes the Service(called "Producer") in another cluster.
Creating the Cluster with Multi-Cluster Services
Services Installation
Assuming that the 2 GKE clusters are now available, the first cluster holds the Caller and an Ingress Gateway to enable the UI of the caller to be accessible to the user. This is through a deployment descriptor which looks something like this for the caller:
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-caller-v1
labels:
app: sample-caller
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: sample-caller
version: v1
template:
metadata:
labels:
app: sample-caller
version: v1
spec:
serviceAccountName: sample-caller-sa
containers:
- name: sample-caller
image: us-docker.pkg.dev/sample/docker-repo/sample-caller:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
securityContext:
runAsUser: 1000
resources:
requests:
memory: "256Mi"
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 3
periodSeconds: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
I have reproduced the entire yaml just for demonstration, there is nothing that should stand out in the file.
Along the same lines the Producer application is deployed to the second cluster.
Caller to Producer call - Using Multi-Cluster Services
The right approach to getting service to service call working across a cluster is to use a feature of Anthos called Multi-cluster service and is described in detail
in this blog post and
this how to post
The short of it is that if a "ServiceExport" resource is defined in cluster 2 and if the same namespace exists in Cluster 1 then the Service is resolved using a host name of the form "service-name.namespace.svc.clusterset.local" and in my case this maps to "sample-producer.istio-apps.svc.clusterset.local"!. The ServiceExport resource looks something like this:
kind: ServiceExport
apiVersion: net.gke.io/v1
metadata:
namespace: istio-apps
name: sample-producer
This is the only change that I have to make to the caller, instead of calling Producer using "sample-producer", now it uses the host name of "sample-producer.istio-apps.svc.clusterset.local" and everything resolves cleanly and the call continues to work across the cluster.
View from the caller:
View from the Producer:
Conclusion
I hope this clarifies to some extent how service to service call can be enabled across multiple clusters, even across regions.
There are a few small catches, for eg, to get the Mutual TLS to work across clusters is not easy. This is cleanly solved when using Anthos Service Mesh and will be detailed in the next blog post.
No comments:
Post a Comment