之前有很多同学提到如何做容器调试,特别是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. Hibernate的Dao层通用设计

    hibernate作为一款优秀的数据库持久化框架,在现实的运用中是非常广泛的.它的出现让不熟悉sql语法的程序员能开发数据库连接层成为一种可能,但是理想与现实永远是有差距的.开发过程中如果只使用hql ...

  2. Kubernetes中利用Kubectl set 让Deployment更新镜像

    问题描述 我的deployment有单个pod,我的自定义docker镜像如下: containers: - name: mycontainer image: myimage:latest 在开发过程 ...

  3. 量体裁衣方得最优解:聊聊页面静态化架构和二级CDN建设

    量体裁衣方得最优解:聊聊页面静态化架构和二级CDN建设 上期文章中我们介绍了CDN和云存储的实践,以及云生态的崛起之路,今天,我们继续聊一聊CDN. 我们通常意义上讲的CDN,更多的是针对静态资源类的 ...

  4. 显示IPC信息--ipcs

    ipcs                                       显示共享内存,消息队列, 信号量全部的IPC ipcs -q                            ...

  5. [DFS]排列的生成

    排列的生成 Time Limit:1000MS Memory Limit:65536K Total Submit:150 Accepted:95 Description 输出P(n,m)的排列(n,m ...

  6. 201871030126-王会娟 实验二 个人项目—《D{0-1} KP》项目报告

    项目 内容 课程班级博客链接 https://home.cnblogs.com/u/wanghuijuan815 这个作业要求链接 https://www.cnblogs.com/nwnu-daizh ...

  7. Day12_62_线程的生命周期

    线程的生命周期 要实现多线程,必须在主线程中创建新的线程对象. 任何线程一般都具有五种状态,即创建,就绪,运行,阻塞,终止(消亡) 新建状态:在程序中创建了一个新的线程对象后,新的线程对象便处于新建状 ...

  8. Django 模板(Template)

    1. 模板简介 2. 模板语言 DTL 3. 模板继承 4. HTML 转义 5. CSRF 1. 模板简介 作为 Web 开发框架,Django 提供了模板,可以很便利的动态生成 HTML.模版系统 ...

  9. k8s service NodePort 方式向外发布

    k8s service NodePort 方式向外发布 k8s 无头service 方式向内发布 k8s service 服务发现 {ServiceName}.{Namespace}.svc.{Clu ...

  10. 判断请求是否属于Ajax请求

    我们有时候需要根据请求类型来判断返回视图名称还是JSON数据,这里记录一个判断Ajax的工具类方便日后好找 通过传入Request对象获取头信息,根据头信息判断是否属于Ajax请求 public cl ...