2020-10-31 14:51:00 +11:00

7.2 KiB

Introduction to Linkerd

We need a Kubernetes cluster

Lets create a Kubernetes cluster to play with using kind

kind create cluster --name linkerd --image kindest/node:v1.19.1

Deploy our microservices (Video catalog)

# ingress controller
kubectl create ns ingress-nginx
kubectl apply -f kubernetes/servicemesh/applications/ingress-nginx/

# applications
kubectl apply -f kubernetes/servicemesh/applications/playlists-api/
kubectl apply -f kubernetes/servicemesh/applications/playlists-db/
kubectl apply -f kubernetes/servicemesh/applications/videos-web/
kubectl apply -f kubernetes/servicemesh/applications/videos-api/
kubectl apply -f kubernetes/servicemesh/applications/videos-db/

Make sure our applications are running

kubectl get pods
NAME                            READY   STATUS    RESTARTS   AGE  
playlists-api-d7f64c9c6-rfhdg   1/1     Running   0          2m19s
playlists-db-67d75dc7f4-p8wk5   1/1     Running   0          2m19s
videos-api-7769dfc56b-fsqsr     1/1     Running   0          2m18s
videos-db-74576d7c7d-5ljdh      1/1     Running   0          2m18s
videos-web-598c76f8f-chhgm      1/1     Running   0          100s 

Make sure our ingress controller is running

kubectl -n ingress-nginx get pods
NAME                                        READY   STATUS    RESTARTS   AGE  
nginx-ingress-controller-6fbb446cff-8fwxz   1/1     Running   0          2m38s
nginx-ingress-controller-6fbb446cff-zbw7x   1/1     Running   0          2m38s

We'll need a fake DNS name servicemesh.demo
Let's fake one by adding the following entry in our hosts (C:\Windows\System32\drivers\etc\hosts) file:

127.0.0.1  servicemesh.demo

Let's access our applications via Ingress

kubectl -n ingress-nginx port-forward deploy/nginx-ingress-controller 80

Access our application in the browser

We should be able to access our site under http://servicemesh.demo/home/



Getting Started with Linkerd

Firstly, I like to do most of my work in containers so everything is reproducible
and my machine remains clean.

Get a container to work in


Run a small `alpine linux` container where we can install and play with `linkerd`:
docker run -it --rm -v ${HOME}:/root/ -v ${PWD}:/work -w /work --net host alpine sh

# install curl & kubectl
apk add --no-cache curl nano
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
chmod +x ./kubectl
mv ./kubectl /usr/local/bin/kubectl
export KUBE_EDITOR="nano"

#test cluster access:
/work # kubectl get nodes
NAME                    STATUS   ROLES    AGE   VERSION
linkerd-control-plane   Ready    master   26m   v1.19.1

Linkerd CLI

Lets download the linkerd command line tool
I grabbed the edge-20.10.1 release using curl

You can go to the releases page to get it

curl -L -o linkerd https://github.com/linkerd/linkerd2/releases/download/edge-20.10.1/linkerd2-cli-edge-20.10.1-linux-amd64 
chmod +x linkerd && mv ./linkerd /usr/local/bin/

linkerd --help

Pre flight checks

Linkerd has a great capability to check compatibility with the target cluster

linkerd check --pre

Get the YAML

linkerd install > ./kubernetes/servicemesh/linkerd/manifest/linkerd-edge-20.10.1.yaml

Install Linkerd

kubectl apply -f ./kubernetes/servicemesh/linkerd/manifest/linkerd-edge-20.10.1.yaml

Let's wait until all components are running

watch kubectl -n linkerd get pods
kubectl -n linkerd get svc

Do a final check

linkerd check

The dashboard

Let's access the linkerd dashboard via port-forward

kubectl -n linkerd port-forward svc/linkerd-web 8084

Mesh our video catalog services

There are 2 ways to mesh:

  1. We can add an annotation to your deployment to persist the mesh if our YAML is part of a GitOps flow: This is a more permanent solution:
  template:
    metadata:
      annotations:
        linkerd.io/inject: enabled
  1. Or inject linkerd on the fly: This may only be temporary as your CI/CD system may roll out the previous YAML
kubectl get deploy
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
playlists-api   1/1     1            1           8h 
playlists-db    1/1     1            1           8h 
videos-api      1/1     1            1           8h 
videos-db       1/1     1            1           8h 
videos-web      1/1     1            1           8h 

kubectl get deploy playlists-api -o yaml | linkerd inject - | kubectl apply -f -
kubectl get deploy playlists-db -o yaml | linkerd inject - | kubectl apply -f -
kubectl get deploy videos-api -o yaml | linkerd inject - | kubectl apply -f -
kubectl get deploy videos-db -o yaml | linkerd inject - | kubectl apply -f -
kubectl get deploy videos-web -o yaml | linkerd inject - | kubectl apply -f -
kubectl -n ingress-nginx get deploy nginx-ingress-controller  -o yaml | linkerd inject - | kubectl apply -f -

Generate some traffic

Let's run a curl loop to generate some traffic to our site
We'll make a call to /home/ and to simulate the browser making a call to get the playlists,
we'll make a follow up call to /api/playlists

While ($true) { curl -UseBasicParsing http://servicemesh.demo/home/;curl -UseBasicParsing http://servicemesh.demo/api/playlists; Start-Sleep -Seconds 1;}

linkerd -n default check --proxy

linkerd -n default stat deploy

Add Faulty behaviour in videos API

kubectl edit deploy videos-api

#set environment FLAKY=true

Service Profile

linkerd profile -n default videos-api --tap deploy/videos-api --tap-duration 10s

After crafting the serviceprofile, we can apply it using kubectl

 kubectl apply -f kubernetes/servicemesh/linkerd/serviceprofiles/videos-api.yaml

We can see that service profile helps us add retry policies in place:

linkerd routes -n default deploy/playlists-api --to svc/videos-api -o wide
linkerd top deploy/videos-api

Mutual TLS

We can validate if mTLS is working

/work # linkerd -n default edges deployment
SRC                  DST             SRC_NS    DST_NS    SECURED       
playlists-api        videos-api      default   default   √
linkerd-prometheus   playlists-api   linkerd   default   √
linkerd-prometheus   playlists-db    linkerd   default   √
linkerd-prometheus   videos-api      linkerd   default   √
linkerd-prometheus   videos-db       linkerd   default   √
linkerd-prometheus   videos-web      linkerd   default   √
linkerd-tap          playlists-api   linkerd   default   √
linkerd-tap          playlists-db    linkerd   default   √
linkerd-tap          videos-api      linkerd   default   √
linkerd-tap          videos-db       linkerd   default   √
linkerd-tap          videos-web      linkerd   default   √

linkerd -n default tap deploy