The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

使用 Dapr 與 Kubernetes 打造微服務架構:以 AKS 為例

我昨天在 Kubernetes Summit 2021 舉行了一場實戰工作坊,詳細的介紹 Dapr 這套工具如何部署到 Kubernetes,以及如何透過 Dapr 大幅降低導入微服務架構的複雜度。今天這篇文章我打算以 Azure Kubernetes Services (AKS) 為例,將我昨天的實戰工作坊完整實作一遍。

準備 Azure 資源

  1. 安裝 Azure CLI 工具

  2. 透過 Azure CLI 登入帳號

    az login --use-device-code
    

    開啟 https://microsoft.com/devicelogin 網頁,並輸入你在 CLI 看到的 Device Code

  3. 列出目前使用的帳號與可使用的訂用帳戶(Subscription)

    az account list -o table
    
  4. 選擇要建立資源的訂用帳戶(Subscription)

    az account set --subscription [subscription-id]
    
  5. 建立資源群組 (Resource Group)

    az group create -n k8ssummitlab -l westus2
    az group list
    
  6. 調整 Azure CLI 使用預設資源群組與區域

    az configure --defaults location=westus2 group=k8ssummitlab
    az configure --list-defaults
    
  7. 註冊 Azure CLI 提供者

    # 註冊 Microsoft.Cache 提供者,讓你可以用 az redis 命令
    az provider register --namespace Microsoft.Cache
    
    # 啟用叢集監控功能 (Enable cluster monitoring)
    az provider register --namespace Microsoft.OperationsManagement
    az provider register --namespace Microsoft.OperationalInsights
    
    # 檢查是否已經啟用監控功能
    az provider show -n Microsoft.OperationsManagement -o table
    az provider show -n Microsoft.OperationalInsights -o table
    
  8. 註冊 AKS-ExtensionManagerAKS-Dapr 預覽功能

    az feature register --namespace "Microsoft.ContainerService" --name "AKS-ExtensionManager"
    az feature register --namespace "Microsoft.ContainerService" --name "AKS-Dapr"
    

    檢查是否註冊成功 (可能要等十幾分鐘才會註冊好)

    az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/AKS-ExtensionManager')].{Name:name,State:properties.state}"
    az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/AKS-Dapr')].{Name:name,State:properties.state}"
    

    更新功能旗標狀態 (上面的步驟確實完成才能執行以下這兩行)

    az provider register --namespace Microsoft.KubernetesConfiguration
    az provider register --namespace Microsoft.ContainerService
    

    更新功能旗標狀態 (上面的步驟確實完成才能執行以下這兩行)

    az provider show -n Microsoft.KubernetesConfiguration
    az provider show -n Microsoft.ContainerService
    

建立 AKS 叢集環境

  1. 查詢可使用的 Kubernetes 版本

    az aks get-versions -o table
    
    KubernetesVersion    Upgrades
    -------------------  ------------------------
    1.22.4               None available
    1.22.2               1.22.4
    1.21.7               1.22.2, 1.22.4
    1.21.2               1.21.7, 1.22.2, 1.22.4
    1.20.13              1.21.2, 1.21.7
    1.20.9               1.20.13, 1.21.2, 1.21.7
    1.19.13              1.20.9, 1.20.13
    1.19.11              1.19.13, 1.20.9, 1.20.13
    
  2. 建立 Kubernetes 叢集

    Bash

    az aks create -n k8ssummitaks -l westus2 -g k8ssummitlab \
        --kubernetes-version 1.21.7 \
        --node-vm-size Standard_DS2_v2 \
        --enable-cluster-autoscaler \
        --node-count 3 \
        --min-count 3 \
        --max-count 6 \
        --network-plugin azure \
        --network-policy calico \
        --enable-addons monitoring \
        --enable-managed-identity \
        --generate-ssh-keys \
        -o json
    

    PowerShell

    az aks create -n k8ssummitaks -l westus2 -g k8ssummitlab `
        --kubernetes-version 1.21.7 `
        --node-vm-size Standard_DS2_v2 `
        --enable-cluster-autoscaler `
        --node-count 3 `
        --min-count 3 `
        --max-count 6 `
        --network-plugin azure `
        --network-policy calico `
        --enable-addons monitoring `
        --enable-managed-identity `
        --generate-ssh-keys `
        -o json
    
  3. 檢查叢集是否建立成功

    az aks list -o table
    
  4. 安裝 kubectl 工具 (請安裝與 Server 一樣的版本)

    Bash

    sudo az aks install-cli --client-version=1.21.7
    

    PowerShell

    az aks install-cli --client-version=1.21.7
    
    $env:PATH = "$env:USERPROFILE\.azure-kubectl;$env:USERPROFILE\.azure-kubelogin;" + $env:PATH
    
  5. 連接 AKS 叢集 (取得 KUBECONFIG 檔案)

    az aks get-credentials -n k8ssummitaks
    
  6. 測試 AKS 是否可以正常連接

    # 請確保 Client 與 Server 為相同版號
    kubectl version --short
    
    # 取得叢集資訊
    kubectl cluster-info
    
    # 取得叢集節點資訊
    kubectl get node -o wide
    
    # 取得叢集所有 namespace 與 pod 清單
    kubectl get pod --all-namespaces
    

