Hello, and welcome to your Aiden's Lab Notebook.
Following up on our last post covering the core concepts and features of Linkerd, this time, we're going to roll up our sleeves and get hands-on withĀ installing and using Linkerd.
To keep this exercise focused, we'll use Minikube for our Kubernetes cluster setup. Since we've covered Minikube in previous posts, I won't go into extra detail here.
Before we dive in, let's take a closer look at Linkerd's main components to make our hands-on session more effective.
A Closer Look at Linkerd's Main Components
Linkerd'sĀ Control PlaneĀ acts as the brain of the Service Mesh and consists of these core components:
controller: Provides the public API.destination: Manages service discovery and routing information.identity: Issues and manages certificates for mTLS.proxy-injector: Automatically injects the sidecar proxy when Pods are created.
And Linkerd'sĀ Data PlaneĀ is made up ofĀ linkerd-proxy, an ultra-lightweight sidecar proxy deployed alongside each application's Pod.
TheĀ Linkerd proxyĀ transparently intercepts all TCP traffic (mainly HTTP, gRPC, etc.) going into and out of its Pod. With this intercepted traffic, it performs functions likeĀ mTLS encryption, load balancing, retries, timeouts, and metrics collection.
TheĀ Linkerd CLIĀ is the tool that allows you, from your local machine, to communicate with the Linkerd Control Plane and manage the Service Mesh.
From the CLI, you can perform various tasks like installing Linkerd, checking its status, viewing resource statistics, monitoring real-time traffic, and injecting proxies. It's an essential tool for operating and debugging Linkerd.
Finally,Ā Linkerd VizĀ is an extension that allows you to visually monitor and analyze the health and performance of your Linkerd Service Mesh.
Through its web-based dashboard, you can monitor real-time traffic, success rates, latency, and more. It alsoĀ provides a Prometheus-compatible metrics API, enabling integration with external monitoring systems.
Preparing Our Lab: Installing the Linkerd CLI
I'm running this lab in a WSL environment. First, I'll start a Minikube cluster namedĀ k8s-testĀ in my terminal.

Next, I'll run the Linkerd CLI installation command below.
curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install-edge | shThe Linkerd installation script will then be downloaded and executed, as shown below.

Run the following command to add it to your environment variables.
export PATH=$HOME/.linkerd2/bin:$PATHOnce that's done, you can check if the Linkerd CLI is installed with theĀ linkerd version command.

Since Linkerd's Control Plane hasn't been deployed to our Minikube cluster yet, the Server version isĀ unavailable. After we deploy the Control Plane later, we'll check again, and the Server version will be updated.
To use Linkerd, theĀ Gateway API CRD must be installed on your Kubernetes cluster.Ā A CRD (Custom Resource Definition) allows you to extend the cluster's functionality by adding new resource types beyond the default ones (like Deployment, StatefulSet, etc.).
The Gateway API is a CRD that defines resources related to network traffic. If it's not already installed, you can install it on your cluster with the following command:
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/standard-install.yamlThis will install the CRDs that make up the Gateway API.

Next, running theĀ linkerd check --preĀ command in your terminal will verify if your cluster meets the prerequisites for using Linkerd. This command helps you identify potential environmental issues in advance, from the Kubernetes API status and version to the Linkerd CLI version.

Now that all prerequisites are met, let's deploy Linkerd's Control Plane to our cluster.
Deploying the Linkerd Control Plane on Minikube
To deploy Linkerd's Control Plane, you first need to install the CRDs required for it to operate, using the command below.
linkerd install --crds | kubectl apply -f -
Next, let's install the Linkerd Control Plane itself. The following command will automatically install the components that make up the Control Plane.
linkerd install | kubectl apply -f -If your Minikube is running on Docker...
When you try to install the Linkerd Control Plane, the installation might fail with a message stating that theĀ proxy-init container must run as the root user.
In that case, use the commandĀ linkerd install --set proxyInit.runAsRoot=true | kubectl apply -f -Ā to install Linkerd.
Since my Minikube is indeed running on Docker, I used the following command to install the Linkerd Control Plane:

You can now see that all the necessary resources for Linkerd have been deployed to theĀ linkerdĀ Namespace. (kubectl -n linkerd get all)

Next, running theĀ linkerd checkĀ command will confirm that all necessary resources for the Linkerd Control Plane are installed and running correctly.

Now, let'sĀ install theĀ vizĀ extensionĀ to enhance Linkerd's observability features.
Installing LinkerdĀ vizĀ gives you access to a web dashboard, on-demand tap functionality, a Prometheus-compatible metrics API, and more. It's useful for visually understanding and analyzing the state of your Service Mesh.
Run the LinkerdĀ vizĀ extension installation command in your terminal:
linkerd viz install | kubectl apply -f -All the necessary resources for the LinkerdĀ vizĀ extension will be automatically installed.

