![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISM9AnYldnJwAzN9c3Pn5GcuQ0MlMWbidXND1EeFRkTyEERPRTTU1EdnR0T3VFVNVTU61UeBpWTyEEVNlXQq1EdNRlTwkleNBDOp50dFpWT3lkeMpXVE5kMNRkT2NmMiNnSywEd5ITW110MaZHetlVdO1GT3lERNl3YXJGc5kHT20ESjBjUIF2Lc12bj5SYphXa5VWen5WY35iclN3Ztl2Lc9CX6MHc0RHaiojIsJye.png)
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
,以便兩個叢集可以與托管在兩個叢集上的服務通信。
在本指南結束時,您将了解如何在不同叢集上的服務之間配置設定流量。
您将:
- 安裝 Linkerd,在具有共享信任錨(
)的兩個叢集上。shared trust anchor
- 準備叢集。
- 連結叢集。
- 安裝 demo。
- 暴露 demo services, 以控制可見性。
- 驗證叢集的安全性。
- 拆分流量,将從源叢集 (
) 上的 pod 的流量拆分到目标叢集 (west
)。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
公衆号:黑客下午茶
加我微信(互相學習交流),關注公衆号(擷取更多學習資料~)