Contents
- Chapter 15 - Installing Linkerd
- Chapter 16 - Exploring the Reliability Features of Linkerd
- Chapter 17 - Exploring the Security Features of Linkerd
- Chapter 18 - Exploring the Observability Features of Linkerd
This branch has scripts that works with Linkerd stable-2.6.0 release.
Copy and paste command as you practice.
curl -Ls https://api.github.com/repos/linkerd/linkerd2/releases | grep tag_name
cd ## Switch to the home directory
export LINKERD2_VERSION=stable-2.6.0
curl -s -L https://run.linkerd.io/install | sh -
vi ~/.bashrc
## Add these two lines
export LINKERD2_VERSION=stable-2.6.0
export PATH=$PATH:$HOME/.linkerd2/bin
source ~/.bashrc
echo $LINKERD2_VERSION
linkerd version
linkerd check --pre
kubectl create clusterrolebinding linkerd-cluster-role-binding \
--clusterrole=cluster-admin --group=system:serviceaccounts:linkerd
linkerd install | kubectl apply -f -
linkerd check
linkerd version
kubectl -n linkerd get deployments
kubectl -n linkerd get services
kubectl -n linkerd get pods
linkerd install config | kubectl apply -f -
linkerd check config
linkerd install control-plane | kubectl apply -f -
cd ~/ # Switch to home directory
git clone https://github.com/servicemeshbook/linkerd.git
cd linkerd
git checkout $LINKERD2_VERSION
cd scripts
helm repo add nginx-stable https://helm.nginx.com/stable
helm repo update
helm install nginx-stable/nginx-ingress --name nginx --namespace kube-system \
--set fullnameOverride=nginx \
--set controller.name=nginx-controller \
--set controller.config.name=nginx-config \
--set controller.service.name=nginx-controller \
--set controller.serviceAccount.name=nginx
kubectl -n kube-system get services -o wide -l app.kubernetes.io/instance=nginx
export INGRESS_HOST=$(kubectl -n kube-system get service nginx-controller -o jsonpath='{.status.loadBalancer.ingress..ip}') ; echo $INGRESS_HOST
sudo sed -i '/dashboard.linkerd.local/d' /etc/hosts
echo "$INGRESS_HOST dashboard.linkerd.local" | sudo tee -a /etc/hosts
cat 01-create-linkerd-ingress.yaml
kubectl -n linkerd apply -f 01-create-linkerd-ingress.yaml
curl -s -H "Host: dashboard.linkerd.local" http://$INGRESS_HOST | grep -i title
kubectl create clusterrolebinding emojivoto-cluster-role-binding \
--clusterrole=cluster-admin --group=system:serviceaccounts:emojivoto
curl -Ls https://run.linkerd.io/emojivoto.yml | kubectl apply -f -
kubectl -n emojivoto get deployments,services,pods
export INGRESS_HOST=$(kubectl -n kube-system get service nginx-controller -o jsonpath='{.status.loadBalancer.ingress..ip}') ; echo $INGRESS_HOST
sudo sed -i '/emojivoto.linkerd.local/d' /etc/hosts
echo "$INGRESS_HOST emojivoto.linkerd.local" | sudo tee -a /etc/hosts
cat 02-create-emojivoto-ingress.yaml
kubectl -n emojivoto apply -f 02-create-emojivoto-ingress.yaml
curl -s -H "Host: emojivoto.linkerd.local" http://$INGRESS_HOST | grep -i title
kubectl get -n emojivoto deploy -o yaml | linkerd inject - | kubectl apply -f -
kubectl -n emojivoto get deployments
kubectl -n emojivoto get pods
kubectl -n emojivoto get services
kubectl -n linkerd get deploy -l linkerd.io/control-plane-component=proxy-injector
kubectl create clusterrolebinding linkerd-lab-cluster-role-binding \
--clusterrole=cluster-admin --serviceaccount=linkerd:default
cat 03-create-namespace-sidecar-enabled-annotation.yaml
kubectl apply -f 03-create-namespace-sidecar-enabled-annotation.yaml
curl -Ls https://run.linkerd.io/booksapp.yml | kubectl -n linkerd-lab apply -f -
kubectl -n linkerd-lab get svc
kubectl -n linkerd-lab get pods
kubectl -n linkerd-lab describe pod -l app=authors
sudo sed -i '/booksapp.linkerd.local/d' /etc/hosts
echo "$INGRESS_HOST booksapp.linkerd.local" | sudo tee -a /etc/hosts
cat 04-create-booksapp-ingress.yaml
kubectl -n linkerd-lab apply -f 04-create-booksapp-ingress.yaml
curl -s -H "Host: booksapp.linkerd.local" http://$INGRESS_HOST | grep -i /title
cd ~/linkerd/scripts
kubectl -n emojivoto scale deploy voting --replicas=2
kubectl -n emojivoto scale deploy web --replicas=2
linkerd -n emojivoto stat deployments
linkerd -n emojivoto stat pods
Now go to a browser locally or in the VM and run http://dashboard.linkerd.local
linkerd top deployment/traffic --namespace linkerd-lab \
--to deployment/webapp --to-namespace linkerd-lab --path /books --hide-sources
kubectl -n linkerd-lab get crd | grep -i linkerd
kubectl -n linkerd-lab get svc
linkerd -n linkerd-lab routes services
linkerd profile --template webapp -n linkerd-lab > webapp.yaml
cat webapp.yaml
cat 05-create-service-profile-web.yaml
kubectl -n linkerd-lab apply -f 05-create-service-profile-web.yaml
linkerd -n linkerd-lab routes services/webapp
linkerd -n linkerd-lab profile --open-api webapp.swagger webapp
linkerd -n linkerd-lab profile --open-api authors.swagger authors
linkerd -n linkerd-lab profile --open-api books.swagger books
linkerd -n linkerd-lab profile --open-api webapp.swagger webapp | kubectl -n linkerd-lab apply -f -
linkerd -n linkerd-lab profile --open-api books.swagger books| kubectl -n linkerd-lab apply -f -
linkerd -n linkerd-lab profile --open-api authors.swagger authors | kubectl -n linkerd-lab apply -f -
kubectl -n linkerd-lab get serviceprofile
linkerd -n linkerd-lab routes deploy/webapp
linkerd -n linkerd-lab routes deploy/authors
linkerd -n linkerd-lab routes deploy/webapp --to svc/authors
linkerd -n linkerd-lab routes deploy/webapp --to svc/books
linkerd -n linkerd-lab routes deploy/books --to svc/authors
kubectl -n linkerd-lab patch sp authors.linkerd-lab.svc.cluster.local --type json --patch='[{"op": "add","path": "/spec/routes/4/isRetryable","value": true}]'
linkerd -n linkerd-lab routes deploy/books --to svc/authors
the failing request is showing a 100% success rate but notice the latency has increased due to the retry
cat << EOT | tee
spec:
retryBudget:
retryRatio: 0.2
minRetriesPerSecond: 10
ttl: 10s
EOT
Above shows the maximum time to live is 10 seconds and then the retry ratio is 20% of the total requests
kubectl -n linkerd-lab patch sp authors.linkerd-lab.svc.cluster.local \
--type json --patch='[{"op": "add","path": "/spec/routes/4/timeout","value": 25ms}]'
kubectl -n linkerd-lab get sp authors.linkerd-lab.svc.cluster.local -o yaml
linkerd -n linkerd-lab routes deploy/books --to svc/authors
linkerd tap deployment/web --namespace emojivoto \
--to deployment/voting --to-namespace emojivoto \
--path /emojivoto.v1.VotingService/VoteDoughnut
cd ~/linkerd/scripts
linkerd tap deploy -n linkerd-lab
kubectl -n linkerd -c identity -l linkerd.io/control-plane-component=identity logs
helm repo add smallstep https://smallstep.github.io/helm-charts/
helm repo list
helm repo update
helm install --name step --namespace step smallstep/step-certificates \
--set fullnameOverride="step" --set ca.db.enabled=false
kubectl -n step get pods
kubectl -n step exec -t step-0 -- step certificate create --profile root-ca "My Root CA" root-ca.crt root-ca.key --no-password --insecure --force
kubectl -n step exec -t step-0 -- step certificate create identity.linkerd.cluster.local identity.crt identity.key --profile intermediate-ca --ca ./root-ca.crt --ca-key ./root-ca.key --no-password --insecure --force
kubectl -n step exec -t step-0 -- step certificate inspect identity.crt --short
Extract certificates from the pod as we did not use a persistent volume while creating the step helm chart
kubectl -n step cp step-0:root-ca.crt /tmp/root-ca.crt
kubectl -n step cp step-0:identity.crt /tmp/identity.crt
kubectl -n step cp step-0:identity.key /tmp/identity.key
linkerd install --ignore-cluster | kubectl delete -f -
linkerd install \
--identity-trust-anchors-file /tmp/root-ca.crt \
--identity-issuer-key-file /tmp/identity.key \
--identity-issuer-certificate-file /tmp/identity.crt \
--ignore-cluster | kubectl apply -f -
linkerd check
cd ~/linkerd/scripts
kubectl -n linkerd apply -f 01-create-linkerd-ingress.yaml
linkerd tap deploy -n linkerd
kubectl -n linkerd -c identity -l linkerd.io/control-plane-component=identity logs
kubectl -n linkerd get secret linkerd-identity-issuer -o jsonpath='{.data.crt\.pem}' | base64 -d
kubectl -n linkerd get secret linkerd-identity-issuer -o jsonpath='{.data.key\.pem}' | base64 -d
kubectl -n step exec -t step-0 -- step certificate create identity.linkerd.cluster.local identity.crt identity.key --profile intermediate-ca --ca ./root-ca.crt --ca-key ./root-ca.key --no-password --insecure --force
kubectl -n step cp step-0:identity.crt /tmp/identity.crt
kubectl -n step cp step-0:identity.key /tmp/identity.key
kubectl -n linkerd delete secret linkerd-identity-issuer
kubectl -n linkerd create secret generic linkerd-identity-issuer \
--from-file=crt.pem=/tmp/identity.crt \
--from-file=key.pem=/tmp/identity.key
kubectl -n linkerd rollout restart deploy linkerd-identity
linkerd check
kubectl -n linkerd -c identity -l linkerd.io/control-plane-component=identity logs
kubectl -n step exec -t step-0 -- \
step certificate create booksapp.linkerd.local booksapp.crt booksapp.key \
--profile leaf --ca identity.crt --ca-key identity.key \
--no-password --insecure --force --kty=RSA --not-after=2160h
kubectl -n step cp step-0:booksapp.crt booksapp.crt
kubectl -n step cp step-0:booksapp.key booksapp.key
Pass the certificate chain along with the leaf certificate private key to the Nginx Ingress Controller
cat booksapp.crt /tmp/identity.crt > ca-bundle.crt
kubectl -n linkerd-lab create secret tls booksapp-keys --key booksapp.key --cert ca-bundle.crt
cat 07-create-booksapp-ingress-tls.yaml
kubectl -n linkerd-lab apply -f 07-create-booksapp-ingress-tls.yaml
NGINX_POD=$(kubectl -n kube-system get pod -l app=nginx-controller -o jsonpath='{.items..metadata.name}') ; echo $NGINX_POD
kubectl -n kube-system exec -it $NGINX_POD -- ls -l /etc/nginx/conf.d
kubectl -n kube-system exec -it $NGINX_POD -- cat /etc/nginx/conf.d/linkerd-lab-booksapp.conf
kubectl -n kube-system exec -it $NGINX_POD -- ls -l /etc/nginx/secrets
kubectl -n kube-system exec -it $NGINX_POD -- cat /etc/nginx/secrets/default
Check https://booksinfo.linkerd.local from web browser
export INGRESS_PORT=$(kubectl -n kube-system get service nginx-controller -o jsonpath='{.spec.ports[?(@.name=="https")].port}') ; echo $INGRESS_PORT
export INGRESS_HOST=$(kubectl -n kube-system get service nginx-controller -o jsonpath='{.status.loadBalancer.ingress..ip}') ; echo $INGRESS_HOST
rm -fr ~/.pki
curl -Ls -HHost:booksapp.linkerd.local \
--resolve booksapp.linkerd.local:$INGRESS_HOST:$INGRESS_PORT \
--cacert ca-bundle.crt https://booksapp.linkerd.local
cd ~/linkerd/scripts
linkerd top deployment --namespace emojivoto --hide-sources
cat 06-create-prometheus-ingress.yaml
kubectl -n linkerd apply -f 06-create-prometheus-ingress.yaml
export INGRESS_HOST=$(kubectl -n kube-system get service nginx-controller -o jsonpath='{.status.loadBalancer.ingress..ip}') ; echo $INGRESS_HOST
sudo sed -i '/prometheus.linkerd.local/d' /etc/hosts
echo "$INGRESS_HOST prometheus.linkerd.local" | sudo tee -a /etc/hosts
Run http://prometheus.linkerd.local from your browser
curl -Ls -H "Host: prometheus.linkerd.local" http://prometheus.linkerd.local | grep title
curl -Ls -G --data-urlencode 'match[]={job="linkerd-proxy"}' --data-urlencode 'match[]={job="linkerd-controller"}' http://prometheus.linkerd.local/federate | tail -100
export AUTHORS_PODIP=$(kubectl -n linkerd-lab get pods -l app=authors -o jsonpath='{.items[0].status.podIP}') ; echo $AUTHORS_PODIP
curl -s http://$AUTHORS_PODIP:4191/metrics | tail -100