跳转至

快速设置 Docker 的两种网络代理配置

前情提要

docker 拉不了镜像,国内镜像站不能用了,在迁移国内靠谱镜像站前,正常服务应该怎么维护?

1. Docker Daemon - 代理拉取或推送国外镜像

参考 Docker 官方文档:Control Docker with systemd

通过 daemon.json 方式配置的优先级会高于通过 systemd 配置。

配置 Docker 守护程序以使用代理服务器

1. 创建 daemon.json 文件
mkdir /etc/docker  && vim /etc/docker/daemon.json 
2. 在 Docker Engine 23.0 及更高版本中,您还可以在 daemon.json 文件中为守护进程配置代理行为
{
  "proxies": {
    "http-proxy": "http://proxy.example.com:3128",
    "https-proxy": "https://proxy.example.com:3129",
    "no-proxy": "*.test.example.com,.example.org,127.0.0.0/8"
  }
}
3. 重启服务
systemctl daemon-reload && systemctl restart docker
4. 验证配置
docker info| grep Proxy
1. 创建一个 systemd 目录 docker
mkdir -p /etc/systemd/system/docker.service.d
2. 创建一个名为的文件 /etc/systemd/system/docker.service.d/http-proxy.conf 并添加 HTTP_PROXY HTTPS 环境变量:
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:3128"
Environment="HTTPS_PROXY=https://proxy.example.com:3129"
Environment="NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,.corp"
        # IP 地址前缀 ( 1.2.3.4)
        # 域名或特殊 DNS 标签 ( *)
        # 域名与该名称及其所有子域匹配。以“.”开头的域名仅与子域匹配。例如,给定域 foo.example.com和example.com:
        # example.com匹配example.com和foo.example.com,和
        # .example.com仅匹配foo.example.com
        # 单个星号 ( *) 表示无需进行代理
        # 1.2.3.4:80IP 地址前缀 ( ) 和域名 ( foo.example.com:80)接受文字端口号
3. 重启服务
systemctl daemon-reload && systemctl restart docker
4. 验证配置
> systemctl show --property=Environment docker
Environment=HTTP_PROXY=http://proxy.example.com:3128 HTTPS_PROXY=https://proxy.example.com:3129 NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,.corp

2. Container - 容器内部代理访问国外资源

参考 Docker 官方文档: Configure Docker to use a proxy server

该代理只针对于后续 build 或 run 的容器有效,已经创建好的不受影响。

1. 通过 ~/.docker/config.json 配置

1. Docker 提供了一个全局的配置,可以通过配置 Docker 客户端以自动将代理信息传递给容器,从而让所有的容器内部都支持代理访问。

1. 在 Docker 客户端上,在启动容器的用户的主目录中创建或编辑文件 ~/.docker/config.json。
# 创建目录
mkdir ~/.docker
# 创建配置文件
touch ~/.docker/config.json
# 编辑配置文件
vim ~/.docker/config.json
2. 添加 HTTP_PROXY 和 HTTPS_PROXY
{
  "auths": {
    "..."
  },
  "proxies": {
    # 通用配置,会对当前客户端连接的所有Docker服务生效
    "default": {
    "httpProxy": "http://proxy.example.com:3128",
    "httpsProxy": "https://proxy.example.com:3129",
    "noProxy": "*.test.example.com,.example.org,127.0.0.0/8"
    },
    # 如果只对某个Docker服务时配置代理,则需要通过 docker-host: proxy-settings的方式在下面配置 
    "tcp://docker-daemon1.example.com": {
    "noProxy": "*.internal.example.net"
    }
  }
}
3. 重启服务
systemctl daemon-reload && systemctl restart docker

2. 在构建镜像的过程中使用代理

1. 通过 ~/.docker/config.json 的方式配置代理在构建过程中依然有效。

2. 通过命令行配置代理

1. build 时 添加代理
docker build --build-arg HTTP_PROXY="http://proxy.example.com:3128"

3. Dockerfile 中构建时配置代理

建议:不要在 Dockerfile 中使用ENV指令配置构建过程中使用到的代理配置

1. 使用 ENV 参数,这样传递进去的参数在此之后会一直留存在镜像之中:
FROM ubuntu as base
# 放在开头,之后的指令就都会被这两条环境变量影响
ENV https_proxy="https://172.17.0.1:7890"
ENV http_proxy="http://172.17.0.1:7890"
# 其余命令
2. 使用 ARG 参数,这样两条代理指令仅在构建过程中起效,构建结束后的 Image 中不会留存相关环境变量:
FROM ubuntu as base
# 放在开头,之后的指令就都会被这两条环境变量影响
ARG https_proxy="https://172.17.0.1:7890"
ARG http_proxy="http://172.17.0.1:7890"
# 其余命令

3. 运行单个容器配置网络代理

1. 为特定的 Docker 容器配置网络代理,允许您为不同的容器指定不同的代理配置。

1. 可以在运行容器时通过 --env 参数指定
docker run -it --env http_proxy="http://test:123456@10.1.1.57:8081" --env https_proxy="http://10.1.1.57:8081" ubuntu bash

4. 使用 Docker Compose 编排文件配置代理

1. Docker Compose 是处理多容器 Docker 应用的一个编排工具。简化了复杂应用的代理配置过程,只需一次性设置即可应用于所有相关服务。

1. 在 compose.yml 文件中为服务设置代理环境变量:
services:
  your-service:
    image: your-image
    environment:
      - "http_proxy=http://10.1.1.57:8081"
      - "https_proxy=http://10.1.1.57:8081"