初始化 Dapr 到 Kubernetes 叢集 (Deploy Dapr on a Kubernetes cluster)

  1. 安裝 Dapr CLI 工具

  2. 初始化 Dapr 並安裝至 Kubernetes 叢集中

    啟用 Dapr 高可用模式

    dapr init -k --enable-ha=true --wait
    

    啟用 Dapr 單點模式

    dapr init -k --wait
    
    Making the jump to hyperspace...
    Note: To install Dapr using Helm, see here: https://docs.dapr.io/getting-started/install-dapr-kubernetes/#install-with-helm-advanced
    
    Deploying the Dapr control plane to your cluster...
    Success! Dapr has been installed to namespace dapr-system. To verify, run `dapr status -k' in your terminal. To get started, go here: https://aka.ms/dapr-getting-started
    

    初始化需要 1 分鐘左右,請用以下命令確認所有 STATUS 都是 Running 狀態

    dapr status -k
    
    NAME                   NAMESPACE    HEALTHY  STATUS   REPLICAS  VERSION  AGE  CREATED
    dapr-dashboard         dapr-system  True     Running  1         0.9.0    2m   2021-12-21 18:58.28
    dapr-operator          dapr-system  True     Running  3         1.5.1    2m   2021-12-21 18:58.28
    dapr-sentry            dapr-system  True     Running  3         1.5.1    2m   2021-12-21 18:58.28
    dapr-sidecar-injector  dapr-system  True     Running  3         1.5.1    2m   2021-12-21 18:58.28
    dapr-placement-server  dapr-system  True     Running  3         1.5.1    2m   2021-12-21 18:58.28
    
  3. 重新部署 deploy/dapr-operator (參考資訊)

    kubectl rollout restart deploy/dapr-operator -n dapr-system
    
  4. 建立 Azure Cache for Redis 服務

    先建立 Azure Cache for Redis 服務 (az redis create)

    az redis create -n k8ssummitredis --sku Basic --vm-size c0 -o json
    

    取得 Redis 金鑰 (your-redis-password)

    az redis list-keys -n k8ssummitredis
    
  5. 建立一個狀態儲存元件 (state store)

    建立 Secret 儲存 Redis 金鑰

    kubectl create secret generic redis --from-literal=redis-password=<your-redis-password>
    

    設定 Dapr 元件 (Dapr components)

    apiVersion: dapr.io/v1alpha1
    kind: Component
    metadata:
      name: statestore
    spec:
      type: state.redis
      version: v1
      metadata:
      # These settings will work out of the box if you use `helm install
      # bitnami/redis`.  If you have your own setup, replace
      # `redis-master:6379` with your own Redis master address, and the
      # Redis password with your own Secret's name. For more information,
      # see https://docs.dapr.io/operations/components/component-secrets .
      - name: redisHost
        value: k8ssummitredis.redis.cache.windows.net:6380
      - name: redisPassword
        secretKeyRef:
          name: redis
          key: redis-password
      - name: enableTLS
        value: true
    auth:
      secretStore: kubernetes
    

    安裝元件

    kubectl apply -f ./deploy/redis.yaml
    

