nsenter 调试

nsenter 调试

什么是 nsenter

nsenter 是一个 Linux 工具,可以进入进程的命名空间(Namespace)。利用它可以无需在容器内安装任何工具就能进行调试。

为什么用 nsenter

传统调试方式需要在容器内安装工具(如 curl、netstat、tcpdump),但生产容器通常最小化安装,没有这些工具。nsenter 可以在宿主机上进入容器的命名空间。

基本用法

获取容器的 PID

# 方法一
PID=$(docker inspect  -f '{{.State.Pid}}')
echo $PID

# 方法二
PID=$(docker container ls --no-trunc | grep  | awk '{print $1}')

进入容器的命名空间

# 进入所有命名空间
nsenter -t $PID -a /bin/bash

# 只进入 mount 命名空间
nsenter -t $PID -m /bin/bash

# 只进入网络命名空间
nsenter -t $PID -n /bin/bash

# 只进入 PID 命名空间
nsenter -t $PID -p /bin/bash

# 只进入 UTC 命名空间
nsenter -t $PID -u /bin/bash

# 只进入 IPC 命名空间
nsenter -t $PID -i /bin/bash

调试场景

场景一:在容器内使用宿主机网络工具

# 进入容器网络命名空间,使用宿主机的 curl
PID=$(docker inspect myapp -f '{{.State.Pid}}')
nsenter -t $PID -n curl http://localhost:8080/health
nsenter -t $PID -n ping google.com
nsenter -t $PID -n ss -tulpn
nsenter -t $PID -n tcpdump -i eth0

场景二:查看容器文件系统

# 进入容器的 mount 命名空间
PID=$(docker inspect myapp -f '{{.State.Pid}}')
nsenter -t $PID -m -u -i /bin/sh

# 查看容器内的进程
# 注意:此时是在容器的文件系统中
ls /app
cat /etc/nginx/nginx.conf

场景三:调试网络连通性

#!/bin/bash
# test_container_network.sh

CONTAINER=$1
TARGET=$2

if [ -z "$CONTAINER" ] || [ -z "$TARGET" ]; then
  echo "Usage: $0  "
  exit 1
fi

PID=$(docker inspect $CONTAINER -f '{{.State.Pid}}')

echo "Testing network from $CONTAINER to $TARGET..."

# DNS 解析
nsenter -t $PID -n nslookup $TARGET 2>/dev/null || \
  nsenter -t $PID -n getent hosts $TARGET

# Ping
nsenter -t $PID -n ping -c 2 $TARGET

# 端口测试
nsenter -t $PID -n nc -zv $TARGET 80

场景四:查看容器内日志

# 如果应用日志不在 stdout
PID=$(docker inspect myapp -f '{{.State.Pid}}')
nsenter -t $PID -m -u tail -f /var/log/app.log

实用技巧

一键进入容器命名空间

# 添加到 ~/.bashrc
function docker-enter() {
  PID=$(docker inspect "$1" -f '{{.State.Pid}}')
  if [ -z "$PID" ]; then
    echo "Container not found: $1"
    return 1
  fi
  nsenter -t $PID -a /bin/bash
}

# 使用
docker-enter myapp

查看容器资源使用

PID=$(docker inspect myapp -f '{{.State.Pid}}')

# CPU
nsenter -t $PID -p top -b -n 1

# 内存
nsenter -t $PID -p cat /proc/1/status | grep -E "VmRSS|VmSize"

# 文件描述符
nsenter -t $PID -p ls -la /proc/1/fd/

捕获网络流量

# 在宿主机上监听容器的网络流量
PID=$(docker inspect myapp -f '{{.State.Pid}}')

# 使用 tcpdump
nsenter -t $PID -n tcpdump -i eth0 -w /tmp/capture.pcap

# 分析
tcpdump -r /tmp/capture.pcap

nsenter vs docker exec

特性 nsenter docker exec
需要容器内工具 不需要 需要 bash/sh
权限 root 用户 容器用户
资源访问 宿主机视角 容器视角
依赖 Linux 内核 Docker CLI
适用场景 高级调试 日常操作

注意事项

# nsenter 需要 root 权限
sudo nsenter -t $PID -a /bin/bash

# 修改文件时注意:nsenter 使用宿主机的编辑器
# 保存后会覆盖容器内的文件

# 进程树:在 nsenter 中 kill 进程要小心

面试要点

  1. nsenter 进入容器的命名空间,可以在容器内使用宿主机上的调试工具
  2. 不需要容器内有 shell 或任何工具——对最小化容器特别有用
  3. 网络命名空间调试:nsenter -t $PID -n curl/ping/tcpdump
  4. 比 docker exec 更底层,适合”容器太精简无法调试”的场景
  5. 需要 root 权限运行

面试官常问:nsenter 和 docker exec 有什么区别?最小化镜像(scratch/alpine)怎么调试?

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容