前面文章已經演示過,將我們的示例微服務程序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上的容器暴漏端口。