我昨天在 Kubernetes Summit 2021 舉行了一場實戰工作坊,詳細的介紹 Dapr 這套工具如何部署到 Kubernetes,以及如何透過 Dapr 大幅降低導入微服務架構的複雜度。今天這篇文章我打算以 Azure Kubernetes Services (AKS) 為例,將我昨天的實戰工作坊完整實作一遍。
準備 Azure 資源
-
安裝 Azure CLI 工具
-
透過 Azure CLI 登入帳號
az login --use-device-code
開啟 https://microsoft.com/devicelogin 網頁,並輸入你在 CLI 看到的 Device Code
-
列出目前使用的帳號與可使用的訂用帳戶(Subscription)
az account list -o table
-
選擇要建立資源的訂用帳戶(Subscription)
az account set --subscription [subscription-id]
-
建立資源群組 (Resource Group)
az group create -n k8ssummitlab -l westus2
az group list
-
調整 Azure CLI 使用預設資源群組與區域
az configure --defaults location=westus2 group=k8ssummitlab
az configure --list-defaults
-
註冊 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
-
註冊 AKS-ExtensionManager
與 AKS-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 叢集環境
-
查詢可使用的 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
-
建立 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
-
檢查叢集是否建立成功
az aks list -o table
-
安裝 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
-
連接 AKS 叢集 (取得 KUBECONFIG
檔案)
az aks get-credentials -n k8ssummitaks
-
測試 AKS 是否可以正常連接
# 請確保 Client 與 Server 為相同版號
kubectl version --short
# 取得叢集資訊
kubectl cluster-info
# 取得叢集節點資訊
kubectl get node -o wide
# 取得叢集所有 namespace 與 pod 清單
kubectl get pod --all-namespaces
-
安裝 Dapr CLI 工具
-
初始化 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
-
重新部署 deploy/dapr-operator
(參考資訊)
kubectl rollout restart deploy/dapr-operator -n dapr-system
-
建立 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
-
建立一個狀態儲存元件 (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 範例應用程式
-
下載原始碼
git clone https://github.com/dapr/quickstarts.git
cd quickstarts/hello-kubernetes
-
部署 Node.js 應用程式
# 部署 Node.js 應用程式
kubectl apply -f ./deploy/node.yaml
-
查看 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
-
取得 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'
-
測試應用程式 (讀取 DAPR_HTTP_PORT
與 DAPR_GRPC_PORT
環境變數)
curl "$EXTERNAL_IP/ports"
-
執行建立訂單 (透過 Dapr 與 state store 寫入狀態)
curl --request POST --data "@sample.json" --header 'Content-Type: application/json' "$EXTERNAL_IP/neworder"
-
查看訂單編號 (透過 Dapr 與 state store 讀取狀態)
curl "$EXTERNAL_IP/order"
-
部署 Python 應用程式 (透過 Dapr 呼叫 nodeapp 的 neworder 方法)
kubectl apply -f ./deploy/python.yaml
查看 Python 應用程式的 Logs
kubectl logs --selector=app=node -c node --tail=-1 -f
-
查看訂單編號 (透過 Dapr 與 state store 讀取狀態)
curl "$EXTERNAL_IP/order"
-
開啟 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 相關資源
-
刪除 Deployments, Pods, Services
kubectl delete -f ./deploy/node.yaml
kubectl delete -f ./deploy/python.yaml
-
從 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
相關連結