1. 为什么需要自动恢复Docker自定义网络?
每次宿主机重启后,最让人头疼的就是Docker自定义网络会丢失。我刚开始用Docker时也踩过这个坑——早上来公司发现服务器重启了,所有容器虽然还在,但自定义网络全没了,容器之间互相ping不通,服务完全瘫痪。这时候就得手动重建网络、重新连接容器,特别麻烦。
Docker默认的三种网络(bridge、host、none)在宿主机重启后不会丢失,但自定义网络会消失。这是因为Docker的网络配置默认存储在内存中,重启后自然就没了。对于生产环境来说,这种手动恢复的方式显然不可靠。
核心痛点在于:
- 自定义网络配置需要重新创建
- 容器需要重新连接到新创建的网络
- 依赖网络的服务需要重新启动
- 整个过程耗时且容易出错
2. 关键配置参数解析
2.1 --live-restore机制
这个参数是我解决这个问题的关键发现。在/etc/docker/daemon.json中添加:
{ "live-restore": true }或者在启动参数中加入--live-restore,它的作用是:
- 保持容器在Docker守护进程重启时继续运行
- 避免容器被意外停止
- 为网络恢复提供基础环境
实测发现,单独使用--live-restore虽然能保持容器运行,但自定义网络还是会丢失。所以需要配合其他配置。
2.2 禁用崩溃文件删除
在/etc/sysconfig/docker中添加:
DISABLE_CRASH_FILES_DELETE=true这个配置阻止Docker在崩溃时删除网络配置等关键文件。我曾在测试环境反复验证,不加这个参数的话,即使有备份文件也无法完整恢复网络状态。
3. 完整解决方案实施步骤
3.1 修改Docker守护进程配置
首先备份原始配置:
cp /etc/docker/daemon.json /etc/docker/daemon.json.bak然后编辑配置文件:
vim /etc/docker/daemon.json加入以下内容:
{ "live-restore": true, "iptables": true, "ip-forward": true, "data-root": "/var/lib/docker" }3.2 配置系统服务
对于使用systemd的系统(如CentOS 7+、Ubuntu 16.04+),需要修改docker服务配置:
sudo mkdir -p /etc/systemd/system/docker.service.d sudo vim /etc/systemd/system/docker.service.d/override.conf加入:
[Service] Restart=always StartLimitInterval=03.3 网络恢复脚本
创建网络恢复脚本/usr/local/bin/restore_docker_network.sh:
#!/bin/bash # 定义需要恢复的网络 NETWORKS=( "mybridge 172.18.0.0/16" "mybridge2 172.19.0.0/16" ) # 恢复网络 for net in "${NETWORKS[@]}"; do name=$(echo $net | awk '{print $1}') subnet=$(echo $net | awk '{print $2}') if ! docker network inspect $name &>/dev/null; then docker network create --driver bridge --subnet $subnet $name echo "已创建网络: $name" else echo "网络已存在: $name" fi done # 重新连接容器 docker network connect mybridge ganglia-s-gmond-11 docker network connect mybridge ganglia-s-gmond-12 docker network connect mybridge2 ganglia-s-gmond-21 docker network connect mybridge2 ganglia-s-gmond-22 # 重启可能受影响的容器 docker restart ganglia-s-gmond-11 ganglia-s-gmond-12 ganglia-s-gmond-21 ganglia-s-gmond-22给脚本执行权限:
chmod +x /usr/local/bin/restore_docker_network.sh3.4 设置开机自启
将脚本添加到rc.local(没有的话需要先创建):
echo "/usr/local/bin/restore_docker_network.sh" >> /etc/rc.local chmod +x /etc/rc.local对于使用systemd的系统:
cat > /etc/systemd/system/restore-docker-network.service <<EOF [Unit] Description=Restore Docker Networks After=docker.service [Service] ExecStart=/usr/local/bin/restore_docker_network.sh [Install] WantedBy=multi-user.target EOF systemctl enable restore-docker-network.service4. 验证与故障排查
4.1 手动测试恢复流程
- 主动重启Docker服务:
systemctl restart docker- 检查网络是否自动恢复:
docker network ls- 检查容器连接状态:
docker inspect ganglia-s-gmond-11 | grep IPAddress4.2 常见问题解决
问题1:网络恢复但容器IP变化
- 原因:没有指定固定IP
- 解决:创建网络时指定
--ip-range,连接容器时指定--ip
问题2:部分容器无法连接网络
- 原因:容器状态异常
- 解决:先停止再启动容器:
docker stop ganglia-s-gmond-11 && docker start ganglia-s-gmond-11问题3:脚本执行权限问题
- 现象:开机后网络未恢复
- 解决:
chmod +x /etc/rc.local chmod +x /usr/local/bin/restore_docker_network.sh5. 进阶配置建议
5.1 使用docker-compose
如果是使用docker-compose管理服务,可以在docker-compose.yml中定义网络:
version: '3' networks: mynet: driver: bridge ipam: config: - subnet: 172.20.0.0/16 services: service1: networks: mynet: ipv4_address: 172.20.0.25.2 网络配置备份
定期备份网络配置:
docker network inspect mybridge > /backup/mybridge.json恢复时可以使用:
docker network create --config /backup/mybridge.json5.3 监控网络状态
设置定时任务检查网络健康状态:
crontab -e添加:
*/5 * * * * /usr/local/bin/check_docker_network.sh检查脚本内容:
#!/bin/bash if ! docker network inspect mybridge &>/dev/null; then /usr/local/bin/restore_docker_network.sh echo "$(date): 检测到网络丢失,已自动恢复" >> /var/log/docker_network.log fi6. 生产环境注意事项
- 网络规划:提前规划好子网划分,避免IP冲突
- 变更管理:任何网络配置变更都要同步更新恢复脚本
- 日志记录:确保恢复脚本有完善的日志记录
- 测试验证:定期模拟重启测试恢复流程
- 权限控制:恢复脚本应使用最小必要权限
我在实际生产环境中实施这套方案后,宿主机重启后的恢复时间从原来的30分钟缩短到2分钟以内,最重要的是再也不需要人工干预了。特别是对于分布式系统,网络自动恢复保证了服务的高可用性。