之前有很多同學提到如何做容器除錯,特別是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的微服務電商系統(十四)——開發環境容器除錯小技巧
附錄:(如果你覺得對你有用,請給個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,檢查系統初始化,就打斷點在這個方法上,再重新整理一下頁面,即可看到斷點命中成功了。