Guest post originally published on Buoyant’s blog by Michael Levan

As discussed in my introduction to Linkerd, service meshes provide important, powerful security, reliability, and observability features. And although many engineers shy away from implementing a service mesh due to its perceived complexity, there is no real reason to wait if you use Linkerd. 

Today, we’ll show three different deployments of Linkerd:

  1. We’ll use the linkerd CLI to deploy Linkerd on Azure. The CLI is ideal for development, test, or local environments.
  2. Next we’ll use Helm to deploy Linkerd on AWS. Helm is the recommended way to deploy Linkerd in production environments. 
  3. Finally, we’ll use Helm to deploy Linkerd in HA mode on GKE. HA mode is highly recommended for production use.

You can mix and match the deployment mode and the cloud provider. Use the CLI for GKE; use Helm in HA mode mode on AWS – any mode will work on any cloud. You’ll get the best picture by reading all three examples.

Setup: Generating Certificates

We will be exploring production-ready methods and, for some approaches, you’ll need your own mTLS certificates. Hence, you’ll need a way to generate them. For this tutorial, I’ll use Step. How you generate your certificate is really up to you. You can use openSSL, LetsEncrypt, or any other certificate creation tool. If you’d like to use Step as I did, check out the Step install guide here.  

The step installation varies depending on the OS you’re on. On MacOS and many Linux systems, you can use homebrew:

brew install step

If you’re running a Debian-based Linux distribution like Ubuntu, you can use the following Debian method:

wget https://dl.step.sm/gh-release/cli/docs-cli-install/v0.23.1/step-cli_0.23.1_amd64.deb sudo dpkg -i step-cli_0.23.1_amd64.deb

Once installed, create the certificate and key for mTLS with this command.

step certificate create root.linkerd.cluster.local ca.crt ca.key \
     --profile root-ca --no-password --insecure

The output is simple – step just confirms that it’s saved information in the files you’ve specified.

Your certificate has been saved in ca.crt.
Your private key has been saved in ca.key.

Next, create the certificate and key to sign the Linkerd proxies CSR.

step certificate create identity.linkerd.cluster.local issuer.crt issuer.key \
     --profile intermediate-ca --not-after 8760h --no-password --insecure \
     --ca ca.crt --ca-key ca.key

Again, the output is a simple confirmation of where the keys were saved:

Your certificate has been saved in issuer.crt.
Your private key has been saved in issuer.key.

Now that you have the certificates and keys, you can start using them in various environments. Let’s have a look at how it works with AKS.

Deploying Linkerd on Azure Kubernetes Service (AKS)

Armed with your newly created certificates and keys, you are ready to deploy Linkerd on Azure Kubernetes Service (AKS). In this section, we deploy Linkerd with the CLI (remember, this is only recommended for  development, test, or local environments – for production settings, please use Helm as described in the next section). While you don’t have to generate your own certificates and keys when installing Linkerd with the CLI, it is recommended to do so, so that you know what certificates and keys you’re using, and you have full control over key management.

Ok, back to our CLI. Ensure that the Custom Resource Definitions (CRDs) for Linkerd are properly installed:

linkerd install --crds | kubectl apply -f -

To check and confirm the CRDs were installed successfully, run:

kubectl get crd | grep linkerd

The output should look roughly like this (obviously, the dates will be different):

NAME                                           CREATED AT
meshtlsauthentications.policy.linkerd.io       2023-05-15T13:58:22Z
httproutes.policy.linkerd.io                   2023-05-15T13:58:22Z
serviceprofiles.linkerd.io                     2023-05-15T13:58:22Z
servers.policy.linkerd.io                      2023-05-15T13:58:22Z
networkauthentications.policy.linkerd.io       2023-05-15T13:58:22Z
authorizationpolicies.policy.linkerd.io        2023-05-15T13:58:22Z
serverauthorizations.policy.linkerd.io         2023-05-15T13:58:22Z
dataplanes.linkerd.buoyant.io                  2023-05-15T13:59:47Z
controlplanes.linkerd.buoyant.io               2023-05-15T13:59:47Z

