docker 代理相关问题 - 解决方案记录

1. 首先不得不吐槽一下

有时候真的要被这司马墙壁搞的红温。本来正常 docker 镜像跑一行命令就解决的事,非得浪费人精力去折腾代理方案。曾有笑话说中国程序员的网络技术功底往往远在一般人之上,此处深以为然😅

网上能搜到的 docker 代理经验很多,但是很多文章都多少存在些问题。为了减轻 mental burden,自行整理一遍各种方案。

2. docker pull 如何使用代理

曾经,使用镜像站是国内服务器拉取 docker 镜像的主流方式。不过最近因为某些不可抗力,很多大厂建立的公益镜像站都已经关闭,于是我们只能用更直接的办法,在服务器上安装代理服务来解决镜像访问的问题。

首先,关于如何在服务器上使用代理服务,可以参考《Linux 服务器使用 mihomo 代理经验》一文进行配置。

配置完毕之后,接下来参考官方文档:Configure the daemon with systemd | Docker Docs,由于 docker pull 等命令是由 dockerd 进程来执行的,在已有 socks5/http 代理的情况下,我们需要单独为 dockerd 进程配置代理,告知其需要通过代理服务器发起连接。

执行如下命令在 systemd 文件夹下创建并编辑代理配置文件:

sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf

http-proxy.conf 文件中添加如下内容

[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,docker-registry.example.com,.corp"

其中 7890 是你的 http 代理端口,NO_PROXY 可以根据自己的需要配置。配置完成后,重启 docker 服务

sudo systemctl daemon-reload
sudo systemctl restart docker

重启 docker 之后执行 sudo systemctl show --property=Environment docker 查看,如果出现如下显示就说明配置成功了。

Environment=HTTP_PROXY=http://127.0.0.1:7890/ HTTPS_PROXY=http://127.0.0.1:7890/

3. docker pull 如何使用镜像站

如果你找到了能用的镜像站,或者自建镜像站,也可以按这里的老方法给 docker pull 加载镜像站使用

3.1. 方式 1:临时使用

直接拿镜像站域名拼接上官方镜像名,使用 docker pull 命令拉取即可。例如要拉镜像 istio/distroless,可以用下面写法(不要带 https://):

docker pull docker.unsee.tech/istio/distroless

3.2. 方式 2:长久有效

创建或者修改文件 /etc/docker/daemon.json,按如下格式填入镜像站配置:

{
    "registry-mirrors": [
        "https://docker.unsee.tech",
        "https://dockerpull.org",
        "https://docker.1panel.live",
        ...
    ]
}

随后重启 docker 服务,就可以正常 pull 了:

sudo systemctl daemon-reload
sudo systemctl restart docker

4. docker build 如何使用代理

docker build 命令虽然是在 docker 所在的宿主机上执行的,看上去像是直接使用了宿主机的网络环境,但实际上 docker build 也是启动了一个 container 进行构建,所以在构建过程中的所有命令都是在 container 中执行的。因此,为 docker-daemon 设置的代理在容器中又不会生效,必须在容器中单独设置。

这里有一种比较简单的方案,可以让容器直接使用宿主机所在的网络环境和代理配置。很简单,在 build 命令上加几个参数:

docker build --build-arg http_proxy=http://127.0.0.1:7890 --build-
arg https_proxy=http://127.0.0.1:7890 --network=host ...

其中代理端口 7890 可以按需修改。这些参数的含义是,使容器使用宿主机的网络栈,并且通过–build-arg 传递 proxy 环境变量进去。这样容器内部在构建时就可以使用到宿主机的代理环境了。

5. docker 容器内如何使用代理

和前面的 docker build 方法类似,使用环境变量注入 http_proxy、https_proxy 和 all_proxy,并把对应的 http/socks5 代理端口映射进 docker 容器,或者将网络模式设置为 host 即可。

docker-compose 示例:

services:
  your-app:
    ......
    environment:
      - ...
      - http_proxy=http://127.0.0.1:7890
      - https_proxy=http://127.0.0.1:7890
      - all_proxy=socks5://127.0.0.1:7890
    ports:
      - ...
      - "7890:7890"  # 映射代理工作端口
    ......

services:
  your-app:
    ......
    network_mode: "host"
    environment:
      - ...
      - http_proxy=http://127.0.0.1:7890
      - https_proxy=http://127.0.0.1:7890
      - all_proxy=socks5://127.0.0.1:7890
    ......

docker 代理相关问题 - 解决方案记录
https://blog.openyq.top/posts/12753/
作者
yqs112358
许可协议