天天看點

Linkerd 2.10(Step by Step)—多叢集通信

Linkerd 2.10(Step by Step)—多叢集通信

Linkerd 2.10 系列

  • 快速上手 Linkerd v2.10 Service Mesh(服務網格)
  • 騰訊雲 K8S 叢集實戰 Service Mesh—Linkerd2 & Traefik2 部署 emojivoto 應用
  • 詳細了解 Linkerd 2.10 基礎功能,一起步入 Service Mesh 微服務架構時代
  • Linkerd 2.10—将您的服務添加到 Linkerd
  • Linkerd 2.10—自動化的金絲雀釋出
  • Linkerd 2.10—自動輪換控制平面 TLS 與 Webhook TLS 憑證
  • Linkerd 2.10—如何配置外部 Prometheus 執行個體
  • Linkerd 2.10—配置代理并發
  • Linkerd 2.10—配置重試
  • Linkerd 2.10—配置逾時
  • Linkerd 2.10—控制平面調試端點
  • Linkerd 2.10—使用 Kustomize 自定義 Linkerd 的配置
  • Linkerd 2.10—使用 Linkerd 進行分布式跟蹤
  • Linkerd 2.10—調試 502s
  • Linkerd 2.10—使用每個路由名額調試 HTTP 應用程式
  • Linkerd 2.10—使用請求跟蹤調試 gRPC 應用程式
  • Linkerd 2.10—導出名額
  • Linkerd 2.10—暴露 Dashboard
  • Linkerd 2.10—生成您自己的 mTLS 根證書
  • Linkerd 2.10—擷取每條路由名額
  • Linkerd 2.10—混沌工程之注入故障
  • Linkerd 2.10—優雅的 Pod 關閉
  • Linkerd 2.10—Ingress 流量
  • Linkerd 2.10—安裝多叢集元件
  • Linkerd 2.10—安裝 Linkerd
  • Linkerd 2.10—使用 Helm 安裝 Linkerd
  • Linkerd 2.10—Linkerd 和 Pod 安全政策 (PSP)
  • Linkerd 2.10—手動輪換控制平面 TLS 憑證
  • Linkerd 2.10—修改代理日志級别

Linkerd 2.10 中文手冊持續修正更新中:

  • https://linkerd.hacker-linner.com

本指南将引導您安裝和配置

Linkerd

,以便兩個叢集可以與托管在兩個叢集上的服務通信。

在本指南結束時,您将了解如何在不同叢集上的服務之間配置設定流量。

您将:

  1. 安裝 Linkerd,在具有共享信任錨(

    shared trust anchor

    )的兩個叢集上。
  2. 準備叢集。
  3. 連結叢集。
  4. 安裝 demo。
  5. 暴露 demo services, 以控制可見性。
  6. 驗證叢集的安全性。
  7. 拆分流量,将從源叢集 (

    west

    ) 上的 pod 的流量拆分到目标叢集 (

    east

    )。

前提條件

  • 兩個叢集。我們将在本指南中将它們稱為

    east

    west

    在您浏覽本指南時,請跟随

    部落格文章!

    為開發執行此操作的最簡單方法是在您的筆記本電腦上本地運作一個

    kind

    或 k3d 叢集,

    并在雲提供商(例如 AKS)

    上遠端運作一個叢集。

  • 這些叢集中的每一個都應配置為

    kubectl

    contexts。

    我們建議您使用

    east

    west

    的名稱,

    以便您可以按照本指南進行操作。

    使用

    kubectl

    rename contexts

    很容易,是以不要覺得你需要永遠保持這種命名方式。

  • 兩個叢集上的提升權限。我們将建立服務帳戶并授予擴充權限,

    是以您需要能夠在測試叢集上執行此操作。

  • 應安裝 Linkerd 的

    viz

    擴充,以便運作

    stat

    指令、

    檢視 Grafana 或 Linkerd 儀表闆并

    運作

    linkerd multicluster gateways

    指令。
  • 支援

    east

    叢集中的

    LoadBalancer

    類型的服務。

    檢視叢集提供商的文檔或檢視

    inlets。

    這是

    west

    叢集将用于通過網關與

    east

    通信的内容。

安裝 Linkerd

Linkerd 2.10(Step by Step)—多叢集通信

Linkerd 需要在所有互相通信的叢集中的安裝之間存在共享

trust anchor。

這用于加密叢集之間的流量并授權到達網關的請求,以便您的叢集不對公共網際網路開放。

我們需要生成憑據并将它們用作

install

指令的配置,而不是讓

linkerd

生成所有内容。

我們喜歡使用 step CLI 來生成這些證書。

如果您更喜歡

openssl

,請随意使用它!

