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 中文手冊持續修正更新中:
本指南將引導您安裝和配置 Linkerd
,以便兩個叢集可以與託管在兩個叢集上的服務通訊。
在本指南結束時,您將瞭解如何在不同叢集上的服務之間分配流量。
您將:
- 安裝 Linkerd,在具有共享信任錨(
shared trust anchor
)的兩個叢集上。 - 準備叢集。
- 連結叢集。
- 安裝 demo。
- 暴露 demo services, 以控制可見性。
- 驗證叢集的安全性。
- 拆分流量,將從源叢集 (
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 需要在所有相互通訊的叢集中的安裝之間存在共享
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 利用了 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-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
)並準備啟動映象服務。
我們現在想要將叢集連結在一起!
連結叢集
為了讓 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
標誌。
安裝測試服務
是時候測試這一切了!
第一步是新增一些我們可以映象的服務。
要將這些新增到兩個叢集,您可以執行:
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
通過 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 跨叢集擴充套件其自動 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"
流量拆分
讓服務自動出現在叢集中並能夠明確地處理它們是非常有用的,
但是這僅涵蓋操作多個叢集的一個用例。
多叢集的另一個場景是故障轉移。
在故障轉移場景中,您沒有時間更新配置。
相反,您需要能夠不理會應用程式,而只需更改路由即可。
如果這聽起來很像我們進行 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
的問候訊息。
您還可以通過指標觀察發生的情況。要檢視事物的源頭(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。
清理
要清理多叢集控制平面,您可以執行:
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
公眾號:黑客下午茶
加我微信(互相學習交流),關注公眾號(獲取更多學習資料~)