强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Alpine Linux 完全指南 / 第 13 章:故障排查

第 13 章:故障排查

常见问题诊断与解决方法、musl 兼容性处理和系统调试技巧。

13.1 musl 兼容性问题

常见错误及解决

错误信息原因解决方案
No such file or directory程序链接 glibc 动态链接器安装 gcompat 或重编译
Error relocating: symbol not foundglibc 专有符号安装 gcompat
Segmentation faultglibc 二进制不兼容使用容器隔离或重编译
DNS resolution failedmusl DNS 实现差异检查 resolv.conf

gcompat 兼容层

# 安装 glibc 兼容层
apk add gcompat

# 设置 glibc 链接器路径
export LD_LIBRARY_PATH=/lib64:/usr/lib64

# 验证 glibc 程序运行
ldd /path/to/glibc/binary
# 应显示 /lib64/ld-linux-x86-64.so.2

# 常见需 gcompat 的软件
# - Steam
# - 某些 Electron 应用
# - 部分商业软件
# - 某些预编译二进制

DNS 解析问题

# musl 的 DNS 解析行为与 glibc 不同
# musl 不支持 nsswitch.conf 的复杂配置

# 问题:某些程序无法解析主机名
# 解决:检查 /etc/resolv.conf
cat /etc/resolv.conf
# 确保包含有效的 nameserver

# 问题:DNS 超时
# musl 默认不支持 search 域的复杂解析
# 解决方案:
echo "options single-request-reopen" >> /etc/resolv.conf

# 问题:IPv6 DNS 解析问题
# musl 优先尝试 IPv6
# 解决:
echo "options single-request" >> /etc/resolv.conf

# DNS 调试
apk add bind-tools
dig example.com +trace
nslookup example.com 8.8.8.8

字符编码问题

# musl 的 locale 支持有限
# 默认只有 C/POSIX locale

# 安装 locale 支持
apk add musl-locales

# 设置 locale
export MUSL_LOCPATH=/usr/share/i18n/locales/musl
export LANG=zh_CN.UTF-8
export LC_ALL=zh_CN.UTF-8

# 查看可用 locale
ls /usr/share/i18n/locales/musl/

# 持久化配置
cat >> /etc/profile.d/locale.sh << 'EOF'
export MUSL_LOCPATH=/usr/share/i18n/locales/musl
export LANG=zh_CN.UTF-8
EOF

静态链接解决兼容性

# 编译静态链接的程序,避免运行时依赖

# C/C++
gcc -static -o myapp myapp.c
# 或使用 musl-gcc
musl-gcc -static -o myapp myapp.c

# Go
CGO_ENABLED=0 go build -o myapp .

# Rust
cargo build --release --target x86_64-unknown-linux-musl

# 检查静态链接
file myapp
# 应显示 "statically linked"
ldd myapp
# 应显示 "not a dynamic executable"

13.2 启动问题排查

引导失败

# 1. 从 Live CD 启动
# 2. 挂载根分区
mount /dev/sda2 /mnt
mount /dev/sda1 /mnt/boot

# 3. chroot 进入系统
chroot /mnt /bin/sh

