HiHuo
首页
博客
手册
工具
首页
博客
手册
工具
  • 手撸容器系统

    • 完整手撸容器技术文档系列
    • 01-容器本质与基础概念
    • 02-Namespace隔离机制
    • 03-CGroup资源控制
    • 04-Capabilities与安全机制
    • 05-容器网络原理
    • 06-网络模式与实现
    • 07-CNI插件开发
    • 08-RootFS与文件系统隔离
    • 09-OverlayFS镜像分层
    • 10-命令行手撸容器
    • 11-Go实现最小容器
    • 12-Go实现完整容器
    • 13-容器生命周期管理
    • 14-调试技术与工具
    • 15-OCI规范与标准化
    • 16-进阶场景与优化
    • 常见问题与故障排查
    • 参考资料与延伸阅读

14-调试技术与工具

学习目标

  • 掌握容器调试的核心技术和方法
  • 了解各种调试工具的使用场景
  • 能够进行容器性能分析和优化
  • 掌握容器故障排查的最佳实践
  • 理解容器安全调试技术

前置知识

  • 容器基础原理
  • Linux 系统调试
  • 网络调试基础
  • 性能分析基础

️ 一、调试工具概览

1.1 调试工具分类

graph TD
    A[容器调试工具] --> B[系统调用调试]
    A --> C[网络调试]
    A --> D[性能分析]
    A --> E[日志分析]
    A --> F[安全调试]
    
    B --> B1[strace]
    B --> B2[ltrace]
    B --> B3[gdb]
    
    C --> C1[tcpdump]
    C --> C2[wireshark]
    C --> C3[netstat]
    C --> C4[ss]
    
    D --> D1[perf]
    D --> D2[bpftrace]
    D --> D3[htop]
    D --> D4[iotop]
    
    E --> E1[journalctl]
    E --> E2[tail]
    E --> E3[grep]
    E --> E4[awk]
    
    F --> F1[auditd]
    F --> F2[seccomp]
    F --> F3[capsh]

1.2 调试工具选择

工具类型推荐工具使用场景
系统调用strace, ltrace调试程序行为
网络tcpdump, wireshark网络问题排查
性能perf, bpftrace性能瓶颈分析
日志journalctl, tail日志分析
安全auditd, seccomp安全审计

二、系统调用调试

2.1 strace 使用

2.1.1 基础用法

# 1. 跟踪系统调用
strace -o trace.log ./container

# 2. 跟踪特定系统调用
strace -e trace=open,read,write ./container

# 3. 跟踪网络相关系统调用
strace -e trace=network ./container

# 4. 跟踪文件操作
strace -e trace=file ./container

# 5. 跟踪进程创建
strace -e trace=process ./container

2.1.2 高级用法

# 1. 跟踪子进程
strace -f -o trace.log ./container

# 2. 跟踪特定进程
strace -p <PID> -o trace.log

# 3. 跟踪特定用户
strace -u <username> ./container

# 4. 跟踪特定时间
strace -t -o trace.log ./container

# 5. 跟踪系统调用时间
strace -T -o trace.log ./container

2.1.3 容器调试示例

#!/bin/bash
# 使用 strace 调试容器

echo "=== 使用 strace 调试容器 ==="

# 1. 跟踪容器启动过程
echo "1. 跟踪容器启动过程..."
strace -f -e trace=clone,execve,chroot,pivot_root \
  -o container_start.log \
  ./container -rootfs /tmp/rootfs -cmd /bin/sh

# 2. 跟踪网络操作
echo "2. 跟踪网络操作..."
strace -f -e trace=network \
  -o container_network.log \
  ./container -rootfs /tmp/rootfs -cmd /bin/ping -args "8.8.8.8"

# 3. 跟踪文件操作
echo "3. 跟踪文件操作..."
strace -f -e trace=file \
  -o container_file.log \
  ./container -rootfs /tmp/rootfs -cmd /bin/ls -args "-la /"