要使用

step

生成信任錨,您可以運作:

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

該證書将構成所有叢集之間的共同信任基礎。

每個代理都将獲得此證書的副本,并使用它來驗證從對等方收到的證書,

作為 mTLS 握手的一部分。有了共同的信任基礎,

我們現在需要生成一個證書,可以在每個叢集中使用該證書向代理頒發證書。

我們生成的信任錨是一個自簽名證書,可用于建立新證書(證書頒發機構)。

要使用信任錨生成

issuer credentials

,請運作:

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

叢集中的

identity

服務将使用您在此處生成的證書(certificate)和

密鑰(key)來生成每個單獨代理使用的證書。

雖然我們将在本指南的每個叢集上使用相同的頒發者憑據,

但最好為每個叢集使用不同的頒發者憑據。

有了有效的信任錨(trust anchor)和發行人憑據(issuer credentials),

我們現在就可以在您的

west

east

叢集上安裝 Linkerd。

linkerd install \
  --identity-trust-anchors-file root.crt \
  --identity-issuer-certificate-file issuer.crt \
  --identity-issuer-key-file issuer.key \
  | tee \
    >(kubectl --context=west apply -f -) \
    >(kubectl --context=east apply -f -)
           

install

的輸出将應用于每個叢集并出現!

您可以使用

check

來驗證一切是否成功。

for ctx in west east; do
  echo "Checking cluster: ${ctx} .........\n"
  linkerd --context=${ctx} check || break
  echo "-------------\n"
done
           

準備叢集

Linkerd 2.10(Step by Step)—多叢集通信

為了在叢集之間路由流量,Linkerd 利用了 Kubernetes services,

是以您的應用程式代碼無需更改,也無需學習任何新内容。

這需要一個網關元件,将傳入請求路由到正确的内部服務。

網關将通過

LoadBalancer

類型的

Service

暴露給公共網際網路。

僅允許通過 Linkerd 的 mTLS(具有共享信任錨)驗證的請求通過此網關。

要在

west

east

上安裝多叢集元件,您可以運作:

for ctx in west east; do
  echo "Installing on cluster: ${ctx} ........."
  linkerd --context=${ctx} multicluster install | \
    kubectl --context=${ctx} apply -f - || break
  echo "-------------\n"
done
           
Linkerd 2.10(Step by Step)—多叢集通信

網關安裝在

linkerd-multicluster

命名空間中,

是一個簡單的

NGINX proxy,

它已經注入了 Linkerd 代理。 在入站端,Linkerd 負責驗證連接配接是否

使用了作為信任錨一部分的 TLS 證書。 NGINX 接收請求并将其轉發到 Linkerd 代理的出站端。

此時,Linkerd 代理像資料平面中的任何其他代理一樣運作,

并将請求轉發到正确的服務。通過運作以下指令確定網關成功啟動:

for ctx in west east; do
  echo "Checking gateway on cluster: ${ctx} ........."
  kubectl --context=${ctx} -n linkerd-multicluster \
    rollout status deploy/linkerd-gateway || break
  echo "-------------\n"
done
           

通過運作以下指令仔細檢查負載均衡器是否能夠配置設定公共 IP 位址:

for ctx in west east; do
  printf "Checking cluster: ${ctx} ........."
  while [ "$(kubectl --context=${ctx} -n linkerd-multicluster get service \
    -o 'custom-columns=:.status.loadBalancer.ingress[0].ip' \
    --no-headers)" = "<none>" ]; do
      printf '.'
      sleep 1
  done
  printf "\n"
done
           

每個叢集現在都在運作多叢集控制平面(

multicluster control plane

)并準備啟動鏡像服務。

我們現在想要将叢集連結在一起!

連結叢集

Linkerd 2.10(Step by Step)—多叢集通信

為了讓

west

east

鏡像服務,

west

叢集需要有憑據,

以便它可以監視要暴露的

east

服務。

畢竟,您不希望任何人能夠内省叢集上運作的内容!

憑據包括用于驗證服務鏡像的服務帳戶以及

允許監視服務的

ClusterRole

ClusterRoleBinding

總的來說,服務鏡像元件使用這些憑證來觀察

east

或目标叢集上的服務,

并從自身(

west

)添加/删除它們。

作為

linkerd multicluster install

的一部分添加了一個預設設定,

但是如果您想為每個叢集擁有單獨的憑據,

您可以運作

linkerd multicluster allow

下一步是将

west

連結到

east

這将建立一個 credentials secret、Link resource 和 service-mirror controller。

憑證密鑰包含一個 kubeconfig,可用于通路目标(

east

)叢集的 Kubernetes API。

Link resource 是配置服務鏡像的自定義資源,