Once the CRDs are installed successfully, install Linkerd using the CLI:

linkerd install \
        --identity-trust-anchors-file ca.crt \
        --set proxyInit.runAsRoot=true \
        --identity-issuer-certificate-file issuer.crt \
        --identity-issuer-key-file issuer.key \ 
    | kubectl apply -f -

You’ll get a lot of output from kubectl apply here; linkerd install creates quite a few Kubernetes resources! Once it finishes, check to make sure all is well:

linkerd check

This, too, will produce quite a bit of output: what’s important is that you see green checkmarks (√) for each status. At the end, you should see:

Status check results are √

…telling you that Linkerd is ready to go!

We’ll test Linkerd with a demo application. I’ll be using the Emojivoto demo app with the linkerd inject command, which injects a sidecar into the Pod.

curl -sL https://run.linkerd.io/emojivoto.yml \
    | linkerd inject - | kubectl apply -f -

In the output, you’ll see that Deployments were “injected”, meaning that the Linkerd sidecar container was deployed, while other resources were “skipped”. This is what we expect, since linkerd inject will only inject things that create Pods.

namespace “emojivoto” skipped
serviceaccount “emoji” skipped
serviceaccount “voting” skipped
serviceaccount “voting” skipped
service “emoji-svc” skipped
service “voting-svc” skipped
service “web-svc” skipped
deployment “emoji” injected
deployment “vote-bot” injected
deployment “voting” injected
deployment “web” injected

namespace/emojivoto created
serviceaccount/emoji created
serviceaccount/voting created
serviceaccount/voting created
service/emoji-svc created
service/voting-svc created
service/web-svc created
deployment/emoji created
deployment/vote-bot created
deployment/voting created
deployment/web created

You’re now ready to test your application using AKS!

Deploying Linkerd on Elastic Kubernetes Service (EKS)

In the example above, we used the Linkerd CLI to deploy Linkerd. That’s a great method to deploy Linkerd in development or local environments using tools like Minikube or Kind. For our Elastic Kubernetes Service (EKS) deployment, we’ll use Helm. 

Start by adding the Linkerd Helm repo:

helm repo add linkerd https://helm.linkerd.io/stable

Next, install the CRDs for Linkerd:

helm install linkerd-crds linkerd/linkerd-crds \
             -n linkerd --create-namespace

As with linkerd apply or linkerd check, Helm will produce output telling you what’s up. The important bit is that it finishes with:

The linkerd-crds chart was successfully installed. 🎉

After that, use Helm to install the Linkerd control plane. The Helm install command will include:

helm install linkerd-control-plane linkerd/linkerd-control-plane \
     -n linkerd \
     --set-file identityTrustAnchorsPEM=ca.crt \
     --set-file identity.issuer.tls.crtPEM=issuer.crt

WARNING

If you’re using EKS with Kubernetes version 1.23 (which is currently the default for EKS), you’ll need to add –set proxyInit.runAsRoot=true to your Helm command:

helm install linkerd-control-plane linkerd/linkerd-control-plane \
     -n linkerd \
     --set-file identityTrustAnchorsPEM=ca.crt \
     --set-file identity.issuer.tls.crtPEM=issuer.crt \
     --set proxyInit.runAsRoot=true

If you don’t, you’ll get an error:

There are nodes using the docker container runtime and proxy-init container must run as root user.

Back to where we were.

Again, Helm will produce output telling you what it’s just done. As long as it finishes with:

The linkerd control plane was successfully installed. 🎉

then all is well. Finish up by running linkerd check and look for it to finish with

Status check results are √

At this point, you can deploy the Emojivoto app using the steps outlined at the end of the Azure Kubernetes Service (AKS) section. Deploying the application doesn’t change from cluster to cluster.

Deploying Linkerd on Google Kubernetes Engine (GKE)

