之前有很多同学提到如何做容器调试,特别是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,检查系统初始化,就打断点在这个方法上,再刷新一下页面,即可看到断点命中成功了。

通过Dapr实现一个简单的基于.net的微服务电商系统(十四)——开发环境容器调试小技巧的更多相关文章

  1. 通过Dapr实现一个简单的基于.net的微服务电商系统(十五)——集中式接口文档实现

    之前有小伙伴在评论区留言说如何集成swagger,最开始没有想透给了对方一个似是而非的回答.实际上后来下来想了一下,用.NET5 提供的Source Generator其实可以很方便的实现接口集成.今 ...

  2. 通过Dapr实现一个简单的基于.net的微服务电商系统(十六)——dapr+sentinel中间件实现服务保护

    dapr目前更新到了1.2版本,在之前4月份的时候来自阿里的开发工程师发起了一个dapr集成Alibaba Sentinel的提案,很快被社区加入到了1.2的里程碑中并且在1.2 release 相关 ...

  3. 通过Dapr实现一个简单的基于.net的微服务电商系统(十九)——分布式事务之Saga模式

    在之前的系列文章中聊过分布式事务的一种实现方案,即通过在集群中暴露actor服务来实现分布式事务的本地原子化.但是actor服务本身有其特殊性,场景上并不通用.所以今天来讲讲分布式事务实现方案之sag ...

  4. 通过Dapr实现一个简单的基于.net的微服务电商系统(十八)——服务保护之多级缓存

    很久没有更新dapr系列了.今天带来的是一个小的组件集成,通过多级缓存框架来实现对服务的缓存保护,依旧是一个简易的演示以及对其设计原理思路的讲解,欢迎大家转发留言和star 目录:一.通过Dapr实现 ...

  5. 通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定

    如果说Actor是dapr有状态服务的内部体现的话,那绑定应该是dapr对serverless这部分的体现了.我们可以通过绑定极大的扩展应用的能力,甚至未来会成为serverless的基础.最开始接触 ...

  6. 通过Dapr实现一个简单的基于.net的微服务电商系统(十二)——istio+dapr构建多运行时服务网格

    多运行时是一个非常新的概念.在 2020 年,Bilgin Ibryam 提出了 Multi-Runtime(多运行时)的理念,对基于 Sidecar 模式的各种产品形态进行了实践总结和理论升华.那到 ...

  7. 通过Dapr实现一个简单的基于.net的微服务电商系统(十七)——服务保护之动态配置与热重载

    在上一篇文章里,我们通过注入sentinel component到apigateway实现了对下游服务的保护,不过受限于目前变更component需要人工的重新注入配置以及重启应用更新componen ...

  8. 通过Dapr实现一个简单的基于.net的微服务电商系统(二十)——Saga框架实现思路分享

    今天这篇博文的主要目的是分享一下我设计Saga的实现思路来抛砖引玉,其实Saga本身非常的类似于一个简单的工作流体系,相比工作流不一样的部分在于它没有工作流的复杂逻辑处理机制(比如会签),没有条件分支 ...

  9. 通过Dapr实现一个简单的基于.net的微服务电商系统(十一)——一步一步教你如何撸Dapr之自动扩/缩容

    上一篇我们讲到了dapr提供的bindings,通过绑定可以让我们的程序轻装上阵,在极端情况下几乎不需要集成任何sdk,仅需要通过httpclient+text.json即可完成对外部组件的调用,这样 ...

随机推荐

  1. Java(171-194)【接口、多态】

    1.接口概述与生活举例 接口就是一种公共的规范标准 只要符合规范标准,就可以大家通用 2.接口的定义基本格式  public interface 接口名称 {       // 抽象方法      / ...

  2. 解决WebStorm无法正确识别Vue3组合式API的问题

    1 问题描述 Vue3的组合式API无法在WebStorm中正确识别,表现为defineComponent等无法被识别: 2 尝试方案 猜想这种问题的原因是无法正确识别对应的Vue3库,笔者相信Web ...

  3. GO-01-GoLang的快捷键

  4. Day16_96_IO_available() 和 skip()方法

    available() 和 skip()方法 int available()方法 返回流中估计剩余字节数,int i ,i 值表示所剩余的字节数.使用read()方法读取数据,读取一个字节,avail ...

  5. Day 12_61_多线程的创建和启动(二)

    多线程的创建和启动 * 在java中实现多线程的第二种方法 实现java.lang.Runnable接口,重写run()方法 * 推荐使用这种方式,因为实现接口还可以保留类的继承. package c ...

  6. jira 改变issue状态触发jenkins构建/发布

    目录 jira中issue状态的改变触发Jenkins构建 jira中定制新的workflow,作为jenkins发布使用流程 大家可以参考我的这个workflow 设置workflow 使用Tran ...

  7. 编写shell脚本让springboot项目在CentOS中开机自启动

    springboot项目部署在CentOS系统上时,如果遇到停电关机,公司的实施人员就得跑到甲方现场重新启动项目并测试,很是麻烦,这里探讨如何编写shell脚本控制springboot项目开机时自动启 ...

  8. 老Python总结的字典相关知识

    字典 Python中的字典(dict)也被称为映射(mapping)或者散列(hash),是支持Python底层实现的重要数据结构. 同时,也是应用最为广泛的数据结构,内部采用hash存储,存储方式为 ...

  9. Summary: DOM modification techniques

    Modifying an existing element We covered various ways that you can modify aspects of an existing ele ...

  10. shopify 学习链接整理

    shopify shopify packagist https://help.shopify.com/zh-CN/manual/apps/apps-by-shopify/script-editor/s ...