包含網關位址(gateway address)、網關辨別(gateway identity)

和在确定要鏡像哪些服務時使用的标簽選擇器等内容。

服務鏡像控制器(service-mirror controller)使用 Link 和 secret 在

目标叢集上查找與給定标簽選擇器比對的服務,

并将它們複制到源(本地)叢集中。

要将

west

叢集連結到

east

叢集,請運作:

linkerd --context=east multicluster link --cluster-name east |
  kubectl --context=west apply -f -
           

Linkerd 将檢視您目前的

east

context,

提取包含伺服器位置(server location)以及 CA 包的

cluster

配置。

然後它将擷取

ServiceAccount

token 并

将這些配置合并到一個 kubeconfig 的 secret 中。

再次運作

check

将確定服務鏡像(service mirror)已經

發現了這個 secret 并且可以到達

east

linkerd --context=west multicluster check
           

此外,

east

網關現在應該顯示在清單中:

linkerd --context=west multicluster gateways
           

link

假設兩個叢集将使用與您在本地使用的配置相同的配置互相連接配接。

如果不是這種情況,您将需要為

link

使用

--api-server-address

标志。

安裝測試服務

Linkerd 2.10(Step by Step)—多叢集通信

是時候測試這一切了!

第一步是添加一些我們可以鏡像的服務。

要将這些添加到兩個叢集,您可以運作:

for ctx in west east; do
  echo "Adding test services on cluster: ${ctx} ........."
  kubectl --context=${ctx} apply \
    -k "github.com/linkerd/website/multicluster/${ctx}/"
  kubectl --context=${ctx} -n test \
    rollout status deploy/podinfo || break
  echo "-------------\n"
done
           

您現在将擁有一個

test

命名空間,在每個叢集中運作兩個部署 - frontend 和 podinfo。

podinfo

在每個叢集中的配置略有不同,具有不同的名稱和顔色,以便我們可以知道請求的去向。

要立即從

west

叢集中檢視它的樣子,您可以運作:

kubectl --context=west -n test port-forward svc/frontend 8080
           
Linkerd 2.10(Step by Step)—多叢集通信

通過 http://localhost:8080 提供的 podinfo 登入頁面,

您現在可以看到它在

west

叢集中的外觀。

或者,運作

curl http://localhost:8080

将傳回一個類似于以下内容的 JSON 響應:

{
  "hostname": "podinfo-5c8cf55777-zbfls",
  "version": "4.0.2",
  "revision": "b4138fdb4dce7b34b6fc46069f70bb295aa8963c",
  "color": "#6c757d",
  "logo": "https://raw.githubusercontent.com/stefanprodan/podinfo/gh-pages/cuddle_clap.gif",
  "message": "greetings from west",
  "goos": "linux",
  "goarch": "amd64",
  "runtime": "go1.14.3",
  "num_goroutine": "8",
  "num_cpu": "4"
}
           

請注意,

message

引用了

west

叢集名稱。

暴露 services

為確定敏感服務(

sensitive services

)不被鏡像并且

叢集性能受到服務的建立或删除的影響,我們要求顯式暴露服務。

出于本指南的目的,我們将把

podinfo

服務從

east

叢集導出到

west

叢集。

為此,我們必須首先導出

east

叢集中的

podinfo

服務。

你可以通過添加

mirror.linkerd.io/exported

标簽來做到這一點:

kubectl --context=east label svc -n test podinfo mirror.linkerd.io/exported=true
           

您可以通過在

linkerd multicluster link

指令上使用

--selector

标志或

通過編輯由

linkerd multicluster link

指令建立

的 Link resource 來配置不同的标簽選擇器。

檢視服務鏡像控制器(service mirror controller)剛剛建立的服務!

kubectl --context=west -n test get svc podinfo-east
           

architecture

中,您會記得服務鏡像(service mirror)元件所做的不僅僅是移動服務。

它還管理鏡像服務上的端點。

要驗證設定是否正确,您可以檢查

west

的端點并驗證它們

是否與

east

網關的公共 IP 位址比對。

kubectl --context=west -n test get endpoints podinfo-east \
  -o 'custom-columns=ENDPOINT_IP:.subsets[*].addresses[*].ip'
kubectl --context=east -n linkerd-multicluster get svc linkerd-gateway \
  -o "custom-columns=GATEWAY_IP:.status.loadBalancer.ingress[*].ip"
           

此時,我們可以從

west

叢集中通路

east

中的

podinfo

服務。

這需要對用戶端進行網格化,是以讓我們從前端 pod 中運作

curl

