你是否曾经遇到过这样的情况:
需要调试一个没有 Shell 的容器?
或者想访问容器内部未公开的端口?
也许你只是想方便地将容器文件系统导出到本地?
如果有,那么 cdebug
就是为你量身打造的工具!
什么是 cdebug?
cdebug
是一个功能强大的容器调试工具,它就像是容器世界的瑞士军刀。无论你是在处理 Docker
容器、Kubernetes Pod
,还是其他类型的容器,cdebug
都能给你提供所需的工具和便利。
想象一下,你有一个神奇的工具箱,里面装满了各种调试工具。现在,你可以随时随地打开这个工具箱,解决容器中遇到的各种问题。这就是 cdebug
!
cdebug 能做什么?
调试 “无 Shell” 容器 : 即使容器内没有 Shell 或调试工具,你也能轻松进入并调试。
端口魔术师 : 将未公开的端口或 localhost 端口转发到你的主机系统。
反向通道 : 将主机系统的端点暴露给容器和 Kubernetes 网络。
文件系统导出专家 : 轻松将镜像或容器的文件系统导出到本地文件夹。
更多惊喜等你发现…
安装 cdebug: 简单得不能再简单!
cdebug
是一个静态链接的 Go
二进制文件,安装起来就像变魔术一样简单:
1 2 3 4 5 6 7 GOOS=linux GOARCH=amd64 $ curl -Ls https://github.com/iximiuz/cdebug/releases/latest/download/cdebug_${GOOS} _${GOARCH} .tar.gz | tar xvz $ sudo mv cdebug /usr/local /bin
如果你是 Homebrew
用户,那就更简单了:
目前支持的系统:
linux/amd64
darwin/amd64
darwin/arm64
cdebug 使用指南: 让调试变得有趣!
1. cdebug exec: 你的容器,你做主
想在一个 “瘦身” 容器中启动一个交互式 Shell? 没问题!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 $ cdebug exec -it mycontainer $ cdebug exec -it docker://mycontainer $ cdebug exec mycontainer cat /etc/os-release $ cdebug exec -it --image=alpine mycontainer $ cdebug exec -it --image=nixery.dev/shell/vim/ps/tshark mycontainer $ cdebug exec -it containerd://mycontainer ... $ cdebug exec --namespace myns -it containerd://mycontainer ... $ cdebug exec -it nerdctl://mycontainer ... $ cdebug exec -it pod/mypod $ cdebug exec -it k8s://mypod $ cdebug exec --namespace=myns -it pod/mypod $ cdebug exec -it pod/mypod/mycontainer
cdebug exec
就像是 docker exec
和 kubectl debug
的完美结合。它能让你在目标容器中启动一个调试用的 “伴侣” 容器,感觉就像是在使用 docker exec
,但功能更强大:
调试器的根文件系统就是目标容器的根文件系统。
目标容器不会被重新创建或重启。
无需额外的卷或复制调试工具。
调试工具在目标容器中随时可用。
2. cdebug port-forward: 端口转发从未如此简单
想要访问容器内部的 “隐藏” 端口? 或者将本地端口暴露给容器? cdebug port-forward
助你轻松搞定!
1 2 3 4 5 6 7 8 9 10 11 $ cdebug port-forward <target> -L 80 $ cdebug port-forward <target> -L 127.0.0.1:5432 $ cdebug port-forward <target> -L <LOCAL_HOST>:<LOCAL_PORT>:<REMOTE_HOST>:<REMOTE_PORT> $ cdebug port-forward <target> -L 8888:my.svc.cluster.local:443
3. 实战示例
示例 1: 给 “无 Shell” 容器一个温暖的家
想象你有一个基于 Distroless
的 Node.js
容器,没有 Shell
,没有调试工具,简直就是一个 “光秃秃” 的容器。别担心,cdebug
来救场!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 $ $ docker run -d --rm \ --name my-distroless gcr.io/distroless/nodejs \ -e 'setTimeout(() => console.log("Done"), 99999999)' $ cdebug exec -it my-distroless / $# ls -lah total 60K drwxr-xr-x 1 root root 4.0K Oct 17 23:49 . drwxr-xr-x 1 root root 4.0K Oct 17 23:49 .. 👉 lrwxrwxrwx 1 root root 18 Oct 17 23:49 .cdebug-c153d669 -> /proc/55/root/bin/ -rwxr-xr-x 1 root root 0 Oct 17 19:49 .dockerenv drwxr-xr-x 2 root root 4.0K Jan 1 1970 bin drwxr-xr-x 2 root root 4.0K Jan 1 1970 boot drwxr-xr-x 5 root root 340 Oct 17 19:49 dev drwxr-xr-x 1 root root 4.0K Oct 17 19:49 etc drwxr-xr-x 3 nonroot nonroot 4.0K Jan 1 1970 home drwxr-xr-x 1 root root 4.0K Jan 1 1970 lib drwxr-xr-x 2 root root 4.0K Jan 1 1970 lib64 drwxr-xr-x 5 root root 4.0K Jan 1 1970 nodejs ...
示例 2: 给你的容器加上超能力
有时候,busybox
提供的工具可能不够用。没关系,我们可以借助 nixery
项目的力量,给容器加上任何你想要的工具!
1 2 3 4 5 $ cdebug exec -it --image nixery.dev/shell/vim my-distroless $ cdebug exec -it --image nixery.dev/shell/ps/findutils/tshark my-distroless
示例 3: 调试 containerd 容器(无需 Docker)
首先,启动目标容器:
1 2 $ sudo ctr image pull docker.io/library/nginx:latest $ sudo ctr run -d docker.io/library/nginx:latest nginx-1
使用简单的 cdebug exec
在目标容器中运行交互式 Shell
:
1 2 $ sudo cdebug exec -it containerd://nginx-1 / $# wget -O- 127.0.0.1
使用 cdebug exec --image nixery.dev/shell/vim
在目标容器中运行 VIM
:
1 $ sudo cdebug exec -it --rm --image nixery.dev/shell/vim containerd://nginx-1
示例 4: 调试 nerdctl 容器(无需 Docker)
使用 nerdctl
启动容器:
1 2 $ sudo $(which nerdctl) run -d --name nginx-1 nginx 9f8763d82259a6e3e747df83d0ce8b7ee3d33d94269a72cd04e0e3862a3abc5f
使用 nerdctl://
模式和目标名称运行调试器:
1 $ sudo cdebug exec -it --rm nerdctl://nginx-1
或者使用 containerd://
模式在上述容器中运行调试会话:
1 $ sudo cdebug exec -it --rm containerd://9f876
示例 5: Kubernetes Pod 调试大师
在 Kubernetes 中调试 Pod 不再是噩梦:
首先,创建一个 Pod:
1 2 3 4 5 6 7 8 $ kubectl run --image nginx:alpine nginx-1 $ kubectl run --image=nginx:alpine nginx-1 \ --overrides='{ "apiVersion": "v1", "spec": { "containers": [{ "name": "app", "image": "nginx:alpine" }] } }' pod/nginx-1 created $ kubectl get pods NAME READY STATUS RESTARTS AGE nginx-1 1/1 Running 0 5s
然后,使用 cdebug
进入Pod:
1 2 3 4 5 6 7 8 9 10 11 12 $ cdebug exec -it pod/nginx-1 Debugger container name: cdebug-3023d11d Starting debugger container... Waiting for debugger container... Attaching to debugger container... If you don't see a command prompt, try pressing enter. / # ps auxf PID USER TIME COMMAND 1 root 0:00 sh /.cdebug-entrypoint.sh 10 root 0:00 /bin/sh -i 11 root 0:00 ps auxf
想要直接进入特定的容器? 也是没问题的!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ cdebug exec -it pod/nginx-1/app cdebug exec -it pod/nginx-1/app Debugger container name: cdebug-b44ca485 Starting debugger container... Waiting for debugger container... Attaching to debugger container... If you don't see a command prompt, try pressing enter. / # ps auxf PID USER TIME COMMAND 1 root 0:00 nginx: master process nginx -g daemon off; 30 nginx 0:00 nginx: worker process ... 41 nginx 0:00 nginx: worker process 42 root 0:00 sh /.cdebug-entrypoint.sh 51 root 0:00 /bin/ash -i 52 root 0:00 ps auxf
示例 6: 端口转发魔术
6.1 忘记发布容器端口了? cdebug 来帮忙:
1 2 3 4 5 6 7 8 $ docker run -d --name nginx-1 nginx:1.23 $ cdebug port-forward nginx-1 -L 8080:80 $ curl localhost:8080
6.2 将本地端口暴露给容器:
启动仅监听本地主机的容器化服务:
1 $ docker run -d --name svc-1 python:3-alpine python3 -m 'http.server' -b 127.0.0.1 8888
利用上述服务:
1 2 3 4 5 6 7 8 9 10 11 12 $ cdebug port-forward svc-1 -L 127.0.0.1:8888 Pulling forwarder image... latest: Pulling from shell/socat Digest: sha256:b43b6cf8d22615616b13c744b8ff525f5f6c0ca6c11b37fa3832a951ebb3c20c Status: Image is up to date for nixery.dev/shell/socat:latest Forwarding 127.0.0.1:49176 to 127.0.0.1:8888 through 172.17.0.4:34128 $ curl localhost:49176 <!DOCTYPE HTML> <html lang="en"> <head> ...
总结: 你的容器调试新伙伴
cdebug
不仅仅是一个工具,它是你在容器世界冒险时的得力助手。无论你是在调试一个顽固的容器,还是需要快速访问一个隐藏的服务,cdebug
都能帮你搞定。
记住,在容器的海洋中,cdebug
就是你的瑞士军刀。所以,下次当你面对一个看似不可能的容器调试任务时,别忘了问问自己:“我的 cdebug
在哪里?”
祝你调试愉快,容器世界的冒险家!