【視訊】k8s套娃開發偵錯dapr應用

2022-06-16 06:00:39

這篇部落格是在2022年6月11日的【開源雲原生】大會上的演講中的演示部分。k8s叢集套娃(巢狀)是指在一個k8s的pod中執行另外一個k8s叢集,這想法看上去很瘋狂,實際上非常實用。

VMLC

k8s叢集套娃(巢狀)是指在一個k8s的pod中執行另外一個k8s叢集,這想法看上去很瘋狂,其實這想法也非常實用。 試想,當你開發一個k8s應用的時候候一定會希望在自己的環境中先測試一下,這時你有幾個選擇:1)自己找伺服器搭建一個完整的叢集;2)在自己的本地開發機中搭建一個精簡的叢集,比如使用minikube或者docker desktop;3)直接在生產環境部署。無論哪種做法,你都需要面臨很多難以解決的問題,自己搭建完整叢集操作複雜而且還需要額外準備伺服器資源,本地搭建叢集對開發機要求高,沒有個8核16G的高配筆電是不可能的,更不要說minikube和docker desktop 只支援單一節點的閹割版叢集,做簡單的測試可以,如果要完成一些複雜的叢集排程實驗就會顯得力不從心。最後,如果你打算直接在生產環境部署,那麼需要足夠的膽量並且隨時做好怕路的準備。

其實,這是當前雲原生開發的一個普遍困境,開發環境變得越來越複雜,以往我們只需要拿到原始碼就可以開發偵錯的日子不再有了。k8s環境使用起來方便,但是對於開發者而言,要獲取一個使用者開發偵錯和測試,或者隨便可以折騰的環境太困難了。今天要給大家介紹的k8s套娃就是為了應對這個困境的,讓開發者可以實現 隨用隨啟、用完即焚!

雲原生IDE的優勢和困境

雲原生開發的最佳環境其實就是雲原生環境本身,既然我們的應用會執行在容器中,那麼我們為什麼不直接到容器中開發;既然我們的應用會執行在K8s中,為什麼我們不直接在k8s中進行開發?先不用關心如何實現,我們先來看看這樣做會帶來怎樣一些好處:

  • 適用於任何人、任何時間、任何地點的標準化環境:將開發環境放入容器意味著我們可以像管理容器一樣管理開發環境,類似系統設定、開發語言SDK,IDE,測試工具,設定項等等都可以利用容器技術進行標準化;同時因為是容器,我們可以實現 Lift & Shift (拿起就走&插上就幹活)的能力。你只需要對開發環境定義一次,就可以讓任何人在任何地方複製出同樣的環境。

  • 徹底消除專案上手和切換成本:基於以上能力,我們將開發環境組態檔也放入當前專案的程式碼庫,開發者只要拿到了程式碼就拿到了環境(因為環境組態檔和程式碼版本是統一管理,版本保持對齊)。這樣開發者再也不用為了偵錯某份程式碼重新搭建環境,可以隨時隨地的切換到應用的任何版本上,甚至可以同時開發偵錯一個應用的不同版本。這其實就 IDE as Code 的概念體現,具體請參考 這篇部落格。

  • 端到端的程式碼安全:既然開發環境位於容器中,我們就可以將這個容器放置於一個完全受管控的雲端環境中,專案的程式碼完全在這個容器中被處理,開發者不需要下載程式碼;所有的程式碼操作,包括:編寫,編譯,打包,測試和釋出過程全部通過網頁在雲端完成。對於需要很高程式碼安全性保障的行業,比如:金融、軍工、通訊和高科技企業來說;這個特性可以徹底解決程式碼安全問題。而且,使用雲原生IDE還可以在保障程式碼安全同時允許企業放心的使用外包開發人員。在當全球疫情持續發展的情況下,遠端開發基礎設施變成了企業的必備能力,雲原生IDE在這方面有天然的優勢。

  • 解鎖雲端超算力環境:很多大規模系統動輒需要幾百個服務元件才能執行,要在本地完成這種環境搭建是完全不可能實現的,即便有專業運維團隊的支援,在雲端複製類似的環境也困難重重,這造成在很多大規模開發團隊中,開發/偵錯/測試環境的獲取變成了一個普遍的瓶頸。而利用雲原生IDE所提供的IDE as Code能力,複製一個環境和啟動一個普通的開發環境沒有本質上的區別,開發者在程式碼庫中隨意選取一個程式碼版本一鍵完成整個環境的搭建變得非常簡單。測試環境的獲取能力是評估一個團隊DevOps能力的通用標準,採用基於 IDE as Code 的之後,獲取這項能力的門檻將被完全抹平。開發人員也因此可以完全解鎖雲端的超強算力,儲存和高速網路環境,對於AI,巨量資料,區塊鏈,Web3.0這些需要複雜環境支撐的開發場景,雲原DE更加是一個必須品。