部署 Dapr 範例應用程式

  1. 下載原始碼

    git clone https://github.com/dapr/quickstarts.git
    cd quickstarts/hello-kubernetes
    
  2. 部署 Node.js 應用程式

    # 部署 Node.js 應用程式
    kubectl apply -f ./deploy/node.yaml
    
  3. 查看 dapr-sidecar-injector 是否正常運作

    透過以下命令取得 Dapr 的 Sidecar Injector Logs

    kubectl logs -l app=dapr-sidecar-injector -n dapr-system
    

    你必須看到 Sidecar injector succeeded injection for app 'nodeapp' 這個訊息:

    time="2021-12-21T20:10:30.577411865Z" level=info msg="log level set to: info" instance=dapr-sidecar-injector-6f749dbf87-vvrnz scope=dapr.injector type=log ver=unknown
    time="2021-12-21T20:10:30.578115669Z" level=info msg="metrics server started on :9090/" instance=dapr-sidecar-injector-6f749dbf87-vvrnz scope=dapr.metrics type=log ver=unknown
    time="2021-12-21T20:10:30.578207469Z" level=info msg="starting Dapr Sidecar Injector -- version 1.5.1 -- commit c6daae8e9b11b3e241a9cb84c33e5aa740d74368" instance=dapr-sidecar-injector-6f749dbf87-vvrnz scope=dapr.injector type=log ver=unknown
    time="2021-12-21T20:10:30.58025808Z" level=info msg="Healthz server is listening on :8080" instance=dapr-sidecar-injector-6f749dbf87-vvrnz scope=dapr.injector type=log ver=unknown
    time="2021-12-21T20:10:31.654958547Z" level=info msg="Sidecar injector is listening on :4000, patching Dapr-enabled pods" instance=dapr-sidecar-injector-6f749dbf87-vvrnz scope=dapr.injector type=log ver=unknown
    time="2021-12-21T20:12:31.613696722Z" level=info msg="AdmissionReview for Kind=/v1, Kind=Pod, Namespace=default Name= () UID=e49c2a43-503d-4607-a2f3-0fedf0e6f76f patchOperation=CREATE UserInfo={system:serviceaccount:kube-system:replicaset-controller b195fb68-b478-4954-992c-8653f2009acb [system:serviceaccounts system:serviceaccounts:kube-system system:authenticated] map[]}" instance=dapr-sidecar-injector-6f749dbf87-vvrnz scope=dapr.injector type=log ver=unknown
    time="2021-12-21T20:12:31.640646979Z" level=info msg="ready to write response ..." instance=dapr-sidecar-injector-6f749dbf87-vvrnz scope=dapr.injector type=log ver=unknown
    time="2021-12-21T20:12:31.641067781Z" level=info msg="Sidecar injector succeeded injection for app 'nodeapp'" instance=dapr-sidecar-injector-6f749dbf87-vvrnz scope=dapr.injector type=log ver=unknown
    
  4. 取得 Node.js 應用程式的服務端點 (EXTERNAL-IP)

    kubectl get svc nodeapp
    

    假設為 20.112.54.56

    PowerShell

    $EXTERNAL_IP='http://20.112.54.56'
    

    Bash

    export EXTERNAL_IP='http://20.112.54.56'
    
  5. 測試應用程式 (讀取 DAPR_HTTP_PORTDAPR_GRPC_PORT 環境變數)

    curl "$EXTERNAL_IP/ports"
    
  6. 執行建立訂單 (透過 Dapr 與 state store 寫入狀態)

    curl --request POST --data "@sample.json" --header 'Content-Type: application/json' "$EXTERNAL_IP/neworder"
    
  7. 查看訂單編號 (透過 Dapr 與 state store 讀取狀態)

    curl "$EXTERNAL_IP/order"
    
  8. 部署 Python 應用程式 (透過 Dapr 呼叫 nodeapp 的 neworder 方法)

    kubectl apply -f ./deploy/python.yaml
    

    查看 Python 應用程式的 Logs

    kubectl logs --selector=app=node -c node --tail=-1 -f
    
  9. 查看訂單編號 (透過 Dapr 與 state store 讀取狀態)

    curl "$EXTERNAL_IP/order"
    
  10. 開啟 Dapr Dashboard 儀表版介面

    先找出 dapr-dashboard 的 Pod 名稱

    kubectl get pod --namespace=dapr-system -l 'app.kubernetes.io/component=dashboard'
    

    開啟 Port Forwarding

    kubectl port-forward dapr-dashboard-57b4db56fc-pxvs7 8080:8080 --namespace=dapr-system
    

    開啟 http://localhost:8080/ 網頁

清除應用程式與 Dpar 相關資源

  1. 刪除 Deployments, Pods, Services

    kubectl delete -f ./deploy/node.yaml
    kubectl delete -f ./deploy/python.yaml
    
  2. 從 Kubernetes 清除 Dapr 相關資源

    dapr uninstall -k
    

暫停 AKS 叢集 (將 Node Count 調整為 0)

az aks stop -n k8ssummitaks --no-wait

重啟 AKS 叢集 (將 Node 調整回暫停前的狀態)

az aks start -n k8ssummitaks --no-wait

刪除 k8ssummitlab 資源群組 (連同 AKS 叢集一併刪除)

az group delete --name k8ssummitlab --yes --no-wait

相關連結

留言評論