【影片】k8s套娃開發調試dapr應用 – 在6月11日【開源雲原生開發者日】上的演示

這篇部落格是在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 指令)工具,可以通過這個地址安裝 //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的詳細資訊可以參考 //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

 

現在,你就可以打開 //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,項目地址 //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