第一种方式修改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: trueuserland-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