Linkerd 2.8 - 實現超級簡單又安全的多叢集(multicluster) Kubernetes 架構

研究動機:如何在 Pod 中呼叫別的 kubernetes cluster service

嘗試過目前市面上現有的三套開源軟體(Linkerd, Consul, Istio),決定推坑大家 Linkerd 在今年六月釋出的 Linkerd 2.8,實現了 multi-cluster Kubernetes 架構,我們來看看主打超輕量化 service mesh 的 Linkerd 會怎麼表現在 multi-cluster。

目前筆者在同一個 GCP 呼叫不同 cluster 的 service 都需要使用 internal load balancer,除了會增加許多額外的花費,internal load balancer 預設是能夠讓同一個 VPC 存取,代表任何 VM 都能使用這個 service,這當然不是我們所預期的行為。最重要的是很難維護,所以開始尋找有沒有 solution 可以解決這個問題。

  • 可以從 Cluster-A 存取 Cluster-B 的 service
  • Cluster-B 可以決定要 expose 哪些 service 給特定的 cluster
  • connections 低延遲、穩定
  • configuration 越少越好
  • discover service fast
  • private connection with security

Install Linkerd

這邊不會提到 cli 和 cluster setup,只會帶到 linkerd,更詳細的 script 會放在 https://github.com/RammusXu/toolkit/tree/master/k8s/linkerd-multi-cluster

其實只要三個指令就能讓兩個 cluster 相互溝通,可以看到 linkerd 在 cli 的設計,非常簡化、直覺。

  • linkerd install
  • linkerd multicluster install
  • linkerd --context=east multicluster link --cluster-name east | kubectl --context=west apply -f -
## Create CA certificate
step certificate create identity.linkerd.cluster.local root.crt root.key \
--profile root-ca --no-password --insecure
step certificate create identity.linkerd.cluster.local issuer.crt issuer.key \
--profile intermediate-ca --not-after 87600h --no-password --insecure \
--ca root.crt --ca-key root.key

## Install Linkerd in every cluster
for ctx in $(kubectx); do
kubectx ${ctx}
echo "Checking cluster: ${ctx} .........\n"
linkerd install \
--identity-trust-anchors-file root.crt \
--identity-issuer-certificate-file issuer.crt \
--identity-issuer-key-file issuer.key \
| kubectl apply -f -
linkerd check || break
echo "-------------\n"
done

## Install Linkerd multicluster component
for ctx in $(kubectx); do
echo "Installing on cluster: ${ctx} ........."
linkerd --context=${ctx} multicluster install | \
kubectl --context=${ctx} apply -f - || break
echo "-------------\n"
done

## Check multicluster gateways
for ctx in $(kubectx); do
echo "Checking gateway on cluster: ${ctx} ........."
kubectl --context=${ctx} -n linkerd-multicluster \
rollout status deploy/linkerd-gateway || break
linkerd --context=${ctx} check --multicluster || break
linkerd --context=${ctx} multicluster gateways
echo "-------------\n"
done

## Link cluster:east to cluster:west
linkerd --context=east multicluster link --cluster-name east |
kubectl --context=west apply -f -

Showtime

Dashboard: 可以看到目前所有的 namespace 有多少 meshed(injected), SR, RPS, Latency,還能直接開啟 grafana 看更詳細的資訊。

點進 Namespace 可以看到 deployment 之間的關聯。

Deployment 後能看到所有進出的流量。

點擊右邊的 Tap,可以看到目前所有的 request,非常強大的 debug 工具。

grafana 即時顯示 SR, RPS, Latency

分流的 yaml 也相當直覺

apiVersion: split.smi-spec.io/v1alpha1
kind: TrafficSplit
metadata:
name: podinfo
namespace: test
spec:
service: podinfo
backends:
- service: podinfo
weight: 50
- service: podinfo-east
weight: 50

Benchmark

這邊在 Cluster control 對 Cluster remote 的 podinfo 壓力測試

  • 這邊比較的基準是直接用 type: LoadBalancer 產生一個 GKE L4 Load Balancer
  • linkerd 會在 Cluster control 產生一個 mirrored service podinfo-remote,透過兩邊的 linkerd-gateway 溝通

環境:

  • Cluster control: n2-highcpu-32 regional GKE in Taiwan
  • Cluster remote: n2-highcpu-32 regional GKE in Oregon
    wrk -t10 -c500 -d30 --latency http://podinfo-remote:9898
    wrk -t10 -c500 -d30 --latency http://34.83.93.113:9898

可以看到在 100 connections 也只增加了 7% 的延遲,已經能處理大部分的 micro service 使用場景。
在 500 connections 增加了 50%,不過對於 cross region HA 的話,還算可以接受的範圍。

更多 linkerd vs istio 在 single cluster 的比較: https://linkerd.io/2019/05/18/linkerd-benchmarks

Other multi cluster solutions

Consul

  • Pod injection 大概會長這樣,比起 linkerd 多了 serviceAccount 的部分,任何需要到 remote 的 service 都要加入。
apiVersion: v1
kind: ServiceAccount
metadata:
name: static-client
---
apiVersion: v1
kind: Pod
metadata:
name: static-client
annotations:
'consul.hashicorp.com/connect-inject': 'true'
'consul.hashicorp.com/connect-service-upstreams': 'static-server:1234:dc2'
spec:
containers:
- name: static-client
image: tutum/curl:latest
command: ['/bin/sh', '-c', '--']
args: ['while true; do sleep 30; done;']
serviceAccountName: static-client
  • 不知道為什麼在 service discovery 的部分有時候會需要 2-3 分鐘。
  • Latency 多了 50% (Consul Gateway 比 L4 Load Balancer)。

Istio

  • 跟著 tutorial 做完,也無法連到另外一個 cluster 的服務
  • 用 GKE addon 或是最新版的 istioctl 都無法部署成功

目前的問題

  • 只能接受 HTTP trafic

感想

不知道是不是先有了部署 Istio 和 Consul 的經驗,部署 linkerd 大概只花了 20-30 分鐘,也可能因為是剛出的文章,所以跑完 tutorial 後能夠正確地顯示結果。相比 Consul 的 tutorial 漏了一堆 configuration,還需要查其他文件才能正確部署成功(大概花了 3-4 小時吧)。Istio 則是完全沒有任何線索繼續。

相較另外兩套 service mesh,Linkerd 相對的平易近人許多,尤其是 pod injection 和 service discovery 的部分,讓我覺得可控性很高,但又不需要太多 config。

Reference