The LinkerdĀ vizĀ extension is deployed in theĀ linkerd-vizĀ Namespace.

If you run theĀ linkerd viz dashboardĀ command in your terminal, you'll see a message that the LinkerdĀ vizĀ dashboard has opened. This sets up port-forwarding between your local machine and the Linkerd dashboard Service, making the dashboard accessible.

Open the URL from the message in your web browser, and...

You can now see the LinkerdĀ vizĀ web dashboard! The metrics for success rate, RPS, and P99 for traffic displayed by Namespace show that Linkerd is now operating normally.
Keep in mind that you need to keep the terminal where you ranĀ linkerd viz dashboardĀ open to maintain access to the dashboard.
We have now completed the Linkerd setup on our Minikube cluster! š
Next, to try out Linkerd's core features, we'll deploy two demo Deployments. Adding a Deployment to the Linkerd Service Mesh is also very simple!
Deploying a Sample App and Adding It to the Service Mesh
To observe traffic using the Linkerd Service Mesh we've just configured, the Service generating that traffic needs to be part of the mesh, right? Linkerd provides two main ways to do this:
Inject the Linkerd proxy into already-deployed Kubernetes resources using theĀ linkerd injectĀ command.
Add a Linkerd-aware annotation to a specific Namespace.
Since the terminal we've been using is keeping theĀ linkerd viz dashboardĀ process running, please open a separate terminal to continue with the lab.
And to deploy the Kubernetes resources for our Linkerd lab separately, let's first create a Namespace calledĀ linkerd-demo.

1. Using theĀ linkerd injectĀ command
To try theĀ linkerd injectĀ command, let's first deploy an Nginx Deployment without the Linkerd proxy. Save the following Deployment and Service manifest as a YAML file and apply it to your cluster.
# 1. 'Server' role Nginx Deployment to be observed by Linkerd
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world-server
namespace: linkerd-demo
spec:
replicas: 1
selector:
matchLabels:
app: hello-world-server
template:
metadata:
labels:
app: hello-world-server
spec:
containers:
- name: hello-world
image: nginx:alpine
ports:
- containerPort: 80
---
# 2. Service to call the 'server' Nginx Deployment from within the cluster
apiVersion: v1
kind: Service
metadata:
name: hello-world-server
namespace: linkerd-demo
spec:
selector:
app: hello-world-server
ports:
- name: http
port: 80
targetPort: 80
Now, if you go back to the LinkerdĀ vizĀ dashboard and click on theĀ linkerd-demoĀ Namespace we created...


Although theĀ hello-world-serverĀ Deployment we just deployed is listed, you'll notice that no metrics are being displayed yet. This is because the Linkerd proxy hasn't been injected into this Deployment, so Linkerd can't receive traffic metrics for it.
TheĀ MeshedĀ count you see in the image shows the number of resources currently included in the Service Mesh. Right now, it shows '0/1' because no resources are meshed yet.
TheĀ linkerd injectĀ command is what allows you to add the Linkerd proxy container directly to the Pod configuration of Kubernetes resources that were deployed before Linkerd was in place.
So, how can we inject the Linkerd proxy into the currently deployed Deployment and redeploy it? You can use the command below.
kubectl -n linkerd-demo get deploy -o yaml | linkerd inject - | kubectl apply -f -This command runs through the following flow:
Fetches the manifests of all Deployments in theĀ
linkerd-demoĀ Namespace in YAML format.Injects the Linkerd proxy-related annotations into the Pod configuration of the fetched manifests.
Redeploys the injected manifests back to the cluster.
Running this command will show a message indicating that the injection and configuration have been updated.

And if you look at the Deployment's configuration with theĀ describeĀ command...

You can see that an annotation indicating that Linkerd's injection is enabled has been added to the Pod configuration, as highlighted in the red box. Now, let's check the Linkerd web dashboard again.

The Meshed count has been updated to 1/1, and the metrics are now displaying correctly!
As you can see, theĀ linkerd injectĀ command makes it easy and fast to bring even pre-existing Kubernetes resources into Linkerd's Service Mesh.
2. Adding a Linkerd-aware Annotation to a Namespace
ButĀ what if you want Pods deployed to a specific Namespace to be included in the Linkerd Service Mesh as soon as they're created?Ā This is a very common scenario.
In this case, all you need to do isĀ add Linkerd's annotation to the desired Namespace.Ā Since this is straightforward, let's jump right into it.
First, let's check the configuration of our existing Namespace linkerd-demo.