In this last section, we’ll deploy Linkerd on Google Kubernetes Engine (GKE) with the same Helm approach, but we’ll use Linkerd’s high availability (HA mode).

The first requirement for Linkerd HA mode is that you use a Kubernetes cluster with at least three worker nodes, so that the cluster can ride through a single-Node failure. Linkerd HA won’t function with fewer than three Nodes. Running kubectl get nodes should show you something like this:

NAME                                  STATUS  ROLES   AGE  VERSION
gke-gke01-default-pool-47a0bc0a-jgql  Ready     14m  v1.24.8-gke.2000
gke-gke01-default-pool-47a0bc0a-qq88  Ready     14m  v1.24.8-gke.2000
gke-gke01-default-pool-47a0bc0a-wcbl  Ready     14m  v1.24.8-gke.2000

where the critical part isn’t what kind of Nodes or how old they are, but that there are at least three of them.

The first bits here are exactly like the EKS section: add the Helm repo if you haven’t already done that:

helm repo add linkerd https://helm.linkerd.io/stable

Then install the CRDs for Linkerd:

helm install linkerd-crds linkerd/linkerd-crds \
             -n linkerd --create-namespace

and look for Helm’s output to end with

The linkerd-crds chart was successfully installed. 🎉

You’ll install Linkerd HA with Helm by using the values-ha.yaml file included in the Linkerd Helm chart, rather than the non-HA values.yaml. Start by using the helm fetch command to extract the chart, so that you have access to the values-ha.yaml file:

helm fetch --untar linkerd/linkerd-control-plane

The last step is to install Linkerd with Helm. Notice the key difference between the EKS installation and this installation – there’s a -f flag pointing to the values-ha.yaml file.

helm install linkerd-control-plane linkerd/linkerd-control-plane \
     -n linkerd \
     --set-file identityTrustAnchorsPEM=ca.crt \
     --set-file identity.issuer.tls.crtPEM=issuer.crt \
     --set-file identity.issuer.tls.keyPEM=issuer.key \
     -f linkerd-control-plane/values-ha.yaml

Again, Helm’s output needs to finish with:

The linkerd control plane was successfully installed. 🎉

Unlike in the EKS deployment screenshot shown above, you’ll end up with three replicas of each Deployment instead of one (and, if you look closer, you’ll find that each replica is running on a separate Node). Running kubectl get pods -n linkerd should show you something like this:

NAME                                      READY   STATUS    RESTARTS   AGE
linkerd-identity-7c95d8cb9d-gsbfc         2/2     Running   0          2m30s
linkerd-identity-7c95d8cb9d-sz88b         2/2     Running   0          2m30s
linkerd-identity-7c95d8cb9d-18epx         2/2     Running   0          2m30s
linkerd-proxy-injector-56cbd84b46-hkfvx   2/2     Running   0          2m30s
linkerd-proxy-injector-56cbd84b46-fhxm1   2/2     Running   0          2m30s
linkerd-proxy-injector-56cbd84b46-j6ahg   2/2     Running   0          2m30s
linkerd-destination-cf56fc5c5-h2mm6       4/4     Running   0          2m30s
linkerd-destination-cf56fc5c5-mlm1z       4/4     Running   0          2m30s
linkerd-destination-cf56fc5c5-6ghuz       4/4     Running   0          2m30s

As with EKS and AKS now that Linkerd is running you can deploy the Emojivoto app using the steps outlined at the end of the Azure Kubernetes Service (AKS) section: deploying the application doesn’t change from cluster to cluster.

Three clouds, three easy deployments

So there you have it: three straightforward examples of how to deploy Linkerd on three different clouds, with three different deployment methods.

Hopefully, this is a good demonstration that service meshes don’t have to be complex. Linkerd’s design principles minimize configuration and operational simplicity, ensuring that the most important features are deployed by default with no needed tweaks. There’s no need to wait to get security, observability, and reliability features for your cloud-native applications: you can use Linkerd from day one and save yourself trouble right from the start.