一、配置守护进程代理

如果需要使用代理服务器连接到互联网,可能需要给 Docker daemon 配置代理以使用代理服务器。

配置好代理之后,守护进程通过代理服务器访问存储在 Docker Hub 和其他注册表上的镜像,同时访问 Docker 集群中的其他节点也通过代理服务器。

有两种方式配置:

  • 通过守护进程配置文件或守护进程命令配置代理
  • 通过系统环境变量配置代理

1、守护进程配置文件

可以在 daemon.json 文件中配置守护进程的代理行为。daemon 文件位置位于 /etc/docker 目录下。

daemon.json 文件内容如下:

1
2
3
4
5
6
7
{
"proxies": {
"http-proxy": "http://172.19.32.1:7890",
"https-proxy": "http://172.19.32.1:7890",
"no-proxy": "*.test.example.com,.example.org,127.0.0.0/8"
}
}

修改文件之后需要重启 docker 服务:

1
$ sudo systemctl restart docker

2、守护进程命令

使用 dockerd 命令的 --http-proxy--https-proxy 选项来指定。

1
2
$ dockerd --http-proxy "http://172.19.32.1:7890"
$ dockerd --https-proxy "http://172.19.32.1:7890"

3、环境变量

Docker 守护进程在启动环境中检查以下环境变量,以配置 HTTP 或 HTTPS 的代理行为:

  • HTTP_PROXY
  • http_proxy
  • HTTPS_PROXY
  • https_proxy
  • NO_PROXY
  • no_proxy

3.1 修改系统环境变量

修改 ~/.bashrc 文件,在其中添加代理配置如下:

1
2
export http_proxy="http://172.19.32.1:7890"
export https_proxy="http://172.19.32.1:7890"

之后执行 source ~/.bashrc 命令使更改配置生效。

3.2 系统文件

如果将 Docker 守护进程作为 systemd 服务运行,可以选择创建一个 systemd 文件来为 docker 服务设置环境变量。

执行如下命令,创建 docker 服务目录:

1
$ sudo mkdir -p /etc/systemd/system/docker.service.d

创建文件 /etc/systemd/system/docker.service.d/http-proxy.conf 在文件中增加代理配置环境变量

1
2
3
[Service]
Environment="HTTP_PROXY=http://172.19.32.1:7890"
Environment="HTTPS_PROXY=http://172.19.32.1:7890"

如果需要连接内部 docker 注册表,其不需要使用代理,可以通过 no_proxy 环境变量进行代理排除。no_proxy 变量是一个字符串,其中包含应该从代理中排除的主机,可以为多个,用逗号分隔。

