Get Service Mesh Certified with Buoyant.

Enroll now!
close

Buoyant Blog

Demo: Migrating from Istio to Linkerd

Blog home

Scott Rigby

Oct. 22. 2024

Linkerd

Did you read the Migrating from Istio to Linkerd blog post and are ready to explore a migration? Before diving into your production environment, test the waters with this step-by-step guide to setting up a demo migration. While this walkthrough provides a valuable learning experience, remember that production migrations require careful planning. Be sure to revisit the Planning the Migration section before tackling your production clusters. 

In the first migration blog post, we provide an overview of all the concepts and the context you need for a successful migration. If you haven't read it, we recommend you do so before going through this tutorial. If you did, let's get right to it!

Hands-on demo

Prerequisites

To follow along with this tutorial, you'll need to install:

  • docker
  • k3d
  • kubectl
  • istioctl
  • linkerd
  • siege

I'm on a MacBook, so I use Homebrew for most of this – we’ll install the Linkerd CLI later.

Version check

Current versions as of this tutorial:

Ok, looks like we're good! There may be differences in future versions, so it's always good to check which you're running.

Create demo cluster

For this demo we're using the k3d wrapper to install k3s locally.

Install sample app on Istio

Let’s use the bookinfo project from Istio to demonstrate a migration. We'll mostly follow the Istio Getting Started guide and also draw from other Istio docs for steps to ensure it works correctly on our local k3s cluster.

1. Install Istio

The demo profile is suitable for Istio's Bookinfo application. There are many additional Istio features we could add, but we'll stick strictly to Istio's Bookinfo application to simulate our migration:

Label the default namespace. Adding a namespace label instructs Istio to automatically inject Envoy sidecar proxies when you deploy the sample application next.

2. Install Bookinfo sample app

3. Expose the app to outside traffic using Istio Ingress Gateway

For local demo purposes, we'll be port-forwarding (in the cloud, you would instead use the Istio Ingress Gateway load balancer's external IP).

Check that it works from outside of the cluster:

If you want you can manually see the app in your web browser too:

4. Visualize app traffic on Istio

Install Istio's visualizer, Kiali, and other required addons to visualize traffic:

In a separate terminal tab, send some traffic to the app through Istio Ingress Gateway:

In another terminal tab, use this command to port-forward and automatically open Kiali in your browser:

The Overview (default) page in Kiali should show something like this:

Kiali Overview tab showing mock traffic through Istio
Kiali Overview tab showing mock traffic through Istio

Click the Graph tab on the left, in the Namespace drop-down, select default, and on the right select Last 10m, and you should see the Versioned app graph (default):

Kiali Graph tab showing HTTP requests through the Bookinfo application services
Kiali has more UI options but these are good for our demo.

OK, we're all set up with a simulated simple Istio bookinfo app installation showing traffic through Istio. Now that we've got that sorted, let's move on to preparing for migration to Linkerd.

Replace Istio Gateway with an Ingress Controller

(source)

OK, so now we're on to the fun part. The Istio sample application is relatively simple to migrate to Linkerd, in several easy steps.

We’ll start with ingress. As of this writing (mid 2024), Linkerd doesn’t provide its own ingress solution (though it’s on the roadmap!), leaving the choice of using a third-party ingress controller or (as shown in the migration blog post) using the Istio ingress gateway in place. For this demo, let’s do it the hard way and replace the Istio ingress gateway with Ingress-NGINX instead!

This is pretty straightforward, but we’ll have to be sure to have Ingress-NGINX in place before migrating any workloads, so that we can  avoid downtime during an in-place migration to Linkerd. We'll also be installing our mesh in non-strict mode so that both the Istio Gateway and new ingress controller can send traffic to our sample app at the same time

For simplicity, Linkerd does not provide its own ingress controller. Instead, Linkerd is designed to work alongside your ingress controller of choice for routing traffic. For this demo we'll use the popular Ingress-NGINX project.

1. Deploy the Ingress-NGINX controller

There are additional options here, but for this demo you just need to run:

💡 Note for this demo we'll keep the default behavior that the controller watches all namespaces for ease. To change this, see scope section of the controller install guide.

2. Expose app to outside traffic using Nginx Ingress

Create a Kubernetes Ingress resource pointing to the sample app:

💡 Note the nginx.ingress.kubernetes.io/service-upstream annotation is recommended by Linkerd for this Ingress controller wherever you use it. The nginx.ingress.kubernetes.io/ssl-redirect annotation is because we're not setting up SSL for this local demo.

In a new terminal tab, port forward the Ingress NGINX service as well:

Check that this works from outside of the cluster too:

Migrate sample app from Istio to Linkerd

1. Install the Linkerd CLI

We’re going to use Buoyant Enterprise for Linkerd for this tutorial. To follow along, you’ll need to register for a free Buoyant account at https://enterprise.buoyant.io/ (it only takes a few seconds). Once you’ve done that and set the BUOYANT_LICENSE environment variable as shown in the registration process, you’ll install the Linkerd CLI as described in the Getting Started guide:

💡The latest version of Buoyant Enterprise for Linkerd is currently enterprise-2.16.0 This guide also works with the latest edge release of Linkerd, currently edge-24.8.2 – to use an edge release, start with installing the edge CLI, as described in the edge release quick start.

Once you have the CLI installed, setting up Linkerd in a demo configuration is easy (these steps also come from the Getting Started guide, but we’re installing Linkerd Viz as well.)

💡Remember that this installs Linkerd in a demo configuration (same as we did with Istio). For production installations, there’s a separate guide that you’ll want to check out.

