docker源码阅读环境

想在mac上远程debug linux docker源码

目录
  1. 了解moby项目
  2. 环境信息
  3. 安装go
  4. 编译源码
  5. debug
  6. 总结

1、moby项目

2017 年,Docker 公司将 Docker 项目中的核心组件开源为 Moby,而 Docker 平台则作为基于这些组件的产品发布。这样子的好处是

其一:Docker 最初是一个完整的一体化平台,所有功能(如运行时、网络、存储等)都紧密耦合在一起,限制了功能的创新与更新。将 Docker 的核心功能拆解为独立的模块(如 containerdrunclibnetwork),每个组件可以独立开发、测试和发布,加速新功能的开发和测试。

其二:Docker 公司需要将更多资源投入到商业化产品(如 Docker Enterprise)中,而核心技术的开发和维护负担较重。通过 Moby 项目将核心技术交给社区维护,Docker 公司专注于构建基于 Moby 的商业产品,减轻 Docker 公司的开发和维护压力。

至于有什么模块,等后面学习的过程再继续了解,接下来先把环境弄好。

2、环境信息

本地是mac m2 air ,远程服务器是阿里云99元

linux版本信息

root@iZ7xv60bt3xh588holkr1fZ:~/moby# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 24.04 LTS
Release:        24.04
Codename:       noble