# 4. 分析系统调用
echo "4. 分析系统调用..."
echo "=== 系统调用统计 ==="
strace -c -f ./container -rootfs /tmp/rootfs -cmd /bin/sh

echo "=== 最频繁的系统调用 ==="
awk '{print $2}' container_start.log | sort | uniq -c | sort -nr | head -10

2.2 ltrace 使用

# 1. 跟踪库函数调用
ltrace -o libtrace.log ./container

# 2. 跟踪特定库函数
ltrace -e malloc,free ./container

# 3. 跟踪网络库函数
ltrace -e connect,send,recv ./container

# 4. 跟踪文件库函数
ltrace -e fopen,fread,fwrite ./container

2.3 gdb 调试

# 1. 启动 gdb
gdb ./container

# 2. 设置断点
(gdb) break main
(gdb) break setupContainer

# 3. 运行程序
(gdb) run -rootfs /tmp/rootfs -cmd /bin/sh

# 4. 查看变量
(gdb) print containerID
(gdb) print rootfs

# 5. 单步执行
(gdb) next
(gdb) step

# 6. 查看调用栈
(gdb) backtrace

# 7. 查看内存
(gdb) x/10x $rsp

三、网络调试

3.1 tcpdump 使用

3.1.1 基础用法

# 1. 抓取所有网络包
tcpdump -i any -n

# 2. 抓取特定接口
tcpdump -i eth0 -n

# 3. 抓取特定协议
tcpdump -i any -n icmp
tcpdump -i any -n tcp
tcpdump -i any -n udp

# 4. 抓取特定端口
tcpdump -i any -n port 80
tcpdump -i any -n port 8080

# 5. 抓取特定主机
tcpdump -i any -n host 8.8.8.8

3.1.2 容器网络调试

#!/bin/bash
# 使用 tcpdump 调试容器网络

echo "=== 使用 tcpdump 调试容器网络 ==="

# 1. 抓取容器网络包
echo "1. 抓取容器网络包..."
tcpdump -i cni0 -n -w container_network.pcap &
TCPDUMP_PID=$!

# 2. 启动容器
echo "2. 启动容器..."
./container -rootfs /tmp/rootfs -cmd /bin/ping -args "8.8.8.8"

# 3. 停止抓包
kill $TCPDUMP_PID

# 4. 分析网络包
echo "3. 分析网络包..."
tcpdump -r container_network.pcap -n

# 5. 抓取特定容器流量
echo "4. 抓取特定容器流量..."
tcpdump -i veth-123456 -n -w container_specific.pcap &
TCPDUMP_PID=$!

./container -rootfs /tmp/rootfs -cmd /bin/curl -args "http://example.com"
kill $TCPDUMP_PID

# 6. 分析 HTTP 流量
echo "5. 分析 HTTP 流量..."
tcpdump -r container_specific.pcap -A -s 0 | grep -E "(GET|POST|HTTP)"

3.2 wireshark 使用

# 1. 打开 pcap 文件
wireshark container_network.pcap

# 2. 实时抓包
wireshark -i cni0

# 3. 过滤特定流量
# 在 wireshark 中使用过滤器:
# ip.addr == 10.22.0.2
# tcp.port == 80
# http.request.method == GET

3.3 网络状态检查

#!/bin/bash
# 检查容器网络状态

echo "=== 检查容器网络状态 ==="

# 1. 检查网络接口
echo "1. 网络接口状态:"
ip link show
echo ""

# 2. 检查 Bridge 状态
echo "2. Bridge 状态:"
brctl show cni0
echo ""

# 3. 检查路由表
echo "3. 路由表:"
ip route show
echo ""

# 4. 检查 ARP 表
echo "4. ARP 表:"
ip neigh show
echo ""

# 5. 检查 iptables 规则
echo "5. iptables 规则:"
iptables -t nat -L -n
iptables -t filter -L -n
echo ""

# 6. 检查端口监听
echo "6. 端口监听:"
netstat -tlnp
ss -tlnp
echo ""

