在日常使用 Docker 的过程中,我们可能会遇到需要通过代理服务器来进行网络通信的情况。例如,在构建 Docker 镜像、运行容器或者下载 Docker 镜像时,可能需要配置代理以访问外部网络。下面我们将详细介绍在这三种情况下如何配置代理。

  1. 构建镜像 docker build 的时候,使用 --build-arg 参数配置代理
  2. Docker 容器运行的时候,需要设置宿主机 docker 的 config.json 文件来设置代理。
  3. 下载镜像 docker pull 的时候,使用的 Docker 服务的环境变量来设置 dockerd 进程的代理。

1. 构建镜像 docker build

构建镜像的时候跟别的环境都是隔离的,所以要通过命令行参数 --build-arg 来传递代理配置给 docker build 命令。

1
2
3
4
5
docker build . \
--build-arg "HTTP_PROXY=http://proxy.example.com:7890" \
--build-arg "HTTPS_PROXY=http://proxy.example.com:7890" \
--build-arg "NO_PROXY=localhost,127.0.0.1,.example.com" \
-t image-name

注意把 proxy.example.com 和端口替换成你自己的代理服务器地址,-t 是设置镜像的名称,跟配置代理没关系,这个大家应该都知道。至于这里可不可以使用 127.0.0.1 本地代理,我感觉是不能的,还是使用公网 IP 最稳,不过我也没测试,欢迎有尝试过的同学在评论区留言指正。

如果你希望这些代理设置在容器运行时仍然有效,可以在 Dockerfile 中使用 ARG 和 ENV 指令来保持这些设置:

1
2
3
4
5
6
7
8
9
10
FROM ubuntu:latest

# 接收 build-arg 参数
ARG HTTP_PROXY
ARG HTTPS_PROXY

# 设置运行时环境变量
ENV http_proxy $HTTP_PROXY
ENV https_proxy $HTTPS_PROXY
...

2. 容器运行时容器内部的代理

在创建容器时,我们可以通过 -e 选项在 docker run 命令中设置代理环境变量。

1
2
3
4
docker run \
-e HTTP_PROXY=http://proxy.example.com:7890 \
-e HTTPS_PROXY=http://proxy.example.com:7890 \
-it image-name

3. 下载镜像 docker pull

在执行 docker pull 时,是由守护进程 dockerd 来执行。 因此,代理需要配在 dockerd 的环境中。 而这个环境,则是受 systemd 所管控,因此实际是 systemd 的配置。

  1. 创建或编辑 /etc/systemd/system/docker.service.d/proxy.conf 文件

    1
    2
    sudo mkdir -p /etc/systemd/system/docker.service.d
    sudo touch /etc/systemd/system/docker.service.d/proxy.conf
  2. 在这个 proxy.conf 文件(可以是任意 *.conf 的形式)中,添加以下内容:

    1
    2
    3
    4
    [Service]
    Environment="HTTP_PROXY=http://proxy.example.com:7890"
    Environment="HTTPS_PROXY=http://proxy.example.com:7890"
    Environment="NO_PROXY=localhost,127.0.0.1,.example.com"

    依旧要记得把 proxy.example.com:7890 换成可用的免密代理。

  3. 重载 systemd 并重启 dockerd

    代理配置完成后,dockerd 代理的修改比较特殊,它实际上是改 systemd 的配置,因此需要重载 systemd 并重启 dockerd 才能生效。使得代理生效:

    1
    2
    sudo systemctl daemon-reload
    sudo systemctl restart docker
  4. 检查代理配置:

    1
    systemctl show --property=Environment docker

通过以上步骤,我们可以在不同场景下为Docker配置代理,以满足网络通信的需求。在构建、运行和下载镜像时的代理配置是Docker网络配置的重要组成部分,正确的配置将帮助我们更有效地使用Docker。

4. 参考资料