當然,雲原生IDE也並不是沒有缺點,使用容器作為開發環境本身就會遇到很多的問題。

容器化開發環境的困境和解決方案VMLC

容器化技術出現以後,絕大多數的使用場景都是生產環境,因此對容器的優化目標都是圍繞精簡,單一程序,不可變狀態的目標來實現的;對於開發人員來說,按這種目標設計的容器並不適合作為開發環境來使用。相對於生產環境中已經預先確定的設定,開發環境的設定則需要進行持續的調整,在Inner Cycle中,每個環節(包含了編碼,編譯打包,部署,測試,修復)都會產生環境變更的訴求。

VMLC(類虛擬機器器容器) 是 VM Like Container 的縮寫,其設計目標是為開發者在容器中提供類似虛擬機器器的環境,包括:systemd服務管理能力,sshd遠端登入能力,docker/k8s巢狀能力等。

VMLC

使用VMLC技術實現容器巢狀

SmartIDE 是完全基於 IDE as Code 理念設計和開發的一款 雲原生IDE 產品,開發者既可以使用 SmartIDE CLI 在個人開發環境中一鍵拉起 雲原生IDE 開發環境,也可以由企業管理員部署 SmartIDE Sever 統一管理。SmartIDE 支援跨平臺,Windows / MacOS / Linux 均可以使用,開發者也可以選擇自己習慣的 IDE工具,比如:VSCode, JetBrains全家桶 以及 國產開源的OpenSumi。 SmartIDE 通過 開發者映象和模版 同時支援7種主流開發語言技術棧,包括:前端/Node/JavaScriptJavaDotNet/C#Python/Anaconda, PHP, Golang, C/C++;如果這些內建的映象和模版都無法滿足開發者的需求,也可以通過客製化的Dockerfile和模版定義來進行擴充套件,這些 Dockefile和模版 全部都採用GPL3.0開源協定免費提供給社群使用。

VMLC

以下演示是在 2022年6月11日舉辦的 開源雲原生開發者大會 上的展示的使用 SmartIDE VMLC開發者容器 完成一個 dapr 應用的開發偵錯場景:

以下是視訊中演示的操作手冊,感興趣的小夥伴可以自己操作體驗一下;範例採用 dapr-traffic-control 應用程式碼,程式碼庫地址如下:

所有操作指令碼都可以在以上程式碼庫中找到。

建立支援VMLC的AKS叢集

使用以下指令碼建立 Azure Kubernetes Service

如果沒有安裝 Azure CLI 命令列(az 指令)工具,可以通過這個地址安裝 https://docs.microsoft.com/zh-cn/cli/azure/install-azure-cli

 1 ## 以下指令碼可以在Windows/MacOS/Linux上執行
 2 
 3 ## 建立aks
 4 ## 登入並切換到你需要使用的訂閱
 5 az login 
 6 az account set -s <訂閱ID>
 7 
 8 ## 建立資源組,資源組可以方便你管理Azure種的資源,後續我們可以直接刪除這個資源組就可以清理所有資源
 9 az group create --name SmartIDE-DEMO-RG --location southeastasia
10 ## 建立一個單節點的AKS叢集,使用 Standard_B8ms 節點大小,可以根據需要修改指令碼
11 az aks create -g SmartIDE-DEMO-RG -n SmartIDEAKS --location southeastasia --node-vm-size Standard_B8ms --node-count 1 --disable-rbac --generate-ssh-keys
12 ## 獲取連結金鑰,金鑰檔案可以自動儲存到當前使用者的預設位置 ~/.kube/config 
13 ## 獲取後本地可以直接私用 kubectl 操作叢集
14 az aks get-credentials -g SmartIDE-DEMO-RG -n SmartIDEAKS

 