# 7. 检查网络统计
echo "7. 网络统计:"
cat /proc/net/dev
cat /proc/net/snmp

四、性能分析

4.1 perf 使用

4.1.1 基础用法

# 1. 记录性能数据
perf record -g ./container

# 2. 查看性能报告
perf report

# 3. 查看调用图
perf report -g graph

# 4. 查看特定函数
perf report --stdio -s symbol

# 5. 实时监控
perf top

4.1.2 容器性能分析

#!/bin/bash
# 使用 perf 分析容器性能

echo "=== 使用 perf 分析容器性能 ==="

# 1. 记录容器启动性能
echo "1. 记录容器启动性能..."
perf record -g -o container_start.data ./container -rootfs /tmp/rootfs -cmd /bin/sh

# 2. 分析启动性能
echo "2. 分析启动性能..."
perf report -i container_start.data

# 3. 记录容器运行性能
echo "3. 记录容器运行性能..."
perf record -g -p $(pgrep container) -o container_runtime.data sleep 10

# 4. 分析运行性能
echo "4. 分析运行性能..."
perf report -i container_runtime.data

# 5. 记录系统调用性能
echo "5. 记录系统调用性能..."
perf record -e syscalls:sys_enter_* -o container_syscalls.data ./container -rootfs /tmp/rootfs -cmd /bin/ls

# 6. 分析系统调用性能
echo "6. 分析系统调用性能..."
perf report -i container_syscalls.data

4.2 bpftrace 使用

# 1. 跟踪系统调用
bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args->filename)); }'

# 2. 跟踪网络事件
bpftrace -e 'kprobe:tcp_connect { printf("TCP connect: %s\n", comm); }'

# 3. 跟踪文件操作
bpftrace -e 'tracepoint:syscalls:sys_enter_read { printf("Read: %s %d\n", comm, args->count); }'

# 4. 跟踪容器事件
bpftrace -e 'kprobe:copy_process { printf("Process created: %s\n", comm); }'

4.3 系统监控

#!/bin/bash
# 系统监控脚本

echo "=== 系统监控 ==="

# 1. CPU 使用率
echo "1. CPU 使用率:"
top -bn1 | grep "Cpu(s)"
echo ""

# 2. 内存使用率
echo "2. 内存使用率:"
free -h
echo ""

# 3. 磁盘使用率
echo "3. 磁盘使用率:"
df -h
echo ""

# 4. 网络统计
echo "4. 网络统计:"
cat /proc/net/dev
echo ""

# 5. 进程统计
echo "5. 进程统计:"
ps aux --sort=-%cpu | head -10
echo ""

# 6. 容器统计
echo "6. 容器统计:"
docker stats --no-stream
echo ""

五、日志分析

5.1 日志收集

#!/bin/bash
# 日志收集脚本

echo "=== 日志收集 ==="

# 1. 收集系统日志
echo "1. 收集系统日志..."
journalctl -u docker --since "1 hour ago" > system.log

# 2. 收集容器日志
echo "2. 收集容器日志..."
docker logs container-123 > container.log

# 3. 收集网络日志
echo "3. 收集网络日志..."
dmesg | grep -i network > network.log

# 4. 收集性能日志
echo "4. 收集性能日志..."
sar -u 1 60 > cpu.log
sar -r 1 60 > memory.log
sar -n DEV 1 60 > network_stats.log

# 5. 收集错误日志
echo "5. 收集错误日志..."
journalctl -p err --since "1 hour ago" > errors.log

5.2 日志分析

#!/bin/bash
# 日志分析脚本

echo "=== 日志分析 ==="

# 1. 分析错误日志
echo "1. 分析错误日志..."
grep -i error system.log | head -10
echo ""

# 2. 分析网络日志
echo "2. 分析网络日志..."
grep -i "connection refused" network.log | wc -l
echo ""

# 3. 分析性能日志
echo "3. 分析性能日志..."
awk '{sum+=$3} END {print "Average CPU usage:", sum/NR "%"}' cpu.log
echo ""