Since we didn't add any other settings when we created this Namespace, it only has the default values.Ā The kubectlĀ supports anĀ annotateĀ command to add annotations (annotate) to resources, so let's add Linkerd's annotation with the following command:
kubectl annotate namespace linkerd-demo linkerd.io/inject=enabled
If you check the Namespace configuration again, you'll see that the same annotation added in the first injection method is now present. Now, any new Pod added to theĀ linkerd-demoĀ Namespace will automatically get the Linkerd proxy sidecar container. That was quick, right?
Now, let's deploy a new Deployment to this Namespace. This Deployment, namedĀ traffic-generator, sends HTTP traffic to ourĀ hello-world-serverĀ every 2 seconds. We'll take a look at this later with Linkerd's traffic observation features.
# 'Client' Deployment that consistently generates traffic to the 'Server'
apiVersion: apps/v1
kind: Deployment
metadata:
name: traffic-generator
namespace: linkerd-demo
spec:
replicas: 1
selector:
matchLabels:
app: traffic-generator
template:
metadata:
labels:
app: traffic-generator
spec:
containers:
- name: traffic-curl
image: curlimages/curl:latest
# Sends an HTTP request to the hello-world-server service every 2 seconds.
command: ["sh", "-c", "while true; do echo '--> Sending request to hello-world-server'; curl -s http://hello-world-server > /dev/null; echo 'Request sent.'; sleep 2; done"]I saved the above YAML file asĀ client.yamlĀ and applied it to the cluster with theĀ kubectl applyĀ command.

And if we check the Linkerd web dashboard again...

The Pod of the newly deployed Deployment is now in a Meshed state, and its traffic metrics are also being displayed correctly! From now on, any new Pod created in theĀ linkerd-demoĀ Namespace will automatically be incorporated into Linkerd's Service Mesh.
So far, we've learned about two ways to bring Pods into Linkerd's Service Mesh. These are very simple methods that reflect Linkerd's design philosophies of 'Keep it simple' and 'Just work'.
Now that our Deployments are properly integrated into the Linkerd Service Mesh, let's actually try out Linkerd's core features.
Getting Hands-On with Linkerd's Core Features
Most of Linkerd's core features can be accessed from the Linkerd web dashboard. However, there are times when you need to check specific things directly from the terminal with a command. To wrap up this lab, let's go overĀ three essential Linkerd commandsĀ together.
1. Check Current Traffic Stats withĀ linkerd viz stat
linkerd viz statĀ is a tool that provides a summary of real-time traffic statistics for resources within the Linkerd Service Mesh. By using it as shown below, you canĀ check the current requests per second (RPS), success rate (SR), and latency (P99)Ā for all Deployments in theĀ linkerd-demoĀ Namespace.
linkerd viz stat deploy -n linkerd-demo
2. Observe Real-Time Request and Response Streams withĀ linkerd viz tap
TheĀ linkerd viz tapĀ command is a tool that captures and displays a real-time stream of actual requests and responses passing through a specific K8s resource (Deployment, Pod, Service, etc.). This is useful for troubleshooting or traffic analysis, as it allows developers and operators toĀ directly inspect the headers, body, status codes, and latency of individual requests.
You can view the real-time request and response stream for all Deployments in theĀ linkerd-demoĀ Namespace as follows:
linkerd viz tap deploy -n linkerd-demo
3. Check mTLS Encrypted Connection Status withĀ linkerd viz edges
As we mentioned, Linkerd automatically encrypts all TCP communication between services included in the Service Mesh with mTLS. This mTLS connection status can be visually confirmed in the Linkerd dashboard's topology view or in the details of each service.
You can also use a command likeĀ linkerd viz edges deploy -n {Namespace_name}Ā in the terminal toĀ immediately check which services are communicating securely with mTLS.Ā For example, running the command below will show the mTLS connection status for all Deployments in theĀ linkerd-demoĀ Namespace.
linkerd viz edges deploy -n linkerd-demo
Wrapping Up
We've covered everything from installing Linkerd and adding a Deployment to the Service Mesh to using three of Linkerd's core commands. Are you getting a better feel for what Linkerd is all about?
Of course, to successfully adopt Linkerd in a real production environment, there are more considerations, such as planning for the resource requirements of the Control and Data Planes and configuring Control Plane replication for high availability.
However, the experience of installing and operating a Service Mesh like Linkerd firsthand builds practical skills needed to solve complex communication problems in a microservice architecture and to improve a service's observability, reliability, and security.
This experience is more than just learning a single tool; it's a crucial foundation that deepens your overall understanding of system operations in a cloud-native environment.
I truly hope this series has been a great first step for those who wanted to learn more about Service Mesh or Linkerd.
I'll see you in the next article with another interesting topic. Thank you!
References
āØEnjoyed this issue?
How about this newsletter? Iād love to hear your thought about this issue in the below form!
š Feedback Form
Your input will be help improve Aidenās Lab Notebook and make it more useful for you.
Thanks again for reading this notebook from Aidenās Lab :)
