当了解一些大型项目的代码逻辑时,如kubernetes,跟着调试器跟踪代码学习,是很好的方式。当项目部署在远程环境时,在本机进行开发,很自然对Remote Debug有迫切需求,这也是和调试一般golang程序最主要的诉求区别点,本文将通过两个实际例子,来介绍如何Remote Debug。
dlv远程调试的原理
vscode支持丰富的插件,dlv插件可以帮助我们调试golang代码,基本使用方法详见 delve官网,以及我之前的一篇文档通过delve(dlv)调试golang程序。dlv远程调试的基本原理是,在服务端启动dlv server,客户端vscode去连接dlv server
远程调试的步骤
主要参考了Debugging Go code using VS Code,现将步骤整理如下:
环境安装
Local安装Golang
参考Golang官网安装步骤Getting Started
Local和Remote端安装dlv工具
1 | go get -u github.com/go-delve/delve/cmd/dlv |
本地代码版本切换到和目标端一致
以一个服务uhost-scheduler为例, 线上和本地都保持为1.0.10版本
1 | [root@yg-man-uhost-set9-01 bin]# /data/uframework/uhost_server -v |
##在Remote端启动dlv server
启动命令如下
1 | dlv --listen=":50000" --headless=true --log --api-version=2 exec /data/uframework/uhost_server \ |
参数说明:
- -l, –listen string Debugging server listen address. (default “127.0.0.1:0”)
- –headless Run debug server only, in headless mode.
- –log Enable debugging server logging.
更多参数说明详见dlv
在Local端的调试
dlv命令行的调试
访问dlv server的IP:Port,可以调试,类似于gdb
1 | ➜ ~ dlv connect 172.23.0.159:50000 |
在VS Code里的调试
但命令行里,没有图形界面直观和方便,所以更推荐在VS Code里的调试
- 保持VS Code打开的代码,和Remote端的代码或二进制包一致
- 在本地主机中配置远程调试的参数,会在当前项目下的.vscode目录产生一个launch.json文件
- 配置Remote端的IP和Port
1 | { |
- 运行Debug,可以像本地一样调试,如加断点、条件断点、单步调试等。
本地VS Code界面
Remote端页面
Remote-Debug-Go-Code-with-Visual-Studio-Code.md
条件断点
k8s scheduler的远程调试
k8s里有很多单独的服务,如kube-apiserver、kube-proxy、kube-scheduler等,每个都可以作为单独的调试代码。最近在看kube-scheduler的代码,所以这里以它为例。
k8s环境的搭建
k8s环境通过kubeadm搭建在远程的4台虚机上,1台master和3台node,具体的搭建步骤见kubeadm部署single control-plane k8s集群。
停止kube-scheduler服务
我们需要dlv拉起kube-scheduler服务,但是kubeadm部署的kube-scheduler被kill掉后
,会自动拉起来,占用10251的端口,影响调试。
这里对对配置文件改名,防止自动拉起kube-schedulermv /etc/kubernetes/scheduler.conf /etc/kubernetes/scheduler_191223.conf
dlv server
dlv server启动后,监听40000端口
1 | dlv --listen=":40000" --headless=true --log --api-version=2 exec /data/k8s/kube-scheduler \ |
注意:本地是从公网访问虚机的40000端口,如果防火墙有打开的话,要关掉。
本地调试kube-scheduler
与之前步骤一样
- 代码与线上一致;如果不一致,重新编译新的版本推到线上,重新拉起服务
1 | ➜ kube-scheduler git:(b3cbbae) ✗ pwd |
- 配置文件launch.json的内容
1 | { |
3.运行Debug,这时可以像可以像本地一样调试,如加断点、单步调试等。
本地VS Code远程调试kube-scheduler界面
Remote端kube-scheduler输出,看到打断点和调试的日志
后面就是结合创建pod,去分析具体的调度逻辑了。