# 4. 分析容器日志
echo "4. 分析容器日志..."
grep -i "container" container.log | head -10
echo ""

# 5. 分析时间序列
echo "5. 分析时间序列..."
awk '{print $1, $2, $3}' cpu.log | head -10
echo ""

5.3 日志监控

#!/bin/bash
# 日志监控脚本

echo "=== 日志监控 ==="

# 1. 实时监控系统日志
echo "1. 实时监控系统日志..."
journalctl -f -u docker &

# 2. 实时监控容器日志
echo "2. 实时监控容器日志..."
docker logs -f container-123 &

# 3. 实时监控网络日志
echo "3. 实时监控网络日志..."
tail -f /var/log/syslog | grep -i network &

# 4. 实时监控错误日志
echo "4. 实时监控错误日志..."
tail -f /var/log/syslog | grep -i error &

# 5. 实时监控性能日志
echo "5. 实时监控性能日志..."
top -d 1 &

六、安全调试

6.1 安全审计

#!/bin/bash
# 安全审计脚本

echo "=== 安全审计 ==="

# 1. 检查容器权限
echo "1. 检查容器权限..."
docker inspect container-123 | jq '.[0].HostConfig.Privileged'
echo ""

# 2. 检查容器能力
echo "2. 检查容器能力..."
docker inspect container-123 | jq '.[0].HostConfig.CapAdd'
echo ""

# 3. 检查容器用户
echo "3. 检查容器用户..."
docker inspect container-123 | jq '.[0].Config.User'
echo ""

# 4. 检查容器挂载
echo "4. 检查容器挂载..."
docker inspect container-123 | jq '.[0].Mounts'
echo ""

# 5. 检查容器网络
echo "5. 检查容器网络..."
docker inspect container-123 | jq '.[0].NetworkSettings'
echo ""

6.2 安全监控

#!/bin/bash
# 安全监控脚本

echo "=== 安全监控 ==="

# 1. 监控文件访问
echo "1. 监控文件访问..."
auditctl -w /etc/passwd -p rwxa -k passwd_access
auditctl -w /etc/shadow -p rwxa -k shadow_access

# 2. 监控网络访问
echo "2. 监控网络访问..."
auditctl -w /bin/netstat -p x -k network_tools
auditctl -w /bin/ss -p x -k network_tools

# 3. 监控进程创建
echo "3. 监控进程创建..."
auditctl -w /bin/docker -p x -k docker_commands
auditctl -w /bin/container -p x -k container_commands

# 4. 查看审计日志
echo "4. 查看审计日志..."
ausearch -k passwd_access
ausearch -k shadow_access
ausearch -k network_tools
ausearch -k docker_commands
ausearch -k container_commands

6.3 安全分析

#!/bin/bash
# 安全分析脚本

echo "=== 安全分析 ==="

# 1. 分析容器逃逸
echo "1. 分析容器逃逸..."
grep -i "container" /var/log/audit/audit.log | grep -i "escape"
echo ""

# 2. 分析权限提升
echo "2. 分析权限提升..."
grep -i "privilege" /var/log/audit/audit.log | grep -i "escalation"
echo ""

# 3. 分析网络攻击
echo "3. 分析网络攻击..."
grep -i "attack" /var/log/audit/audit.log | grep -i "network"
echo ""

# 4. 分析文件访问
echo "4. 分析文件访问..."
grep -i "file" /var/log/audit/audit.log | grep -i "access"
echo ""

# 5. 分析进程创建
echo "5. 分析进程创建..."
grep -i "process" /var/log/audit/audit.log | grep -i "create"
echo ""

七、调试实践

7.1 容器启动问题

#!/bin/bash
# 调试容器启动问题

echo "=== 调试容器启动问题 ==="

# 1. 检查 rootfs
echo "1. 检查 rootfs..."
ls -la /tmp/rootfs/
echo ""

# 2. 检查权限
echo "2. 检查权限..."
ls -la /tmp/rootfs/bin/
echo ""

