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 规范与标准化,这是容器技术的重要标准!