网卡断开重连后如何让绑定特定IP的Docker容器自动重启?
环境信息:
uname -a
Linux srv2 6.5.0-15-generic #15~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Jan 12 18:54:30 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
docker version
Client: Docker Engine - Community
Version: 20.10.21
API version: 1.41
Go version: go1.18.7
Git commit: baeda1f
Built: Tue Oct 25 18:01:58 2022
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.21
API version: 1.41 (minimum version 1.12)
Go version: go1.18.7
Git commit: 3056208
Built: Tue Oct 25 17:59:49 2022
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.10
GitCommit: 770bd0108c32f3fb5c73ae1264f7e503fe7b2661
runc:
Version: 1.1.4
GitCommit: v1.1.4-0-g5fd4c4d
docker-init:
Version: 0.19.0
GitCommit: de40ad0
网卡重新连接后,绑定特定IP(如- "192.168.1.180:9093:9093")的Caddy容器无法自动重启,即使已设置restart: always;但绑定0.0.0.0:9093:9093时正常。docker inspect显示启动失败原因:
"State": { "Status": "exited", "Running": false, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 0, "ExitCode": 255, "Error": "driver failed programming external connectivity on endpoint caddy (60eb287b2afa0986217e10fef8def64996f9b387acfb5d050acdac0401914edc): Error starting userland proxy: listen tcp4 192.168.1.180:9093: bind: cannot assign requested address", "StartedAt": "2024-01-08T14:01:12.885988901Z", "FinishedAt": "2024-01-30T15:08:13.462577297Z" }
需通过Docker原生方案实现容器自动重启,而非cron定时检查。
1. 配置启动宽限期(start_period)
restart: always在启动阶段因绑定不可用IP失败时,Docker默认重试逻辑可能停止。添加start_period参数可指定启动宽限期,此期限内的启动失败不计入重启次数,Docker会持续重试直到IP恢复可用。
Docker Compose配置示例:
services: caddy: image: caddy:latest ports: - "192.168.1.180:9093:9093" restart: always start_period: 30s # 可根据实际场景调整时长
Docker Run命令示例:
docker run -d \ --name caddy \ -p 192.168.1.180:9093:9093 \ --restart=always \ --start-period=30s \ caddy:latest
2. 备选:使用主机网络模式(network_mode: host)
允许容器直接使用主机网络栈,跳过Docker用户态代理,避免端口绑定的代理层问题。需在Caddy配置中直接绑定目标IP,容器内服务可自行检测IP状态并重启。
Docker Compose配置示例:
services: caddy: image: caddy:latest network_mode: host restart: always # 无需ports配置,直接在Caddyfile中绑定192.168.1.180:9093
start_period告知Docker,指定时间内的启动失败属于"启动中"状态,不会终止重试。当网卡重连后IP恢复,Docker下一次重试即可成功绑定端口启动容器。- 主机网络模式牺牲了容器网络隔离性,但彻底规避了Docker代理层绑定IP的问题,让容器直接使用主机网络接口。
内容的提问来源于stack exchange,提问作者Alexander Lanin