# 4. 检查关键配置
cat /etc/fstab           # 检查文件系统配置
cat /etc/network/interfaces  # 检查网络配置
cat /etc/conf.d/*         # 检查服务配置

# 5. 检查内核和 initramfs
ls -la /boot/

# 6. 重新安装引导
extlinux --install /boot
dd if=/usr/share/syslinux/mbr.bin of=/dev/sda bs=440 count=1

# 7. 检查文件系统
fsck /dev/sda2

服务启动失败

# 查看服务状态
rc-service nginx status

# 查看服务日志
tail -100 /var/log/messages | grep nginx

# 手动启动服务查看错误
nginx -t  # 测试配置文件语法
nginx     # 前台运行查看输出

# 详细日志模式
# /etc/init.d/nginx
# 在 start 函数前添加:
# set -x

# 检查依赖
rc-service -D nginx  # 显示依赖树

# 重建服务依赖
rc-update --update

13.3 网络问题排查

网络诊断流程

# 1. 检查接口状态
ip link show
# 确保接口 UP

# 2. 检查 IP 地址
ip addr show
# 确保有正确 IP

# 3. 检查路由
ip route show
# 确保有默认路由

# 4. 测试本地连通性
ping 127.0.0.1
ping <网关IP>

# 5. 测试外网连通性
ping 8.8.8.8

# 6. 测试 DNS
nslookup example.com
dig @8.8.8.8 example.com

# 7. 测试端口连通性
nc -zv example.com 80
curl -v https://example.com

# 8. 检查防火墙规则
iptables -L -n -v
iptables -L -n -v -t nat

常见网络问题

问题可能原因解决方案
无 IP 地址DHCP 失败检查网络配置、DHCP 服务
有 IP 无网络路由/DNS 问题检查路由表和 resolv.conf
DNS 解析失败DNS 配置错误检查 /etc/resolv.conf
端口无法访问防火墙阻止检查 iptables 规则
连接超时MTU 问题降低 MTU 值

抓包分析

# 安装 tcpdump
apk add tcpdump

# 抓取 HTTP 流量
tcpdump -i eth0 -nn port 80 -A

# 抓取 DNS 查询
tcpdump -i eth0 -nn port 53

# 保存到文件分析
tcpdump -i eth0 -nn -w /tmp/capture.pcap

# 安装 Wireshark CLI
apk add tshark
tshark -r /tmp/capture.pcap

13.4 性能问题排查

CPU 问题

# 查看 CPU 使用率
top -bn1 | head -20
htop  # 需安装

# 查看每个 CPU 核心
mpstat -P ALL 1 5  # 需安装 sysstat

# 进程 CPU 使用率排序
ps aux --sort=-%cpu | head -10

# CPU 密集型进程追踪
strace -c -p <PID>  # 统计系统调用
perf top             # 性能分析(需安装)

内存问题

# 内存使用概览
free -h

# 详细内存信息
cat /proc/meminfo

# 进程内存使用排序
ps aux --sort=-%mem | head -10

# 查看进程内存映射
cat /proc/<PID>/smaps

# 内存泄漏检测
apk add valgrind
valgrind --leak-check=full ./myapp

磁盘 IO 问题

# IO 统计
iostat -x 1 5  # 需安装 sysstat

# 查看 IO 最多的进程
iotop  # 需安装 iotop

# 磁盘使用检查
df -h
du -sh /* | sort -h | tail -10

网络性能

# 带宽测试
apk add iperf3
# 服务端
iperf3 -s
# 客户端
iperf3 -c <服务端IP>

# 延迟测试
ping -c 100 <目标IP> | tail -1

# 连接数统计
ss -s
ss -tlnp | wc -l

13.5 日志分析

# 系统日志
tail -f /var/log/messages

# 认证日志
grep "Failed password" /var/log/messages
grep "Accepted publickey" /var/log/messages

# 内核日志
dmesg | tail -50
dmesg -T | grep -i error  # 带时间戳

# 服务特定日志
journalctl -u nginx  # 如果有 systemd

# 日志分析脚本
cat > /usr/local/bin/log-analyzer << 'SCRIPT'
#!/bin/sh
echo "=== 最近登录失败 ==="
grep "Failed" /var/log/messages 2>/dev/null | tail -10

echo ""
echo "=== 最近错误 ==="
grep -i "error\|critical\|fatal" /var/log/messages | tail -10

echo ""
echo "=== 磁盘空间 ==="
df -h | grep -E '^/dev' | awk '{print $5, $6}'

echo ""
echo "=== 内存使用 ==="
free -h

echo ""
echo "=== 负载 ==="
uptime
SCRIPT
chmod +x /usr/local/bin/log-analyzer

13.6 容器故障排查

# Docker 容器无法启动
docker logs <container>
docker inspect <container>

# 进入运行中的容器
docker exec -it <container> sh

# 进入已停止的容器
docker run -it --rm --entrypoint sh <image>

# 检查容器资源
docker stats <container>
docker inspect --format='{{.State.Pid}}' <container>
cat /proc/<PID>/cgroup

# 网络问题
docker network inspect <network>
docker exec <container> ping <host>
docker exec <container> cat /etc/resolv.conf

# 存储问题
docker exec <container> df -h
docker system df
docker system prune -a

13.7 包管理问题

# 错误: ERROR: unsatisfiable constraints
# 原因: 包依赖冲突
# 解决:
apk update
apk add --simulate package-name  # 预览安装
apk fix package-name  # 尝试修复

# 错误: unable to select packages
# 原因: 包名错误或不在当前仓库
apk search keyword  # 搜索正确包名
cat /etc/apk/repositories  # 检查仓库配置

# 错误: BAD signature
# 原因: 密钥过期或损坏
apk update --allow-untrusted  # 不推荐,仅调试

# 正确方式:更新密钥
apk fix --upgrade alpine-keys
apk update

# 缓存损坏
rm -rf /var/cache/apk/*
apk update

13.8 调试工具速查

工具安装命令用途
straceapk add strace系统调用追踪
ltraceapk add ltrace库函数追踪
gdbapk add gdb程序调试
ldd内置查看动态库依赖
file内置文件类型识别
readelf内置ELF 文件分析
objdumpapk add binutils二进制分析
tcpdumpapk add tcpdump网络抓包
perfapk add linux-tools性能分析
valgrindapk add valgrind内存检测

13.9 常见问题 FAQ

Q: 为什么 glibc 编译的程序在 Alpine 上运行报 “No such file or directory”? A: 程序的 ELF 解释器指向 /lib64/ld-linux-x86-64.so.2(glibc),而 Alpine 使用 /lib/ld-musl-x86_64.so.1。解决:安装 gcompat 或重新编译。

Q: 如何在 Alpine 上运行 Ubuntu 的 deb 包? A: 不推荐。应寻找 Alpine 原生包或源码编译。必要时可使用容器运行 Ubuntu 环境。

Q: Docker 中使用 Alpine 时 musl 导致的问题? A: 使用多阶段构建,在 Alpine 环境中编译程序;或使用 gcompat 包;或静态链接编译。

Q: 如何调试 OpenRC 服务? A: 使用 rc-service <name> -d start(调试模式),或直接运行服务命令查看输出。

13.10 故障排查清单

  • 确认 Alpine 版本:cat /etc/alpine-release
  • 检查系统日志:tail -100 /var/log/messages
  • 检查磁盘空间:df -h
  • 检查内存:free -h
  • 检查网络:ip addr show && ip route show
  • 检查 DNS:nslookup example.com
  • 检查防火墙:iptables -L -n
  • 检查服务状态:rc-status
  • 检查最近更新:apk version -l '<'

扩展阅读


上一章第 12 章:系统加固 下一章第 14 章:嵌入式应用