root@iZ7xv60bt3xh588holkr1fZ:~/moby# cat /proc/version
Linux version 6.8.0-40-generic (buildd@lcy02-amd64-075) (x86_64-linux-gnu-gcc-13 (Ubuntu 13.2.0-23ubuntu4) 13.2.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #40-Ubuntu SMP PREEMPT_DYNAMIC Fri Jul  5 10:34:03 UTC 2024

更新于2024.12.12
在后续的containerd源码阅读中,发现dockerd依赖了containerd,所以这环境信息缺了一部分,下面是补上的

需要先通过apt命令安装一遍docker,目的是安装containerdrunc,否则dockerd启动的时候会找不到containerd
docker版本是

Docker version 27.3.1, build ce12230

3、安装go

go官网下载安装包,选择linux版本的压缩包,版本是
https://go.dev/dl/

安装go,解压后路径为/root/go

tar -zxvf xxxxx.tar.gz

配置环境变量, vim ~/.bashrc

export GOROOT=/root/go                                                           
export GOPATH=/root/go_space                                                     
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin

4、编译源码

克隆docker源码,

github clone https://github.com/moby/moby.git

命令行运行下面的命令

# 
cd moby

#设置代理
go env -w GOPROXY=https://goproxy.cn,direct

#
go mod init

接下来,将vendor.mod中内容复制到go.mod文件中,再运行

go mod tidy
go mod vendor

4.1编译dockerd

编译dockerd程序,也就平时常说的Docker Daemon, 是Docker的核心守护进程,负责执行实际操作,例如启动、停止、删除容器。询问GPT得到以下编译命令

go build \
   -gcflags "all=-N -l" \
   -ldflags "-X github.com/docker/docker/dockerversion.Version=27.1.x \
             -X github.com/docker/docker/dockerversion.GitCommit=$(git rev-parse --short HEAD) \
             -X github.com/docker/docker/dockerversion.BuildTime=$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \
   -o ./bundles/binary-daemon/dockerd ./cmd/dockerd

该命令会编译 ./cmd/dockerd目录中的代码, 入口脚本是docker.go, 编译好的二进制文件放到./bundles/binary-daemon/目录下,名字为dockerd,其他参数说明如下:
-gcflags "all=-N -l"
-N:关闭优化,以便调试器更容易跟踪代码执行。
-l:禁止函数内联(inlining),确保所有函数都可以在调试器中完整查看。

-ldflags
版本信息的标志,便于在调试时了解当前的版本、提交信息和构建时间。

编译完成后,查看版本信息

./bundles/binary-daemon/dockerd -v

4.2编译cli

cli就是我们平时常用docker命令,cli的代码并不在moby项目中,因此需要再下一个仓库。。。

git clone https://github.com/docker/cli.git
cd cli

和前面一样

go mod init

接下来,将vendor.mod中内容复制到go.mod文件中,再运行

go mod tidy
go mod vendor

项目中提供了makefile脚本来编译cli工具

make -f docker.Makefile binary

但是这玩意会用到dockerd去构建一个docker镜像,然后在镜像实例中进行编译,所以我们要启动dockerd守护进程。由于国内的环境,要拉取镜像很麻烦,就算用了阿里云代理,你还得登录。

目前,我们此时还没有编译docker cli也就是docker 命令,pull 和 tag操作都搞不了,所以和dockerd一样,都是直接go build来编译.

再次询问GPT结果给出的编译命令是错的,只能自己找找看。

在这里插入图片描述

在scripts下找到了编译的命令,环境变量是在.variables中设置的,和dockerd一样,脚本逻辑不想看,有问题再回来看吧,先参考上面dockerd的写一个试试先

go build \
   -gcflags "all=-N -l" \
   -ldflags "-X github.com/docker/cli/cli/version.Version=27.1.x \
             -X github.com/docker/cli/cli/version.GitCommit=$(git rev-parse --short HEAD) \
             -X github.com/docker/cli/cli/version.BuildTime=$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \
   -o ./build/docker ./cmd/docker

编译完成后查看版本号

root@iZ7xv60bt3xh588holkr1fZ:~/cli# ./build/docker -v                            
Docker version 27.1.x, build 61b02e636d

启动dockerd后,执行docker info命令看看能返回dockerd的信息,返回成功
在这里插入图片描述

5、debug配置

编译的目的就是为了debug。

vscode添加配置后,能入口打上断点,但是在有些函数的时候跳不过去,估计是因为我是mac的关系,go编译器忽略了部分代码导致了500+的error,看着难受。idea一开始也有这个问题,但可以设置编译选项后就没问题了

补充说明by 2024.12.03
idea因为插件里面go版本只支持到1.21,导致仍旧有部分代码是会报错的,没办法,要换工具了
换Goland ,同样是jetbrains 的,配置差不多,就不补图了

Settings

在这里插入图片描述

go插件
在这里插入图片描述

debug配置
在这里插入图片描述

在远程主机上,随便找个目录执行下面的命令,安装dlv

go install github.com/go-delve/delve/cmd/dlv@latest

在远程主机上,moby项目根目录下,通过 Delve 启动 dockerd 并启用远程调试模式:

dlv --listen=:8005 --headless=true --api-version=2 exec ./bundles/binary-daemon/dockerd -- --debug

启动后输出

root@iZ7xv60bt3xh588holkr1fZ:~/moby# dlv --listen=:8005 --headless=true --api-version=2 exec ./bundles/binary-daemon/dockerd -- --debug
API server listening at: [::]:8005
2024-12-02T10:19:38+08:00 warning layer=rpc Listening for remote connections (connections are not authenticated nor encrypted)

docker images 命令为例,对应的请求是 /images/json
..../moby/api/server/router/image/image.go可以看到对应的处理方法是
getImagesJSON
在这里插入图片描述

打上断点后,idea启动debug, 等到命令行输出下面的内容后

...
DEBU[2024-12-02T10:41:24.032627719+08:00] Registering POST, /networks/{id:.*}/connect  
DEBU[2024-12-02T10:41:24.032857336+08:00] Registering POST, /networks/{id:.*}/disconnect 
DEBU[2024-12-02T10:41:24.033095076+08:00] Registering POST, /networks/prune      
DEBU[2024-12-02T10:41:24.033262752+08:00] Registering DELETE, /networks/{id:.*}  
INFO[2024-12-02T10:41:24.040106901+08:00] API listen on /var/run/docker.sock   ```

另开一个远程会话,在cli项目的根目录下执行
```shell
./build/docker images

看到进来了!
在这里插入图片描述

总结

他喵的,不问gpt我都不知道moby这玩意…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值