前面文章已經演示過,將我們的示例微服務程式DaprTest1部署到k8s上並執行。當時用的k8s是Docker for desktop 自帶的k8s,只要在Docker for desktop中啟用就可以了。但是我發現,啟用了k8s後,Docker for desktop會消耗大量的系統資源,導致系統變得很慢。據說windows 上的WSL 2 效能不錯,這次我嘗試在WSL Linux上安裝K8s並部署我們的微服務,看看還會不會出現系統資源消耗過大的情況。
關於網路:我用的是外企公司的VPN。關於系統:我用的是Windows 11 1000.22000.168.0
1 在WSL上安裝k8s叢集
1.1 從微軟商店安裝“Windows Terminal”
Windows Terminal用來連線管理WSL中的Linux Ubuntu。
1.2 在本地電腦安裝“Lens”
Lens用來連線管理k8s叢集,啟動介面如下:
1.3 啟用Windows功能“虛擬機器平臺”
啟用虛擬機器平臺是安裝WSL 2 的必要條件
1.4 從微軟商店安裝“Ubuntu”
安裝WSL相容的Linux Ubuntu
安裝完成後,從開始選單開啟Ubuntu應用(命令視窗),提示使用者輸入使用者和密碼,設定好後,我們需要設定root使用者的密碼,命令為:
sudo passwd root
1.5 安裝Docker for desktop 並啟用WSL整合
為了更好的效能和程式開發方便,微軟不建議在 WSL Ubuntu 中直接安裝Docker,而是通過Docker for desktop與WSL 互操作的方式在Ubuntu中使用Docker。安裝地址:Docker Desktop for Mac and Windows | Docker
1.6 在Ubuntu 中安裝Kind
通過Windows terminal 連線 Ubuntu
通過su命令切換到root使用者,然後執行更新apt工具命令:
apt update && apt upgrade -y
安裝Kind最新版本,需要依次執行如下命令:
# 下載 KinD 二進位制檔案 curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.11.1/kind-$(uname)-amd64 # 標記為可執行檔案 chmod +x ./kind # 移動到 PATH 目錄下去 mv ./kind /usr/local/bin/ #檢視kind版本 kind version #輸出:kind v0.11.1 go1.16.4 linux/amd64
1.7 在Ubuntu 中安裝 Kubectl 工具
本步驟可選,因為我們也可以從本地電腦kubectl工具或者lens來管理k8s叢集.
安裝步驟如下(和Kind的安裝步驟類似):
curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" chmod +x ./kubectl sudo mv ./kubectl /usr/local/bin/kubectl
kubectl version
1.8 在Ubuntu 中用Kind 建立K8s 叢集
首先建立k8s叢集建立配置檔案(該叢集包含一個控制皮膚節點和一個工作節點)
# 建立一個2節點叢集的配置檔案 cat << EOF > kind-3nodes.yaml apiVersion: kind.x-k8s.io/v1alpha4 kind: Cluster nodes: - role: control-plane extraPortMappings: - containerPort: 30000 hostPort: 30000 listenAddress: "0.0.0.0" # Optional, defaults to "0.0.0.0" protocol: tcp # Optional, defaults to tcp - role: worker EOF
注意檔案中“extraPortMappings” 配置節,是用來將Ubuntu上的k8s容器30000埠暴漏給localhost(kind是通過容器來執行k8s 節點), 這樣我們就可以通過localhost:30000訪問k8s叢集中的服務。
然後根據配置檔案建立k8s叢集
# 使用配置檔案建立新的叢集
kind create cluster --name wslk8s --config ./kind-3nodes.yaml
建立完成後,我們可用命令kubectl cluster-info 檢視叢集資訊(如果我們在Ubuntu上安裝了Kubectl工具的話)。
1.9 用Lens和本地Kubectl 工具連線k8s叢集
在Ubuntu中開啟k8s連線配置檔案,並拷貝檔案內容。
cat $HOME/.kube/config
將檔案內容拷貝到本地電腦的C:\Users\[使用者名稱]/.kube/cofnig 檔案。
然後就可以在本地電腦用kubectl cluster-info 檢視叢集資訊,也可以開啟Lens, 看到叢集資訊。
2 在k8s叢集上部署微服務
2.1 在本地電腦用Dapr cli 安裝 Dapr 到K8s 叢集
因為我們的微服務示例程式是基於Dapr的,我們也能夠從本地電腦連線到k8s叢集,我們需要從本地電腦上通過Dapr Cli 安裝Dapr 到 k8s叢集。
Dapr init -k
2.2 在本地電腦從微服務專案生成映象
和以前一樣,我們從本地電腦的專案檔案中生成映象,執行
./build-docker-images.ps1
2.3 在Ubuntu 中用Kind將映象載入到k8s叢集
因為Kind 是把K8s的node放到容器中執行,導致k8s找不到我們自己生成的映象(錯誤:ImagePullError),我們需要通過Kind把我們的映象載入到k8s叢集。
kind load docker-image dapr-test1/blazorweb:3.0 --name wslk8s kind load docker-image dapr-test1/serviceapi1:3.0 --name wslk8s
2.4 在本地電腦用Kubectl工具部署微服務
在專案的Deploy 檔案中執行 ./Deploy.ps1命令即可部署我們的微服務到K8s叢集/
容器執行後,可通過http://localhost:30000訪問我們的示例微服務。
檢視工作管理員,發現通過WSL執行k8s的系統資源消耗比以前用Docker for desktop少了,系統執行也流暢了。
3 遺留待處理問題
3.1 Kind 部署K8s的 Nodeport問題
因為Kind是將K8s節點放到容器中執行,需要通過對localhost暴漏埠的方式來訪問微服務,微服務Nodeport配置的暴埠必須和k8s節點的暴漏埠一致才可以訪問。但是,如果我們的叢集上有多個微服務系統怎麼訪問呢?目前的想法是微服務通過Ingress的方式提供對外訪問,為每個微服務系統配置不同的域名。參考kind – Ingress (k8s.io) 和Kubernetes ingress same path multiple ports - Stack Overflow
3.2 公共服務的訪問問題。
我們每個微服務系統都會用到redis,RabbitMQ和zipkin等,沒有必要每個微服務系統都配置這些基礎服務容器來執行,計劃把這些基礎服務以通過Docker容器(暴漏localhost 埠)的方式執行,其它微服務系統通過定義Serivice 和Endpoints的方式來訪問這些基礎服務。參考mongodb - How to access host's localhost from inside kubernetes cluster - Stack Overflow ,需要測試用域名kubernetes.docker.internal 是否可以從k8s叢集內部訪問localhost上的容器暴漏埠。