# 3. 检查依赖
echo "3. 检查依赖..."
ldd /tmp/rootfs/bin/sh
echo ""

# 4. 检查命名空间
echo "4. 检查命名空间..."
ls -la /proc/self/ns/
echo ""

# 5. 检查 cgroup
echo "5. 检查 cgroup..."
ls -la /sys/fs/cgroup/
echo ""

# 6. 使用 strace 调试
echo "6. 使用 strace 调试..."
strace -f -e trace=clone,execve,chroot,pivot_root \
  -o debug.log \
  ./container -rootfs /tmp/rootfs -cmd /bin/sh

# 7. 分析调试日志
echo "7. 分析调试日志..."
grep -i error debug.log
grep -i "no such file" debug.log
grep -i "permission denied" debug.log

7.2 网络连接问题

#!/bin/bash
# 调试网络连接问题

echo "=== 调试网络连接问题 ==="

# 1. 检查网络接口
echo "1. 检查网络接口..."
ip link show
echo ""

# 2. 检查 Bridge 状态
echo "2. 检查 Bridge 状态..."
brctl show cni0
echo ""

# 3. 检查路由表
echo "3. 检查路由表..."
ip route show
echo ""

# 4. 检查 ARP 表
echo "4. 检查 ARP 表..."
ip neigh show
echo ""

# 5. 检查 iptables 规则
echo "5. 检查 iptables 规则..."
iptables -t nat -L -n
iptables -t filter -L -n
echo ""

# 6. 使用 tcpdump 调试
echo "6. 使用 tcpdump 调试..."
tcpdump -i cni0 -n -w network_debug.pcap &
TCPDUMP_PID=$!

# 7. 测试网络连接
echo "7. 测试网络连接..."
./container -rootfs /tmp/rootfs -cmd /bin/ping -args "8.8.8.8"

# 8. 停止抓包
kill $TCPDUMP_PID

# 9. 分析网络包
echo "9. 分析网络包..."
tcpdump -r network_debug.pcap -n

7.3 性能问题

#!/bin/bash
# 调试性能问题

echo "=== 调试性能问题 ==="

# 1. 检查系统资源
echo "1. 检查系统资源..."
top -bn1 | head -5
free -h
df -h
echo ""

# 2. 检查容器资源使用
echo "2. 检查容器资源使用..."
docker stats --no-stream
echo ""

# 3. 使用 perf 分析
echo "3. 使用 perf 分析..."
perf record -g -o performance.data ./container -rootfs /tmp/rootfs -cmd /bin/sh
perf report -i performance.data
echo ""

# 4. 使用 bpftrace 分析
echo "4. 使用 bpftrace 分析..."
bpftrace -e 'tracepoint:syscalls:sys_enter_* { @[probe] = count(); }' &
BPFTRACE_PID=$!
sleep 10
kill $BPFTRACE_PID
echo ""

# 5. 检查系统调用
echo "5. 检查系统调用..."
strace -c -f ./container -rootfs /tmp/rootfs -cmd /bin/ls
echo ""

八、验证检查清单

基础调试

  • [ ] 能够使用 strace 调试系统调用
  • [ ] 能够使用 tcpdump 调试网络问题
  • [ ] 能够使用 perf 分析性能问题
  • [ ] 能够分析容器日志

高级调试

  • [ ] 能够使用 gdb 调试程序
  • [ ] 能够使用 bpftrace 分析内核事件
  • [ ] 能够进行安全审计
  • [ ] 能够进行性能优化

故障排查

  • [ ] 能够排查容器启动问题
  • [ ] 能够排查网络连接问题
  • [ ] 能够排查性能问题
  • [ ] 能够排查安全问题

相关链接

  • 13-容器生命周期管理 - 生命周期管理
  • 15-OCI规范与标准化 - 标准化实现
  • 16-进阶场景与优化 - 进阶应用

下一步:让我们学习 OCI 规范与标准化,这是容器技术的重要标准!

Prev
13-容器生命周期管理
Next
15-OCI规范与标准化