kubectl --context=west -n test exec -c nginx -it \
  $(kubectl --context=west -n test get po -l app=frontend \
    --no-headers -o custom-columns=:.metadata.name) \
  -- /bin/sh -c "apk add curl && curl http://podinfo-east:9898"
           

你會看到

greeting from east

的消息!

來自在

west

運作的

frontend

pod 的請求被透明地轉發到

east

假設您仍然在上一步進行端口轉發,

您也可以從浏覽器通路 http://localhost:8080/east。

重新整理幾次,您也可以從

linkerd viz stat

中擷取名額。

linkerd --context=west -n test viz stat --from deploy/frontend svc
           

我們還提供了一個 grafana 儀表闆來了解這裡發生的事情。

您可以通過運作

linkerd --context=west viz dashboard

并轉到

http://localhost:50750/grafana/

來通路它。

Linkerd 2.10(Step by Step)—多叢集通信

安全

預設情況下,請求将通過公共網際網路。

Linkerd 跨叢集擴充其自動

mTLS

以確定通過公共網際網路進行的通信是加密的。

但是,要快速檢查,您可以運作:

linkerd --context=west -n test viz tap deploy/frontend | \
  grep "$(kubectl --context=east -n linkerd-multicluster get svc linkerd-gateway \
    -o "custom-columns=GATEWAY_IP:.status.loadBalancer.ingress[*].ip")"
           

tls=true

告訴你請求正在被加密!

由于

linkerd edge

适用于具體資源,并且不能同時看到兩個叢集,

是以目前無法顯示

east

west

中 pod 之間的邊緣。

這就是我們在這裡使用

tap

來驗證 mTLS 的原因。

除了確定您的所有請求都被加密之外,阻止任意請求進入您的叢集也很重要。

我們通過驗證請求來自網格中的用戶端來做到這一點。

為了進行這種驗證,我們依賴叢集之間的共享信任錨。

要檢視當用戶端在網格之外時會發生什麼,您可以運作:

kubectl --context=west -n test run -it --rm --image=alpine:3 test -- \
  /bin/sh -c "apk add curl && curl -vv http://podinfo-east:9898"
           

流量拆分

Linkerd 2.10(Step by Step)—多叢集通信

讓服務自動出現在叢集中并能夠明确地處理它們是非常有用的,

但是這僅涵蓋操作多個叢集的一個用例。

多叢集的另一個場景是故障轉移。

在故障轉移場景中,您沒有時間更新配置。

相反,您需要能夠不理會應用程式,而隻需更改路由即可。

如果這聽起來很像我們進行 canary 部署的方式,那麼您是對的!

TrafficSplit

允許我們定義多個服務之間的權重并在它們之間拆分流量。

在故障轉移場景中,您希望緩慢執行此操作,以確定不會因為

增加的延遲而使其他叢集過載或跳閘任何 SLO。

為了讓這一切都适用于我們的場景,

讓我們在

west

east

中的

podinfo

服務之間進行拆分。

要配置它,您将運作:

cat <<EOF | kubectl --context=west apply -f -
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
EOF
           

podinfo

的任何請求現在将有 50% 的時間轉發到

podinfo-east

叢集,

另外 50% 的時間會轉發到本地

podinfo

服務。

發送到

podinfo-east

的請求最終會出現在

east

叢集中,

是以我們現在已經有效地使從

west

east

的 50% 以上的流量失敗了。

如果您仍在運作

port-forward

則可以将浏覽器發送到 http://localhost:8080。

重新整理頁面應該顯示兩個叢集。

或者,對于指令行方法,

curl localhost:8080

給你一條來自

west

east

的問候消息。

Linkerd 2.10(Step by Step)—多叢集通信

您還可以通過名額觀察發生的情況。要檢視事物的源頭(

west

),您可以運作:

linkerd --context=west -n test viz stat trafficsplit
           

也可以通過運作從目标(

east

)側觀察:

linkerd --context=east -n test viz stat \
  --from deploy/linkerd-gateway \
  --from-namespace linkerd-multicluster \
  deploy/podinfo
           

甚至還有一個儀表闆! 運作

linkerd viz dashboard

并将浏覽器發送到

localhost:50750。

Linkerd 2.10(Step by Step)—多叢集通信

清理

要清理多叢集控制平面,您可以運作:

for ctx in west east; do
  linkerd --context=${ctx} multicluster uninstall | kubectl --context=${ctx} delete -f -
done
           

如果您還想删除 Linkerd 安裝,請運作:

for ctx in west east; do
  linkerd --context=${ctx} uninstall | kubectl --context=${ctx} delete -f -
done
           
我是為少
微信:uuhells123
公衆号:黑客下午茶
加我微信(互相學習交流),關注公衆号(擷取更多學習資料~)