Today we’re going to have a look at Tanzu Service Mesh. TSM offers various enhanced networking capabilities and comes in an Advanced and Enterprise version. TSM is focussed on providing connectivity for containers based applications running on Kubernetes. TSM Advanced offers end-to-end connectivity and (network) resiliency for apps, encryption for service communications, certificate management and extensive visibility options. TSM Enterprise adds things like zero trust security, user security and API security & visibility to this. If you want to learn more about the extra TSM capabilities Enterprise, check out this blog.
In this article we’re going to look at some of the basics of TSM, I will show you how to onboard a Kubernetes cluster to TSM and how to create, what TSM calls, a global namespace. TSM consists of two parts: first there’s a control plane, packed as a GUI and running as a service in the VMware Cloud. Second, there’s a data plane running is on your Kubernetes cluster using Istio technology. Tanzu Service Mesh is not limited to VMware Tanzu Kubernetes Grid (TKG) clusters, but can be used on a wide variety of Kubernetes clusters including AKS, EKS, GKE and more. A full overview of the requirements and supported platforms is available here.
With TSM enabled on a Kubernetes cluster, the pods that make up your application will connect to each other on Layer 7 using mTLS. You can configure this capability within your K8S cluster(s), but also across your K8S cluster(s). After you’ve onboarded your Kubernetes cluster(s), TSM will show these nice diagrams that will provide you with information on dataflows between your pods/micro-services (Apps) that are running on the cluster:
The nice thing is: you (almost) don’t have to make any changes to your app to get things working. There are some things you have to take into account:
- After a cluster is on-boarded to TSM, you have to redeploy the application before TSM is working for your apps.
- External services to your application will be exposed through the Istio gateway, so if you’re app is configured to use another LB/ingress solution you will need some reconfiguration there.
- If you want to implement TSM Global Namespaces, you need to add the domain of the Global Namespace to the podnames in your YAML files. More on Globale Namespace later in this article.
In this article I will show you how to:
- Onboarding a Kubernetes cluster to TSM.
- Enable an application for TSM (and that’s very easy) – we will use the Google Online Boutique app in this article. A very nice polyglot micro-services app.
- Monitor application dataflows.
- Add the cluster to a Global Namespace.
- On-board a second cluster and deploy a multi-cluster edition of the app.
Onboarding a Kubernetes cluster to TSM
The process for onboarding a Kubernetes cluster to TSM is straightforward. Choose “New Workflow” in the TSM GUI, then “Onboard new cluster” and think of a name for your new cluster. Now choose “Generate new security token”: you wil get a registration YAML file to apply to the cluster and a security token to setup the communication. Now apply these two commands to your cluster to get it registered:
Initial registration will take 1-2 minutes. Now you can install Tanzu Service Mesh on your cluster, on either all namespaces or you can choose to exclude some of your namespaces. Your cluster will show up in the cluster overview screen:
Note: in this example some other clusters are also added. Running “kubectl get ns” on the on-boarded cluster will show the “istio-system” namespace is available on your cluster, on top of that you will also find a “vmware-system-tsm” namespace. These namespaces are both deployed by Tanzu Service Mesh.
Enable an application for TSM
Now you can enable an application for TSM. The app will show up in TSM and you will be able to monitor network traffic flows. Also, the traffic between the micro-services in you application will use mTLS to communicate, thus network is encrypted between the services. If TSM is enabled for a namespace, TSM will be automatically deployed. Note that an already deployed application has to be redeployed before TSM can do its work.
There’s a nice polyglot micro-services app that’s coming from Google that you can deploy as an example. Create a namespace and deploy the app to the samespace:
kubectl create tkg01-boutique kubectl apply -f ./release/kubernetes-manifests.yaml -n tkg01-boutique
You maybe first want to apply the runasroot.yaml to simplify the process (not recommended for production environments). Normally this app would use a regular load balancer: an external IP address would show up for the frontend-external service. Because we’re using TSM, Istio ingress is used for this. So, we need to apply the istio-manifests.yaml (included in the app). We can also delete the frontend-external service:
kubectl apply -f ./release/istio-manifests.yaml -n tkg01-boutique kubectl delete service frontend-external -n tkg01-boutique
To learn how you can acces your app, run:
kubectl get services -n istio-system | grep istio-ingressgateway
Now you can access your app through the IP address behind “istio-ingressgateway. A nice app topology will show up in the TSM UI:
Monitor the app
The app topology is a nice starting point to better understand your app. RPS shows the Requests Per Second. You can click on of the services to focus on a specific service. You will see service dependencies, SLOs (that’s for an upcoming post), performance, instances and nodes. The performance tab give you insight on requests per second, latencies and errors.
You can browse around to learn more about available metrics.
Add your cluster and app to Global Namespace
Tanzu Service Mesh uses the concept of a Global Namespace (GNS) to define an application boundary that makes it possible for applications to communicate across Kubernetes clusters. A GNS is a TSM-specific concept:
A global namespace connects the resources and workloads that make up the application into one virtual unit to provide consistent traffic routing, connectivity, resiliency, and security for applications across multiple clusters and clouds. Each global namespace is an isolated domain that provides automatic service discovery and manages service identities within that global namespace.
A GNS has a name and an internal domain name that is used to setup communication between services that are available in the GNS. When you create the GNS, you have to setup Namespace Mapping Rule that determine which namespaces and clusters are added in the namespace. In this example I’ve already onboarded a second cluster called TKG02, I’m adding the two namespaces to the GNS that will contain my app (to be added in a later stage). Note that it is important NOT to use the similar names for Kubernetes namespaces across the clusters that are added to the namespace:
In this example the “tkg01-boutique” and “tkg02-boutique” running on clusters TKG01 and TKG02 respectively are added to the namespace (the tkg02-boutique namespace is already created on the TKG02 cluster). In this example I’m not configuring any external services, public services, GSLB and/or resiliency options on the namespace (also for an upcoming article :)).
If you want to add the app (for example) only to the tkg01-boutique namespace (and thus not leveraging the tkg02-boutique app) you would still need a small update to your application YAML file. You have to include the domain name of the GNS in the YAML of your app. In this example I’ve used the viktoriousint.nl domain name for this, an updated YAML file is available on my github so you get an idea of this configuration. This YAML file can be used to deploy the app to one Kubernetes cluster within a GNS01 with a domain name called viktoriousint.nl.
On-board a second cluster and deploy a multi-cluster edition of the app
It’s now also pretty simple to deploy a multi-cluster version of the app. On GitHub you will find a multi-cluster version of the Google Boutique app. A multi-cluster version sound like a complete different version of the app, but actually this is not the case. The only things that changed are:
- Add the domain name of the GNS to the YAML file.
- Split up the original YAML file to a kubernetes-cluster01.yaml and kubernetes-cluster02.yaml that determine which components of the app run on each Kubernetes cluster.
In this example the app will be deployed to Kubernetes cluster TKG01 and TKG02 added earlier to the GNS. These clusters run in the same vSphere environment, however (from a functional perspective) it doesn’t really matter if these clusters run on different clouds and/or datacenters. Of course there are some latency considerations you have to take into account if you run your app across clouds.
So, first remove the original “single cluster” version of the app from the TKG01 cluster if it’s still running:
kubectl delete -f ./release/kubernetes-manifests.yaml -n tkg01-boutique
Now deploy the part of the app that will run on cluster TKG01:
kubectl apply -f ./release/kubernetes-cluster01.yaml -n tkg01-boutique
Switch to the second cluster, and deploy part 2 of your app:
kubectx tkg02 kubectl apply -f ./release/kubernetes-cluster02.yaml -n tkg02-boutique
To learn how to access the app use:
kubectl get services -n istio-system | grep istio-ingressgateway
Now you can check out the GNS topology to learn more about your multi-cluster app:
Note that the red warning you see in this picture has to do with the fact that this app is not accessible from the internet (as expected, it’s running on a LAN address).
The app is now available as a multi-cluster application after doing some minor configuration changes to the application: that’s the power of Tanzu Service Mesh.
I hope this was useful, feel free to leave a comment below.