2. Add Ingress-NGINX controller to Linkerd

Mesh the ingress pods, following the Linkerd common ingress options guide. Since we installed the ingress controller with a manifest (rather than with Helm) we can mesh normally by annotating either the Namespace or Deployment resource. Let's go with the Deployment (the effect is the same, with the main difference being you don't need to manually restart the pods):

This produces:

And after just a moment, you can see that the pod was injected correctly:

3. Prepare default namespace for Linkerd sidecar injection instead of the Istio sidecar

While it's perfectly fine to have both Istio and Linkerd running in your cluster at the same time, we shouldn't inject two proxies on a pod at the same time, because each sidecar would fight for hijacking traffic in and out of the pod (the one that runs last in the race condition would win).

Luckily, switching from Istio to Linkerd's proxy is as simple as removing the istio-injection label on the namespace and replacing it with the linkerd.io/inject annotation, then restarting the pod. When the pod restarts, it will automatically contain the Linkerd proxy sidecar and no longer the Istio sidecar.

So we'll go ahead and make this change to the default namespace, since it's where we installed the sample app:

4. Visualize app traffic switching to Linkerd

Similar to what we previously did for Istio, we'll also send some traffic to the same sample app through the Ingress NGINX service that we're already port-forwarding:

In a separate terminal tab, port-forward and automatically open the Linkerd visualizer by running:

Now we can toggle between Istio's Kiali and Linkerd's viz browser tabs as we watch each of the services switch over.

In Kiali, you'll want to click on the Workloads tab and make sure it's set to refresh every 10s. At this point, all the Bookinfo services are part of the Istio mesh.

In Linkerd Viz, select the Default namespace, and click on Deployments. Each of the services will all say 0/1 at this point because they are not yet part of the Linkerd mesh.

Let's see what happens when we restart one service now that our namespace is set to inject the Linkerd sidecar instead of the Istio sidecar:

One workload (ratings) is now part of the Linkerd mesh, whereas Kiali now reports the Istio sidecar as missing for that service. And all other workloads are still part of Istio mesh.

Linkerd VIZ with a Bookinfo service being meshed.
Linkerd Viz with a Bookinfo service being meshed.
Kiali reports the Istio sidecar as missing for the service we migrated to Linkerd. All other workloads are still part of the Istio mesh.
Kiali reports the Istio sidecar as missing for the service we migrated to Linkerd. All other workloads are still part of the Istio mesh.

You may be wondering how rollout restart works to switch over the pods. Both Istio and Linkerd have a mechanism to inject their proxy sidecar, with Istio using a label and Linkerd using an annotation. (Istio calls this automatic sidecar injection, Linkerd calls it automatic proxy injection). In both cases, if you have the Istio label or Linkerd annotation on a namespace, any new pod created in that namespace will get the respective sidecar proxy injected into the pod.

Now let's switch over to another service, but this time monitor the progress in Linkerd Viz:

You can watch the success rate in viz slowly move up from 50% to 100%.

Linkerd VIZ showing the reviews-v1 service being meshed at a 50% success rate.
Linkerd Viz shows the reviews-v1 service meshed at a 50% success rate.
Linkerd VIZ shows the reviews-v1 service being meshed at a 85.71% success rate.
Linkerd Viz shows the reviews-v1 service meshed at a 85.71% success rate.
Linkerd VIZ shows the reviews-v1 service meshed at a 50% success rate.
Linkerd Viz shows the reviews-v1 service meshed at a 100% success rate.

All the while we're getting HTTP 200 in our simulated traffic reports.

Siege output shows HTTP 200 in our simulated traffic reports.
Siege output shows HTTP 200 in our simulated traffic reports.

Everything seems to be running smoothly, so we'll repeat for the rest of the services:

Linkerd Viz will now show all services at 100%, and Kiali will now show "Empty Graph".

Linkerd Viz shows most services at 100%, with the last two services at a 80.95% and 56.25% success rate being meshed.
Linkerd Viz shows most services at 100%, with the last two services at a 80.95% and 56.25% success rate being meshed.
Kiali showing "Empty Graph."
Kiali showing "Empty Graph."
Kiali Overview tab showing no inbound traffic to services in the default namespace.
Kiali Overview tab showing no inbound traffic to services in the default namespace.
Linkerd Viz shows all services fully meshed at 100%.
Linkerd Viz shows all services fully meshed at 100%.
Linkerd Viz default Namespace screen shows all services at 100% with a network graph including all Bookinfo services
Linkerd Viz default Namespace screen shows all services at 100% with a network graph including all Bookinfo services.

Lovely. We're all migrated!

💡But wait! What happened to running ingress2gateway like the migration blog post said?

As it happens, the booksapp is simple enough in its base configuration that it doesn’t need any extra configuration to work with Linkerd! So while we certainly could run ingress2gateway and explore more advanced topics like authorization policy, all we really need to do here is to switch meshes.

Cleanup

Remove Istio

Once you've done this for each of your services, and Istio is no longer responsible for any traffic to them, you can remove Istio altogether. Luckily Istio has a pretty easy way to do this:

Cleanup demo cluster

There you have it! Since we did this all locally, it's easy to clean up this demo by simply deleting your demo cluster.

I hope you enjoyed the hands-on demonstration. 

🙇 Digging into this has been a lot of fun, and I didn't do it alone. Big thanks to Sergio Méndez (Linkerd Ambassador) and Ariel Jatib, who've been at this for longer and helped encourage and guide my service mesh migration journey.