練習 - 使用 Kubernetes 實作基礎結構復原功能

已完成

在上一個單元中,您已使用 .NET 原生復原擴充功能來新增失敗處理程序代碼,以實作復原功能。 不過,這項變更僅適用於您變更的服務。 更新具有許多服務的大型應用程式將是具有挑戰性的。

此單元不使用程式 代碼型 復原,而是使用稱為 基礎結構型 復原的方法,橫跨整個應用程式。 您將:

  • 在 Kubernetes 中重新部署應用程式,而不需要任何復原功能。
  • 在 Kubernetes 叢集中部署 Linkerd。
  • 將應用程式設定為使用 Linkerd 增強韌性。
  • 使用 Linkerd 探索應用程式行為。

重新部署應用程式

套用 Linkerd 之前,請先將應用程式還原為新增程式代碼型復原之前的狀態。 若要還原,請遵循下列步驟:

  1. 在底部面板中,選取 [ 終端機 ] 索引標籤,然後執行下列 git 命令來復原您的變更:

    cd Store
    git checkout Program.cs
    git checkout Store.csproj
    cd ..
    dotnet publish /p:PublishProfile=DefaultContainer
    

安裝 Kubernetes

在您的程式代碼空間中,安裝 Kubernetes 和 k3d。 k3d 是一種工具,可在本機計算機上的虛擬機 (VM) 內執行單一節點 Kubernetes 叢集。 它非常適合在本地測試 Kubernetes 部署,並且在 Codespace 中運行良好。

執行下列命令以安裝 Kubernetes 和 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 檔案轉換為 Kubernetes 指令清單

目前,您會定義應用程式在 Docker 中執行的方式。 Kubernetes 會使用不同的格式來定義您的應用程式執行方式。 您可以使用名為 Kompose 的工具,將 docker-compose 檔案轉換成 Kubernetes 指令清單。

  1. 您必須編輯這些檔案,才能使用您推送至 Docker Hub 的映像。

  2. 在codespace中,開啟 檔案backend-deploy.yml

  3. 變更這一行:

      containers:
        - image: [YOUR DOCKER USER NAME]/productservice:latest
    

    以您實際的 Docker 使用者名稱取代預留位置 [YOUR DOCKER USERNAME]。

  4. 針對 frontend-deploy.yml 檔案重複這些步驟。

  5. 變更這一行:

      containers:
      - name: storefrontend
        image: [YOUR DOCKER USER NAME]/storeimage:latest  
    

    以您實際的 Docker 使用者名稱取代預留位置 [YOUR DOCKER USERNAME]。

  6. 將 eShop 應用程式部署至 Kubernetes:

    kubectl apply -f backend-deploy.yml,frontend-deploy.yml  
    

    您應該會看到類似下列訊息的輸出:

    deployment.apps/productsbackend created
    service/productsbackend created
    deployment.apps/storefrontend created
    service/storefrontend created
    
  7. 檢查所有服務是否正在執行:

    kubectl get pods
    

    您應該會看到類似下列訊息的輸出:

    NAME                        READY   STATUS    RESTARTS   AGE
    backend-66f5657758-5gnkw    1/1     Running   0          20s
    frontend-5c9d8dbf5f-tp456   1/1     Running   0          20s
    
  8. 切換至 [ ] 索引卷標,以檢視在 Kubernetes 上執行的 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 部署至 Kubernetes

首先,執行下列命令來安裝自訂資源定義 (CRD):

linkerd install --crds | kubectl apply -f -

然後,執行下列命令:

linkerd install --set proxyInit.runAsRoot=true | kubectl apply -f -

在上述命令中:

  • linkerd install 會產生 Kubernetes 配置檔,內含必要的控制平面資源。
  • 產生的指令清單會透過管線輸送至 kubectl apply,在 Kubernetes 叢集中安裝控制平面資源。

輸出的第一行會顯示控制平面已安裝在自己的 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容器。

  1. linkerd.io/inject: enabled 批註新增至 範本 元數據下的backend-deploy.yml檔案。

      template:
        metadata:
          annotations:
            linkerd.io/inject: enabled
          labels: 
    
  2. linkerd.io/inject: enabled 批註新增至 frontend-deploy.yml 檔案的相同位置。

  3. 更新 Kubernetes 叢集中的部署:

    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 次「免費」重試。

執行下列命令以在 Kubernetes 叢集中使用服務設定檔:

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 的儀錶板中檢視應用程式的狀態。

  1. 在終端機中,執行此命令以安裝擴充功能:

    linkerd viz install | kubectl apply -f -
    
  2. 使用此指令檢視儀錶本:

    linkerd viz dashboard
    

    移至 [連接埠] 索引標籤,並查看透過執行中的 [linkerd viz 儀表板] 程序轉送的新連接埠。 選取 [ 在瀏覽器中開啟 ] 以開啟儀錶板。

  3. 在 Linkerd 儀錶板中,選取 [命名空間]

  4. 在 [HTTP 計量] 底下,選取 [預設值]。

    此螢幕擷取畫面顯示具有前端和後端的 Linkerd 儀表板。

測試 Linkerd 的復原能力

重新部署的容器狀況良好之後,請使用下列步驟來測試應用程式與Linkerd的行為:

  1. 使用此指令檢查正在運行的 Pods 狀態:

    kubectl get pods --all-namespaces
    
  2. 停止所有產品服務 Pod:

    kubectl scale deployment productsbackend --replicas=0
    
  3. 移至 eShop Web 應用程式,並嘗試檢視產品。 錯誤訊息會延遲顯示:「載入產品時發生問題。請稍後再試一次。

  4. 重新啟動產品服務 Pod:

    kubectl scale deployment productsbackend --replicas=1
    
  5. 應用程式現在應該會顯示產品。

Linkerd 遵循的復原方式會和您在程式碼式復原中看到的不同。 Linkerd 會以明確的方式,連續快速地重試作業多次。 應用程式不需要變更即可支持此行為。

其他資訊

如需 Linkerd 組態的詳細資訊,請參閱下列資源: