第一种方式修改http-proxy.conf文件
用 systemd drop-in 给 Docker 服务加环境变量(只影响 daemon 自己访问 registry,不会自动注入容器)
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf >/dev/null <<'EOF'
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.1,::1"
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
验证
sudo systemctl show docker | grep -i proxy
# 或
docker info 2>/dev/null | grep -A3 -i proxy
拉镜像测试(应能走代理拉取成功)
docker pull busybox
第二种方式修改daemon.json(不推荐)
备份当前配置
sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.broken.$(date +%F_%T)
写入新配置
sudo tee /etc/docker/daemon.json >/dev/null <<'EOF'
{
"iptables": false,
"proxies": {
"http-proxy": "http://192.168.31.45:7890",
"https-proxy": "http://192.168.31.45:7890",
"no-proxy": "localhost,127.0.0.1,172.17.0.0/16"
}
}
EOF
验证JSON语法(可选)
python3 - <<'PY'
import json,sys;json.load(open("/etc/docker/daemon.json"));print("JSON OK")
PY
重启 Docker(并清掉重复失败计数)
sudo systemctl daemon-reload # 让 systemd 重新加载所有 unit 定义和 drop-in 覆盖(比如你新建的 /etc/systemd/system/docker.service.d/http-proxy.conf
sudo systemctl reset-failed docker # 把 docker.service 的 失败计数/失败状态 清零
sudo systemctl restart docker # 重启 Docker 守护进程,让新配置(比如代理环境变量)真正生效。
sudo journalctl -u docker.service -n 200 --no-pager # 查看 docker.service 的最近 200 行日志,--no-pager 表示直接全部输出,不用分页器。
验证
docker info 2>/dev/null | grep -A3 -i proxy
docker pull busybox # 镜像拉取测试
其它配置
iptables: true
且 userland-proxy: false
(我推荐)
只走内核的 NAT(DNAT)路径,不再起任何 docker-proxy 进程。对外发布端口照样可用,监听者变成内核 + iptables,不会有多出来的监听进程;行为更“干净”、更可预期,和防火墙联动(在 DOCKER-USER
链管控)也更直观。
sudo tee /etc/docker/daemon.json >/dev/null <<'EOF'
{
"iptables": true,
"userland-proxy": false
}
EOF
# 先确保已建立连接放行(官方推荐 DOCKER-USER 开头就有)
sudo iptables -C DOCKER-USER -m state --state RELATED,ESTABLISHED -j ACCEPT || \
sudo iptables -I DOCKER-USER -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo ip6tables -C DOCKER-USER -m state --state RELATED,ESTABLISHED -j ACCEPT || \
sudo ip6tables -I DOCKER-USER -m state --state RELATED,ESTABLISHED -j ACCEPT
# 拦 TCP 7369(IPv4+IPv6)
sudo iptables -I DOCKER-USER -p tcp --dport 7369 -j DROP
sudo ip6tables -I DOCKER-USER -p tcp --dport 7369 -j DROP
# 如需同时拦 UDP(可选)
sudo iptables -I DOCKER-USER -p udp --dport 7369 -j DROP
sudo ip6tables -I DOCKER-USER -p udp --dport 7369 -j DROP
# 放行 7369(恢复访问)
# TCP
sudo iptables -D DOCKER-USER -p tcp --dport 7369 -j DROP
sudo ip6tables -D DOCKER-USER -p tcp --dport 7369 -j DROP
# 如果之前加过 UDP
sudo iptables -D DOCKER-USER -p udp --dport 7369 -j DROP
sudo ip6tables -D DOCKER-USER -p udp --dport 7369 -j DROP
# 只允许某来源访问(白名单)
# 先放通已建立连接(同 A 段)
sudo iptables -C DOCKER-USER -m state --state RELATED,ESTABLISHED -j ACCEPT || \
sudo iptables -I DOCKER-USER -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo ip6tables -C DOCKER-USER -m state --state RELATED,ESTABLISHED -j ACCEPT || \
sudo ip6tables -I DOCKER-USER -m state --state RELATED,ESTABLISHED -j ACCEPT
# 先删掉之前可能存在的“全拒”规则,避免冲突(没有的话会报错,忽略即可)
sudo iptables -D DOCKER-USER -p tcp --dport 7369 -j DROP 2>/dev/null || true
sudo ip6tables -D DOCKER-USER -p tcp --dport 7369 -j DROP 2>/dev/null || true
# 白名单:非 203.0.113.8 的流量一律拒绝(IPv4)
sudo iptables -I DOCKER-USER -p tcp --dport 7369 ! -s 203.0.113.8 -j DROP
# 如需 IPv6 白名单,替换成你的 IPv6 地址
# sudo ip6tables -I DOCKER-USER -p tcp --dport 7369 ! -s 2001:db8::1234 -j DROP