完成以上操作後,我們就獲取到了一個可用的AKS叢集,整個操作不超過5分鐘;下面使用k9s連線到叢集進行狀態監控,k9s是一個基於命令列的視覺化k8s管理工具(Windows/MacOS/Linux都可以使用),非常方便而且輕量,安裝地址如下:

VMLC

啟用VMLC支援

VMLC容器需要底層容器執行時的支援,以下指令可以完成sysbox container runtime的安裝

有關sysbox的詳細資訊可以參考 https://github.com/nestybox/sysbox

1 ## 獲取節點名稱
2 kubectl get nodes
3 ## 在節點上新增 sysbox-install=yes 的 label
4 kubectl label nodes <節點名稱> sysbox-install=yes
5 ## 安裝 sysbox container runtime
6 ### 國內安裝地址
7 kubectl apply -f https://gitee.com/smartide/SmartIDE/raw/main/server/deployment/k8s-manifest/sysbox-install.yaml
8 ### 國際安裝地址
9 kubectl apply -f https://raw.githubusercontent.com/SmartIDE/SmartIDE/main/server/deployment/k8s-manifest/sysbox-install.yaml

 

執行後可以在k9s中實時檢視安裝進度,等待以下這個安裝程序結束即可開始使用。

部署sysbox container runtime是叢集級別的一次性操作,只需要管理員在建立叢集的時候執行一次即可。

VMLC

部署VMLC開發環境

所有VMLC開發環境均通過開發者映象的方式提供,在 smartide-dapr-traffic-control 這個程式碼庫已經放置了適配好的 VMLC開發環境部署 manifest 檔案,檔案內容如下:

 1 apiVersion: v1
 2 kind: Pod
 3 metadata:
 4   name: smartide-dev-container
 5   annotations:
 6     io.kubernetes.cri-o.userns-mode: "auto:size=65536"
 7 spec:
 8   runtimeClassName: sysbox-runc
 9   containers:
10   - name: smartide-dev-container
11     image: registry.cn-hangzhou.aliyuncs.com/smartide/smartide-dotnet-v2-vmlc
12     command: ["/sbin/init"]
13   restartPolicy: Never

 

使用以下指令碼即可獲取原始碼並完成 VMLC開發環境部署

git clone https://github.com/SmartIDE/sample-dapr-traffic-control.git
cd sample-dapr-traffic-control
kubectl apply -f vmlc/smartide-vscode-v2-vmlc.yaml

 

執行以上操作以後,通過k9s檢視名為 smartide-dev-containter 的 pod 的部署狀態,部署狀態為 running 即可開始使用了。

VMLC

執行以下指令進入 smartide-dev-container 容器

kubectl exec -i -t -n default smartide-dev-container -c smartide-dev-container "--" sh -c "clear; (bash || ash || sh )"

 

現在我們就可以在這個執行在 k8s 叢集 pod 的容器內進行操作了

1 ## 切換到 smartide 使用者
2 su smartide
3 ## 切換到 smartide 的預設目錄
4 cd
5 ## 將 smartide-dapr-traffic-control 程式碼克隆到容器中
6 git clone https://github.com/SmartIDE/sample-dapr-traffic-control.git

 

在VMLC容器中內建一個叫做 smartide 的普通使用者,這是一個非 root 使用者,預設情況下VMLC容器全部通過這個使用者進行操作,避免越權存取主機資源。 這個容器中已經內建了dotnet開發環境以及dapr cli工具,但是使用 terminal 操作確實不太方便。下面讓我們切換到 VSCode WebIDE 進行後續的開發工作。

使用VSCode WebIDE存取VMLC開發環境

在SmartIDE所提供的VMLC開發者映象中已經內建了 VSCode WebIDE,下面讓我們將容器的3000埠對映到原生的6800埠,並通過瀏覽器存取我們的VMLC開發環境。

## 在你本地開發機的另外一個terminal中執行以下指令
## 注意不要使用以上已經進入 dev-container 容器的terminal
## 這個指令會將遠端k8s pod中容器的3000埠對映到你原生的6800埠
kubectl port-forward smartide-dev-container 6800:3000

 

