練習 - 使用 Kube 實作基礎結構復原
在上一個單元中,您已使用 .NET 原生復原延伸模組新增處理失敗程式碼來實作復原。 不過,這項變更僅適用於您變更的服務。 如果是具有許多服務的大型應用程式,要進行更新會相當困難。
此單元不會使用程式碼型復原,而是使用稱為基礎結構型復原的方法,可跨越整個應用程式。 您將會:
- 將不具有任何復原功能的應用程式重新部署至 Kube。
- 在您的 Kube 叢集中部署 Linkerd。
- 將應用程式設定為使用 Linkerd 來復原。
- 探索使用 Linkerd 時的應用程式行為。
重新部署應用程式
在套用 Linkerd 之前,請先將應用程式還原成尚未新增程式碼型復原功能的狀態。 若要還原,請遵循下列步驟:
在底部面板中,選取 [終端機] 索引標籤,然後執行下列 git 命令來復原您的變更:
cd Store git checkout Program.cs git checkout Store.csproj cd .. dotnet publish /p:PublishProfile=DefaultContainer
安裝 Kube
在您的 codespace 中,安裝 Kubernetes 和 k3d。 k3d 是一種工具,可在本機電腦上的虛擬機器 (VM) 內執行單一節點 Kubernetes 叢集。 它適用於在本機測試 Kube 部署,並可在 codespace 內順利執行。
執行下列命令以安裝 Kube 和 MiniKube:
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubectl
curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash
k3d cluster create devcluster --config k3d.yml
將 eShop 服務部署至 Docker Hub
您所建置之服務的本機映像需要裝載在容器登錄中,才能部署至 Kubernetes。 在本單元中,您將使用 Docker Hub 作為容器登錄。
執行下列命令,將您的映像推送至 Docker Hub:
sudo docker login
sudo docker tag products [your username]/productservice
sudo docker tag store [your username]/storeimage
sudo docker push [your username]/productservice
sudo docker push [your username]/storeimage
將您的 docker-compose 檔案轉換為 Kube 資訊清單
目前,您定義了應用程式在 Docker 中執行的方式。 Kube 會使用不同的格式來定義應用程式執行的方式。 您可以使用名為 Kompose 的工具,將 docker-compose 檔案轉換成 Kubernetes 資訊清單。
您需要編輯這些檔案才能使用您已推送至 Docker Hub 的映像。
在 codespace 中,開啟 backend-deploy.yml 檔案。
變更這一行:
containers: - image: [YOUR DOCKER USER NAME]/productservice:latest
以您實際的 Docker 使用者名稱取代預留位置 [YOUR DOCKER USERNAME]。
針對 frontend-deploy.yml 檔案重複這些步驟。
變更這一行:
containers: - name: storefrontend image: [YOUR DOCKER USER NAME]/storeimage:latest
以您實際的 Docker 使用者名稱取代預留位置 [YOUR DOCKER USERNAME]。
將 eShop 應用程式部署至 Kube:
kubectl apply -f backend-deploy.yml,frontend-deploy.yml
您應該會看到類似下列訊息的輸出:
deployment.apps/productsbackend created service/productsbackend created deployment.apps/storefrontend created service/storefrontend created
檢查所有服務是否正在執行:
kubectl get pods
您應該會看到類似下列訊息的輸出:
NAME READY STATUS RESTARTS AGE backend-66f5657758-5gnkw 1/1 Running 0 20s frontend-5c9d8dbf5f-tp456 1/1 Running 0 20s
切換至 [連接埠] 索引卷標,以檢視在 Kube 上執行的 eShop,選取 [前端 (32000)] 連接埠旁的地球圖示。
安裝 linkerd
開發容器需要安裝 Linkerd CLI。 執行下列命令以確認符合 Linkerd 先決條件:
curl -sL run.linkerd.io/install | sh
export PATH=$PATH:/home/vscode/.linkerd2/bin
linkerd check --pre
隨即出現下列輸出的變化:
kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API
kubernetes-version
------------------
√ is running the minimum Kubernetes API version
√ is running the minimum kubectl version
pre-kubernetes-setup
--------------------
√ control plane namespace does not already exist
√ can create non-namespaced resources
√ can create ServiceAccounts
√ can create Services
√ can create Deployments
√ can create CronJobs
√ can create ConfigMaps
√ can create Secrets
√ can read Secrets
√ can read extension-apiserver-authentication configmap
√ no clock skew detected
pre-kubernetes-capability
-------------------------
√ has NET_ADMIN capability
√ has NET_RAW capability
linkerd-version
---------------
√ can determine the latest version
√ cli is up-to-date
Status check results are √
將 Linkerd 部署至 Kube
首先,執行下列命令來安裝自訂資源定義 (CRD):
linkerd install --crds | kubectl apply -f -
然後,執行下列命令:
linkerd install --set proxyInit.runAsRoot=true | kubectl apply -f -
在上述命令中:
linkerd install
會產生一份含有必要控制平面資源的 Kubernetes 資訊清單。- 系統會將產生的資訊清單輸送至
kubectl apply
,由其在 Kube 叢集中安裝那些控制平面資源。
輸出第一行顯示控制項平面已安裝在專屬的 linkerd
命名空間中。 其餘輸出則代表正在建立的物件。
namespace/linkerd created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-identity created
clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-identity created
serviceaccount/linkerd-identity created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-controller created
驗證 Linkerd 部署
執行以下命令:
linkerd check
上述命令會分析 Linkerd CLI 和控制平面的設定。 如果已正確設定 Linkerd,則會顯示下列輸出:
kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API
kubernetes-version
------------------
√ is running the minimum Kubernetes API version
√ is running the minimum kubectl version
linkerd-existence
-----------------
√ 'linkerd-config' config map exists
√ heartbeat ServiceAccount exist
√ control plane replica sets are ready
√ no unschedulable pods
√ controller pod is running
√ can initialize the client
√ can query the control plane API
linkerd-config
--------------
√ control plane Namespace exists
√ control plane ClusterRoles exist
√ control plane ClusterRoleBindings exist
√ control plane ServiceAccounts exist
√ control plane CustomResourceDefinitions exist
√ control plane MutatingWebhookConfigurations exist
√ control plane ValidatingWebhookConfigurations exist
√ control plane PodSecurityPolicies exist
linkerd-identity
----------------
√ certificate config is valid
√ trust anchors are using supported crypto algorithm
√ trust anchors are within their validity period
√ trust anchors are valid for at least 60 days
√ issuer cert is using supported crypto algorithm
√ issuer cert is within its validity period
√ issuer cert is valid for at least 60 days
√ issuer cert is issued by the trust anchor
linkerd-api
-----------
√ control plane pods are ready
√ control plane self-check
√ [kubernetes] control plane can talk to Kubernetes
√ [prometheus] control plane can talk to Prometheus
√ tap api service is running
linkerd-version
---------------
√ can determine the latest version
√ CLI is up to date
control-plane-version
---------------------
√ control plane is up to date
√ control plane and CLI versions match
linkerd-addons
--------------
√ 'linkerd-config-addons' config map exists
linkerd-grafana
---------------
√ grafana add-on service account exists
√ grafana add-on config map exists
√ grafana pod is running
Status check results are √
提示
若要查看已安裝的 Linkerd 元件清單,請執行此命令:kubectl -n linkerd get deploy
將應用程式設定為使用 Linkerd
已部署 Linkerd,但未設定。 應用程式的行為不會變更。
Linkerd 不知道服務內部情況,因此無法判斷是否適合重試失敗的要求。 例如,付款時失敗的 HTTP POST 就不應該重試。 基於此原因,您需要使用服務設定檔。 服務設定檔是自訂的 Kubernetes 資源,可定義服務的路由。 服務設定檔也可啟用每個路由的功能,例如重試和逾時。 Linkerd 只會重試服務設定檔資訊清單中有設定的路由。
為求簡單明瞭,只在彙總工具和優待券服務上執行 Linkerd。 若要實作這兩個服務的 Linkerd,您必須:
- 修改 eShop 部署,讓 Linkerd 在 Pod 中建立其 Proxy 容器。
- 若要設定優待券服務路由上的重試次數,請將服務設定檔物件新增至叢集中。
修改 eShop 部署
服務必須設定為使用 Linkerd Proxy 容器。
將
linkerd.io/inject: enabled
註釋新增至範本中繼資料下的 backend-deploy.yml 檔案。template: metadata: annotations: linkerd.io/inject: enabled labels:
將
linkerd.io/inject: enabled
註釋新增至同一個位置中的 frontend-deploy.yml 檔案。更新 Kube 叢集中的部署:
kubectl apply -f backend-deploy.yml,frontend-deploy.yml
套用產品服務的 Linkerd 服務設定檔
該產品服務的服務設定檔資訊清單為:
apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: backend
namespace: default
spec:
routes:
- condition:
method: GET
pathRegex: /api/Product
name: GET /v1/products
isRetryable: true
retryBudget:
retryRatio: 0.2
minRetriesPerSecond: 10
ttl: 120s
前面的資訊清單已設定,因此:
- 任何符合
/api/Product
模式的等冪 HTTP GET 路由都可以重試。 - 重試次數最多只能增加額外 20% 的要求負載,再加上每秒另外 10 次的「免費」重試。
執行下列命令,以在 Kube 叢集中使用服務設定檔:
kubectl apply -f - <<EOF
apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: backend
namespace: default
spec:
routes:
- condition:
method: GET
pathRegex: /api/Product
name: GET /v1/products
isRetryable: true
retryBudget:
retryRatio: 0.2
minRetriesPerSecond: 10
ttl: 120s
EOF
會出現下列輸出:
serviceprofile.linkerd.io/backend created
在服務網格上安裝監視功能
Linkerd 具有延伸模組,可為您提供額外的功能。 安裝 viz 延伸模組,並在 Linkerd 的儀錶板中檢視應用程式的狀態。
在終端中,執行此命令以安裝延伸模組:
linkerd viz install | kubectl apply -f -
使用此命令檢視儀表板:
linkerd viz dashboard
移至 [連接埠] 索引標籤,並查看透過執行中的 [linkerd viz 儀表板] 程序轉送的新連接埠。 選取 [在瀏覽器中開啟] 以開啟該儀表板。
在 Linkerd 儀錶板中,選取 [命名空間]。
在 [HTTP 計量] 底下,選取 [預設值]。
測試 Linkerd 復原功能
待重新部署的容器狀況良好之後,請使用下列步驟測試應用程式對 Linkerd 的行為:
使用此命令檢查執行中 Pod 的狀態:
kubectl get pods --all-namespaces
停止所有產品服務 Pod:
kubectl scale deployment productsbackend --replicas=0
移至 eShop Web 應用程式並嘗試檢視產品。 在以下的錯誤訊息出現之前會有延遲:「載入我們的產品時出現問題。請稍後再試。」
重新啟動產品服務 Pod:
kubectl scale deployment productsbackend --replicas=1
應用程式現在應該會顯示產品。
Linkerd 遵循的復原方式會和您在程式碼式復原中看到的不同。 Linkerd 會以明確的方式,連續快速地重試作業多次。 應用程式不需要變更即可支援此行為。
其他資訊
如需 Linkerd 設定的相關資訊,請參閱下列資源:
- 設定重試 - Linkerd 文件
- 設定逾時 - Linkerd 文件
- How we designed retries in Linkerd 2.2 - Linkerd blog (Linkerd 2.2 的重試設計方式 - Linkerd 部落格)