之前有很多同學提到如何做容器調試,特別是k8s環境下的容器調試,今天就講講我是如何調試的。大家都知道在vs自帶的創建項目模板里勾選docker即可通過F5啟動docker容器調試。但是對於啟動在k8s則不是那么清楚。其實兩者原理上是一樣的。
目錄:
一、通過Dapr實現一個簡單的基於.net的微服務電商系統
二、通過Dapr實現一個簡單的基於.net的微服務電商系統(二)——通訊框架講解
三、通過Dapr實現一個簡單的基於.net的微服務電商系統(三)——一步一步教你如何擼Dapr
四、通過Dapr實現一個簡單的基於.net的微服務電商系統(四)——一步一步教你如何擼Dapr之訂閱發布
五、通過Dapr實現一個簡單的基於.net的微服務電商系統(五)——一步一步教你如何擼Dapr之狀態管理
六、通過Dapr實現一個簡單的基於.net的微服務電商系統(六)——一步一步教你如何擼Dapr之Actor服務
七、通過Dapr實現一個簡單的基於.net的微服務電商系統(七)——一步一步教你如何擼Dapr之服務限流
八、通過Dapr實現一個簡單的基於.net的微服務電商系統(八)——一步一步教你如何擼Dapr之鏈路追蹤
九、通過Dapr實現一個簡單的基於.net的微服務電商系統(九)——一步一步教你如何擼Dapr之OAuth2授權 && 百度版Oauth2
十、通過Dapr實現一個簡單的基於.net的微服務電商系統(十)——一步一步教你如何擼Dapr之綁定
十一、通過Dapr實現一個簡單的基於.net的微服務電商系統(十一)——一步一步教你如何擼Dapr之自動擴/縮容
十二、通過Dapr實現一個簡單的基於.net的微服務電商系統(十二)——istio+dapr構建多運行時服務網格
十三、通過Dapr實現一個簡單的基於.net的微服務電商系統(十三)——istio+dapr構建多運行時服務網格之生產環境部署
十四、通過Dapr實現一個簡單的基於.net的微服務電商系統(十四)——開發環境容器調試小技巧
十五、通過Dapr實現一個簡單的基於.net的微服務電商系統(十五)——集中式接口文檔實現
十六、通過Dapr實現一個簡單的基於.net的微服務電商系統(十六)——dapr+sentinel中間件實現服務保護
十七、通過Dapr實現一個簡單的基於.net的微服務電商系統(十七)——服務保護之動態配置與熱重載
十八、通過Dapr實現一個簡單的基於.net的微服務電商系統(十八)——服務保護之多級緩存
十九、通過Dapr實現一個簡單的基於.net的微服務電商系統(十九)——分布式事務之Saga模式
二十、通過Dapr實現一個簡單的基於.net的微服務電商系統(二十)——Saga框架實現思路分享
附錄:(如果你覺得對你有用,請給個star)
一、電商Demo地址
首選我們看看在普通項目上vs是如何附加到容器的,我們打開一個新webapi項目,勾選啟用docker,選擇Linux環境,創建之后默認F5就會以容器的方式啟動調試模式。我們打開輸出->來源選擇“容器工具”,可以看到下面的日志輸出:
1 ========== 容器必備項檢查 ========== 2 正在驗證是否安裝了 Docker Desktop... 3 安裝了 Docker Desktop。 4 ========== 正在驗證 Docker Desktop 是否正在運行... ========== 5 正在驗證 Docker Desktop 是否正在運行... 6 Docker Desktop 正在運行。 7 ========== 正在驗證 Docker OS ========== 8 正在驗證 Docker Desktop 的操作系統模式是否匹配項目的目標操作系統... 9 Docker Desktop 的操作系統模式與項目的目標操作系統匹配。 10 ========== 拉取所需的映像 ========== 11 正在檢查缺少的 Docker 映像... 12 正在拉取 Docker 映像。要取消此下載,請關閉命令提示符窗口。 13 docker pull mcr.microsoft.com/dotnet/aspnet:5.0 14 Docker 映像准備就緒。 15 ========== 正在為 WebApplication5 預熱容器 ========== 16 正在啟動容器... 17 docker build -f "C:\Users\Administrator\source\repos\WebApplication5\WebApplication5\Dockerfile" --force-rm -t webapplication5:dev --target base --label "com.microsoft.created-by=visual-studio" --label "com.microsoft.visual-studio.project-name=WebApplication5" "C:\Users\Administrator\source\repos\WebApplication5" 18 #1 [internal] load build definition from Dockerfile 19 #1 sha256:6cebd8ea57035d67289d428d4ab12b9bd9f7b854cece45a6c8c5896f3e584db4 20 #1 transferring dockerfile: 768B done 21 #1 DONE 1.1s 22 23 #2 [internal] load .dockerignore 24 #2 sha256:ae3807db44f6e2063162c294384e0741768014999eb51b124c29f912625db9d3 25 #2 transferring context: 382B done 26 #2 DONE 1.4s 27 28 #3 [internal] load metadata for mcr.microsoft.com/dotnet/aspnet:5.0 29 #3 sha256:3b35130338ebb888f84ec0aa58f64d182f10a676a625072200f5903996d93690 30 #3 DONE 0.0s 31 32 #4 [base 1/2] FROM mcr.microsoft.com/dotnet/aspnet:5.0 33 #4 sha256:31acc33a1535ed7869167d21032ed94a0e9b41bbf02055dc5f04524507860176 34 #4 DONE 3.9s 35 36 #5 [base 2/2] WORKDIR /app 37 #5 sha256:56abde746b4f39a24525b2b730b2dfb6d9688bcf704d367c86a4753aefff33f6 38 #5 DONE 3.7s 39 40 #6 exporting to image 41 #6 sha256:e8c613e07b0b7ff33893b694f7759a10d42e180f2b4dc349fb57dc6b71dcab00 42 #6 exporting layers 43 #6 exporting layers 0.7s done 44 #6 writing image sha256:406f8da6d5c71bdc01379b493d135e99801857a3c4bdfc9b5898bbda0a62d8a4 0.1s done 45 #6 naming to docker.io/library/webapplication5:dev 0.1s done 46 #6 DONE 1.1s 47 C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -NoProfile -WindowStyle Hidden -ExecutionPolicy RemoteSigned -File "C:\Users\Administrator\AppData\Local\Temp\GetVsDbg.ps1" -Version vs2017u5 -RuntimeID linux-x64 -InstallPath "C:\Users\Administrator\vsdbg\vs2017u5" 48 Info: Using vsdbg version '17.0.10413.12' 49 Info: Using Runtime ID 'linux-x64' 50 Info: C:\Users\Administrator\vsdbg\vs2017u5 exists, deleting. 51 Info: Successfully installed vsdbg at 'C:\Users\Administrator\vsdbg\vs2017u5' 52 C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -NoProfile -WindowStyle Hidden -ExecutionPolicy RemoteSigned -File "C:\Users\Administrator\AppData\Local\Temp\GetVsDbg.ps1" -Version vs2017u5 -RuntimeID linux-musl-x64 -InstallPath "C:\Users\Administrator\vsdbg\vs2017u5\linux-musl-x64" 53 Info: Using vsdbg version '17.0.10413.12' 54 Info: Using Runtime ID 'linux-musl-x64' 55 Info: Successfully installed vsdbg at 'C:\Users\Administrator\vsdbg\vs2017u5\linux-musl-x64' 56 docker run -dt -v "C:\Users\Administrator\vsdbg\vs2017u5:/remote_debugger:rw" -v "C:\Users\Administrator\source\repos\WebApplication5\WebApplication5:/app" -v "C:\Users\Administrator\source\repos\WebApplication5:/src/" -v "C:\Users\Administrator\.nuget\packages\:/root/.nuget/fallbackpackages" -e "DOTNET_USE_POLLING_FILE_WATCHER=1" -e "ASPNETCORE_LOGGING__CONSOLE__DISABLECOLORS=true" -e "ASPNETCORE_ENVIRONMENT=Development" -e "NUGET_PACKAGES=/root/.nuget/fallbackpackages" -e "NUGET_FALLBACK_PACKAGES=/root/.nuget/fallbackpackages" -P --name WebApplication5 --entrypoint tail webapplication5:dev -f /dev/null 57 339a0e69705f04043b704fd4fc3a361c652c73caa95dbb1d1c14f9c4b4af596d 58 已成功啟動容器。 59 ========== 已完成 ==========
這里面檢幾個比較重要的點來說:
1、17行,通過dockerfile創建了一個鏡像
2、47行執行了GetVsDbg.ps1,這是一個powershell腳本,通過這個會在將debug工具下載到51行對應的vs2017u5這個文件夾內(重要)
3、56行,通過掛載文件的方式我們將debug工具以及nuget包通過-v的方式掛載到了鏡像內(重要)
通過以上三點即可知道一個容器環境要調試其實主要就是靠這幾點就能實現,所以不管是不是k8s,本質都是容器。現在我們來看看在k8s里我們如何實現調試的,還是以電商系統為例,我們拿accountservice作為調試目標。首先我們需要構造accountservice的調試版本的鏡像。這個鏡像其實就是一個空的aspnet鏡像,dockerfile如下:
FROM mcr.microsoft.com/dotnet/aspnet:5.0 WORKDIR /app RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone ENTRYPOINT ["dotnet", "Host.dll"]
其實主要就是增加了一個ENTRYPOINT指定鏡像啟動時調用host.dll。也就是我們accountservice的那個host。接着我們將這個dockerfile打包成鏡像:docker build . -t accountservice:debug 。然后我們將accountservice的Deployment作如下修改:
apiVersion: apps/v1 kind: Deployment metadata: name: accountservice namespace: dapreshop labels: app: accountservice spec: replicas: 1 selector: matchLabels: app: accountservice minReadySeconds: 5 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1 template: metadata: labels: app: accountservice annotations: dapr.io/enabled: "true" dapr.io/app-id: "accountservice" dapr.io/app-port: "80" dapr.io/config: "zipkin" spec: containers: - name: web image: accountservice:debug imagePullPolicy: Never ports: - containerPort: 80 volumeMounts: - mountPath: /app name: v1 - mountPath: /remote_debugger:rw name: v2 volumes: - name: v1 hostPath: path: /run/desktop/mnt/host/e/Oxygen-Dapr.EshopSample/Services/AccountService/Host/bin/Debug/net5.0 - name: v2 hostPath: path: /run/desktop/mnt/host/c/Users/Administrator/vsdbg/vs2017u5
注意紅字部分,首先我們替換了鏡像,其次我們將accountservice的host下的bin/debug下的dll掛載到了/app目錄。第三我們將vsdbg工具掛載到了容器調試工具里。這里/run/desktop/mnt/host/是指docker的wsl2映射到我系統里的路徑。因為docker for windwos在wsl2里是一個子系統,所以必須通過這個路徑來映射我們常規的cdef盤路徑。好了,現在我們將我們的解決方案右鍵重新生成一次,然后apply 一下我們的yaml文件。並再次觀察我們的pod,可以看到debug版本的accountservice已經正確的runnging了。
好了,現在我們在vs里,選擇菜單欄->調試->附加到進程,打開附加到進程窗口,連接類型選擇Docker(Linux容器),連接目標選擇查找。彈出查找框,會自動將本地計算機的容器實例展示出來,這個時候查找到我們的accountservice容器,選擇確定
tips:查找名稱的小技巧:所有k8s運行的容器都是以k8s_開頭接着是我們在deployment里申明的containers.name,然后是deployment的name。在后面就是生成pod的隨機串組成的key,這個可以不用關心。所以我們需要找到k8s_web_accountservice開頭的容器即可
tips:遠程附加小技巧:docker cli主機可以附加到遠程調試,調試和本地差不多,唯一區別就是我們需要在遠程服務器掛載調試工具和debug生成的dll,這個可以copy過去也可以通過k8s的storageclass+nfs等方式掛載到局域網共享目錄,這里就不展開了。
接着選擇這個容器后選擇我們容器內的host進程,點擊附加,調試選擇托管
接着就和普通調試沒區別了,我們打開admin.dapreshop,默認login頁面會調用/accountservice/accountquery/CheckRoleBasedAccessControler,檢查系統初始化,就打斷點在這個方法上,再刷新一下頁面,即可看到斷點命中成功了。