現在,你就可以開啟 http://localhost:6800 埠並存取內建於 VMLC 容器中的 VSCode WebIDE 了,點選 Open Folder 按鈕,並開啟 /home/smartide/sample-dapr-traffic-control 作為我們的工作目錄

VMLC

點選 OK 之後,你就可以開始愉快的編碼了,注意你現在使用的是 smartide 使用者存取 smartide-dev-container 的開發環境

VMLC

通過VMLC的開發者映象,我們已經在這個環境中內建了 dotnet sdk, 以及 dapr clikubectlhelmdocker 等常用雲原生開發工具。你可以按照 這篇部落格 的操作完成這個dapr應用的 self-hosted 模式的開發偵錯。這個模式其實是將容器作為你的本地開發環境,並通過容器中的docker巢狀支援來提供 dapr所需要的中介軟體環境。

你會發現使用WebIDE進行類似的操作非常方便,這同時也意味著你已經脫離了你原生的開發機,可以在任何地點存取這個位於雲端的開發環境。 當然,如果你不習慣在瀏覽器中操作IDE環境,也可以通過你原生的常用IDE來存取我們的遠端 VMLC開發環境。

使用Hybird模式存取雲端工作區

在 SmartIDE VMLC 開發環境中,除了內建 WebIDE 之外,也內建了 ssh 服務。也就是說,你現在可以像存取一臺普通的雲端虛擬機器器一樣存取你的 VMLC 容器開發環境。 執行以下指令將 VMLC 的22埠對映到原生的 22002 埠上

kubectl port-forward smartide-dev-container 22002:22

 

現在你就可以開啟原生的命令列通過標準的SSH協定存取這個 VMLC 開發環境了。

## 使用以下指令建立SSH連線,預設密碼 smartide123.@IDE (這個密碼可以通過後續的SmartIDE CLI或者Server進行重置)
ssh smartide@localhost -p 22002

 

當然,通過命令列的方式並不是每個開發者都習慣的方式,那麼我們可以通過 VSCode 的 Remote SSH 外掛或者 JetBrains Gateway 所提供的SSH通道連線方式,將你原生的VSCode或者JetBrains IDE連線到這個遠端的 VMLC雲端雲端工作。這個就是 Hybird(混動)模式。

Hybird 模式兼顧了本地IDE和雲端工作區雙方的優勢,讓開發者在編碼的過程中既可以享有本地工具的快速跟手的操作體驗,又可以方便使用雲端的超級算力。

VSCode Remote SSH 連線

在VSCode中連線雲端工作區非常簡單,你只需要在 SSH Remote 外掛中點選新增連線,然後輸入以上 SSH連線指令即可,這個過程與使用SSH連線一臺遠端主機完全一致。如果你看不到這個遠端連線工具鏈,那麼請從 這裡安裝 SSH Remote 外掛 即可。

VMLC

連線以後,設定工作區到 /home/smartide/sample-dapr-traffic-control 目錄,即可看到如下介面。

VMLC

JetBrains Gateway 連線

啟動Gateway之後,選擇 New Connection,並按我們的SSH指令填寫資訊,並點選 Check Connection and Continue 按鈕

VMLC

這時Gateway會要求你輸入SSH登入密碼,輸入之後會進入以下IDE型別選擇介面,根據需要選擇你希望使用的IDE,因為dapr是一個基於dotnet 6.0的專案,我們在這裡選擇Rider作為我們的接入使用者端IDE。

VMLC

然後制定工作區目錄為 /home/smartide/sample-dapr-traffic-control 目錄,點選 Download and Start IDE。這時Gateway會自動在遠端工作區啟動 Rider IDE Server,並在本地啟動 JetBrains Client,通過我們設定的SSH通道連線

VMLC

啟動完成的執行 JetBrains Client 如下

VMLC

現在,我們已經完成本地IDE和遠端工作區之間的Hybird模式連線。開發者可以根據自己的喜好和操作習慣選擇使用WebIDE或者Hybird模式連線到基於VMLC的遠端工作區。WebIDE的優點在於隨時隨地輕量程式設計,對本地開發機基本沒有任何資源壓力,即使使用一臺ipad也可以完成開發工作;而Hybird模式的優勢在於編碼體驗(特別在一些複雜的鍵盤操作和視窗佈局控制上),特別是重度IDE使用者會面對非常複雜的大規模專案,這種專案要完全執行在本地開發機是不可能的。