no_proxy 环境变量可选项如下:

  • IP 地址(例如,111.222.3.4
  • 域名或特殊的DNS标签(*)
  • 一个匹配域名及所其有子域名的域名。以 . 开头的域名仅匹配子域名。例如,这里有域名 foo.example.comexample.com
    • example.com 匹配 example.comfoo.example.com
    • .example.com 仅匹配 foo.example.com
  • 单个星号(*)表示不应进行代理。
  • IP地址(例如,111.222.3.4:80)和域名(例如,foo.example.com:80)可以添加端口号。

示例如下:

1
2
3
4
[Service]
Environment="HTTP_PROXY=http://172.19.32.1:7890"
Environment="HTTPS_PROXY=http://172.19.32.1:7890"
Environment="no_proxy=localhost,127.0.0.1,docker-registry.example.com,*.test.example.com,.corp"

刷新设置并重启:

1
2
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

通过如下命令验证配置是否已经生效:

1
2
$ sudo systemctl show --property=Environment docker
Environment=HTTP_PROXY=http://172.19.32.1:7890 HTTPS_PROXY=http://172.19.32.1:7890

二、配置 Docker 使容器使用代理

配置 Docker CLI 以通过容器中的环境变量使用代理。

1、 配置 Docker 客户端

可以编辑 config.json 文件,在配置文件中为 Docker 客户端添加代理配置。构建过程和容器都将使用此文件中指定的配置。对于 Windows,该文件路径为 %USERPROFILE%/.docker/config.json,对于 Linux 该文件路径为 ~/.docker/config.json

1
2
3
4
5
6
7
8
9
{
"proxies": {
"default": {
"httpProxy": "http://172.19.32.1:7890",
"httpsProxy": "http://172.19.32.1:7890",
"noProxy": "*.test.example.com,.example.org,127.0.0.0/8"
}
}
}

注意:代理设置可能包含敏感信息。例如,一些代理服务器要求在其URL中包含身份验证信息,或者其地址可能会暴露公司环境的IP地址或主机名。环境变量以纯文本的形式存储在容器的配置中,因此可以通过远程API进行检查或使用 docker commit 提交到镜像。

保存文件之后配置即可用,不用重启 Docker。但是该配置仅适用于新容器和新构建过程,不会影响现存容器。

  • httpProxy 属性,用于设置 HTTP_PROXYhttp_proxy 环境变量和构建参数。
  • httpsProxy 属性,用于 HTTPS_PROXYhttps_proxy 环境变量和构建参数。
  • ftpProxy 属性,用于 FTP_PROXYftp_proxy 环境变量和构建参数。
  • noProxy 属性,用于 NO_PROXYno_proxy 环境变量和构建参数。
  • allProxy 属性,用于 ALL_PROXYall_proxy 环境变量和构建参数。

ALL_PROXY 环境变量为统一代理设置,可以同时为 HTTP、HTTPS、FTP等多种协议设置代理服务器,使得配置更加简洁和统一。

2.1.1 使用代理配置运行容器

当启动一个容器时,它的代理相关的环境变量将使用 config.json 中的代理配置。

1
2
3
4
5
6
7
$ docker run --rm alpine sh -c 'env | grep -i  _PROXY'
HTTPS_PROXY=http://172.19.32.1:7890
no_proxy=*.test.example.com,.example.org,127.0.0.0/8
NO_PROXY=*.test.example.com,.example.org,127.0.0.0/8
https_proxy=http://172.19.32.1:7890
http_proxy=http://172.19.32.1:7890
HTTP_PROXY=http://172.19.32.1:7890

2.1.2 使用代理配置进行构建

当在调用构建时,会根据 Docker 客户端配置文件中的代理设置自动填充与代理相关的构建参数。

2.1.3 为单独的守护进程配置代理

config.json 文件中的默认代理配置(default)会应用于所有连接到守护进程的客户端。如果配置单个代理,需要使用收据进程的地址而不是 default 来作为键。

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
{
"proxies": {
"default": {
"httpProxy": "http://172.19.32.1:7890",
"httpsProxy": "http://172.19.32.1:7890",
"noProxy": "*.test.example.com,.example.org,127.0.0.0/8"
},
"tcp://docker-daemon1.example.com": {
"noProxy": "*.test.example.com"
}
}
}

2、使用 Docker CLI 配置代理

当调用 docker builddocker run 命令时,设置代理。

  • 使用 docker build--build-arg 选项
  • 使用 docker run--env 选项
1
2
$ docker build --build-arg HTTP_PROXY="http://172.19.32.1:7890" .
$ docker run --env HTTP_PROXY="http://172.19.32.1:7890" redis

3、构建的环境变量中使用代理

不要使用 ENV Dockerfile 指令为构建指定代理,改用构建参数。使用环境变量中的代理配置将会使配置嵌入到镜像中。如果代理是内部代理,则根据该镜像创建的容器可能无法访问它。另外在镜像中嵌入代理设置也会带来安全风险,因为这些值可能包含敏感信息。

相关链接

Configure the daemon to use a proxy | Docker Docs

Configure Docker to use a proxy server | Docker Docs

Change Docker Desktop settings on Mac | Docker Docs

Change Docker Desktop settings on Windows | Docker Docs

Change Docker Desktop settings on Linux | Docker Docs

Dockerfile reference | Docker Docs

We need to talk: Can we standardize NO_PROXY? (gitlab.com)

OB tags

#Docker