以下操作使用VSCode Remote SSH模式完成。

在容器中建立k8s叢集

下面,讓我們來將這個應用部署到 容器中巢狀的k8s叢集 中。首先執行以下指令,使用kind建立一個多節點的k8s叢集。

備註:Kind (Kuberentes in Docker) 是k8s開源專案下的一個sig,專案地址 https://kind.sigs.k8s.io/,希望瞭解KIND詳細背景和使用方法的小夥伴可以自行參考

cd vmlc
kind create cluster \
    --config multi-node.yaml \
    --image registry.cn-hangzhou.aliyuncs.com/smartide/nestybox-kindestnode:v1.20.7

 

以上指令執行完畢後,我們可以在容器中執行k9s指令,實時檢視容器內執行的叢集狀態,如下圖可以看到2個節點已經處於Ready狀態

VMLC

編譯打包並部署dapr應用到k8s叢集

現在我們可以進入 src/k8s 目錄執行 build-docker-images.ps1 指令碼,這個指令碼會完成所有應用的docker images的構建。

cd src/k8s
pwsh build-docker-images.ps1

 

VMLC

現在我們來登入到 docker hub 並將打包好的 images 推播上去(這個步驟你在執行時可以跳過,所有映象已經推播並設定為公開模式,可以直接拉取使用)。

docker login
pwsh push-docker-images.ps1

 

VMLC

最後,我們使用以下指令碼在k8s叢集上部署dapr基礎服務和範例應用的服務。

## 在預設的k8s叢集中部署dapr基礎服務
dapr init -k
## 部署 dapr-traffic-control 應用
pwsh start.ps1

 

下圖:dapr基礎服務啟動中

VMLC

下圖:dapr-traffic-control 相關服務啟動中

VMLC

至此,我們就完成了k8s套娃旅程。如果我們不再需要這個環境,就可以通過以下指令一鍵清理掉這個 VMLC 環境,其中的所有內容也就從我們的叢集上徹底清除了。

kubectl delete -f vmlc/smartide-vscode-v2-vmlc.yaml

 

這個過程中,大家應該可以明顯體會到使用套娃方式執行K8s叢集的好處,那就是簡單輕量,節省資源。當然這個過程中容器的安全也是得到充分保障的,VMLC內部使用時非root賬號,開發者在容器內無論進行怎樣的操作都不會對所在叢集的底層節點資源造成影響,是完全隔離的rootless環境。

使用SmartIDE一鍵啟動VMLC環境

當然,以上操作過程中大家也會有另外一個直觀感受,就是太複雜。完成類似的操作需要開發者對容器,k8s以及網路有充分的瞭解;這對普通開發者來說過於複雜。 SmartIDE的設計出發點就在這裡,讓開發者可以在 不學習/不瞭解 雲原生技術的前提下享受雲原生技術帶來的好處。在剛剛結束的 SmartIDE Sprint19中,我們已經發布了 Server版私有部署手冊,開發者可以使用一臺linux主機就可以自行部署一套完整的SmartIDE Server環境,並用它來管理自己的雲端工作區。

特別說明:SmartIDE Server的基礎版功能是開源免費的,任何人和企業都可以免費獲取並無限量使用。

使用SmartIDE Server雲端工作區啟動一個工作區就會變得非常簡單,開發者複製Git倉庫地址貼上到如下介面,即可啟動一個遠端工作區;這個遠端工作區可以執行在遠端主機或者k8s環境中,對於很多開發者而言,K8s仍然是一個過於複雜的存在,但是幾臺雲端的linux主機已經基本上是每個開發者的標配了。現在,你可以將這些Linux主機資源利用起來,使用 SmartIDE Server 將他們轉換為高效的雲端開發工作區。

下圖:使用SmartIDE Server建立雲端工作區

VMLC

下圖:執行在SmartIDE Server中的基於VMLC的遠端工作區,正在部署dapr基礎服務的狀態

VMLC

最後,希望每一名開發者都能尋找到雲原生時代的原力;May the force with YOU!

VMLC