在Ubuntu系统中配置全局代理并解决Docker网络连接问题

引言

在某些网络环境下,我们需要通过代理服务器来访问外部资源。本文将详细介绍如何在Ubuntu系统中配置全局代理,并解决Docker在代理环境下的网络连接问题。整个过程包括安装代理客户端、配置系统代理、设置Docker代理等步骤,同时会分析遇到的问题及解决方案。

环境准备

  • 操作系统:Ubuntu 24.10
  • Docker版本:已安装
  • 代理工具:Hysteria2

1. 安装Hysteria2代理客户端

首先,我们需要安装Hysteria2客户端来建立代理连接:

curl -fsSL https://get.hy2.sh/ | bash

安装完成后,会看到成功提示:

Installing hysteria executable ... ok
Install /etc/hysteria/config.yaml ... ok
Creating user hysteria ... ok
Install /etc/systemd/system/hysteria-server.service ... ok
Install /etc/systemd/system/hysteria-server@.service ... ok

Congratulation! Hysteria 2 has been successfully installed on your server.

2. 配置Hysteria2客户端

创建配置目录和配置文件:

mkdir -p ~/.config/hysteria2
nano ~/.config/hysteria2/config.yaml

在配置文件中添加以下内容(注意替换为您的实际配置):

server: your-server-ip:port
auth: your-password
tls:
  sni: your-sni-domain
  insecure: true  # 对应skip-cert-verify: true
socks5:
  listen: 127.0.0.1:1080
http:
  listen: 127.0.0.1:8080

3. 启动Hysteria2客户端并设置为系统服务

首先,测试客户端是否能正常启动:

which hysteria  # 查找可执行文件路径
/usr/local/bin/hysteria -c ~/.config/hysteria2/config.yaml

如果启动成功,会看到类似以下输出:

INFO    client mode
INFO    connected to server     {"udpEnabled": true, "tx": 0, "count": 1}
INFO    use this URI to share your server       {"uri": "hysteria2://..."}
INFO    HTTP proxy server listening     {"addr": "127.0.0.1:8080"}
INFO    SOCKS5 server listening {"addr": "127.0.0.1:1080"}

接下来,创建系统服务以便后台运行:

sudo nano /etc/systemd/system/hysteria-client.service

添加以下内容:

[Unit]
Description=Hysteria Client Service
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/hysteria -c /root/.config/hysteria2/config.yaml
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

启用并启动服务:

sudo systemctl daemon-reload
sudo systemctl enable hysteria-client.service
sudo systemctl start hysteria-client.service

检查服务状态:

sudo systemctl status hysteria-client.service

4. 配置系统代理

4.1 使用环境变量设置临时代理

export http_proxy="http://127.0.0.1:8080"
export https_proxy="http://127.0.0.1:8080"
export all_proxy="socks5://127.0.0.1:1080"

4.2 安装并配置ProxyChains

ProxyChains可以为单个命令设置代理:

sudo apt update
sudo apt install proxychains4

编辑ProxyChains配置文件:

sudo nano /etc/proxychains4.conf

在文件末尾确保有以下配置(删除或注释其他proxy行):

[ProxyList]
socks5 127.0.0.1 1080

测试ProxyChains是否工作:

proxychains4 curl ifconfig.me

如果返回的IP地址是代理服务器的IP,则说明配置成功。

5. 配置Docker使用代理

尝试运行Docker容器时,可能会遇到网络连接问题:

docker run hello-world

错误信息:

Unable to find image 'hello-world:latest' locally
docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": context deadline exceeded

5.1 配置Docker守护进程使用代理

创建Docker服务配置目录:

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

创建代理配置文件:

sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf > /dev/null << 'EOL'
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:8080"
Environment="HTTPS_PROXY=http://127.0.0.1:8080"
Environment="NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,.corp"
EOL

重新加载配置并重启Docker服务:

sudo systemctl daemon-reload
sudo systemctl restart docker

验证Docker环境变量是否正确设置:

sudo systemctl show --property=Environment docker

5.2 配置Docker客户端代理

创建或编辑Docker客户端配置文件:

mkdir -p ~/.docker
nano ~/.docker/config.json

添加以下内容:

{
  "proxies": {
    "default": {
      "httpProxy": "http://127.0.0.1:8080",
      "httpsProxy": "http://127.0.0.1:8080",
      "noProxy": "localhost,127.0.0.1"
    }
  }
}

6. 测试Docker是否能正常工作

配置完成后,再次尝试运行Docker容器:

docker run hello-world

如果配置正确,将会看到成功信息:

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
e6590344b1a5: Pull complete 
Digest: sha256:c41088499908a59aae84b0a49c70e86f4731e588a737f1637e73c8c09d995654
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.
...

遇到的问题及解决方案

问题1:Hysteria2命令找不到

症状:执行hysteria2命令时提示"command not found"。

解决方案:使用which hysteria查找实际的可执行文件路径,然后使用完整路径执行命令。在本例中,正确的命令是/usr/local/bin/hysteria而不是hysteria2

问题2:Docker无法连接到镜像仓库

症状:Docker尝试拉取镜像时出现"context deadline exceeded"错误。

解决方案

  1. 配置Docker守护进程使用代理
  2. 配置Docker客户端代理设置
  3. 确保两者都正确配置后重启Docker服务

问题3:代理服务无法在后台运行

症状:关闭终端后代理服务停止。

解决方案:将代理客户端配置为系统服务,使用systemd管理,确保其在后台持续运行。

Docker代理配置的影响范围

需要注意的是,Docker代理配置有两个不同的层面:

  1. Docker守护进程代理:通过systemd配置,只影响Docker守护进程从Docker Hub或其他镜像仓库拉取镜像时的网络连接,不会影响容器内部的网络连接。

  2. Docker容器内部网络:默认情况下,容器内部的应用程序不会自动使用配置的代理。如果需要容器内部使用代理,需要在运行容器时通过环境变量传递代理设置:

docker run -e HTTP_PROXY=http://127.0.0.1:8080 -e HTTPS_PROXY=http://127.0.0.1:8080 -it ubuntu bash

临时启用或禁用代理

启用代理

可以将以下函数添加到~/.bashrc文件中:

proxy_on() {
    export http_proxy="http://127.0.0.1:8080"
    export https_proxy="http://127.0.0.1:8080"
    export all_proxy="socks5://127.0.0.1:1080"
    echo "代理已开启"
}

禁用代理

proxy_off() {
    unset http_proxy
    unset https_proxy
    unset all_proxy
    echo "代理已关闭"
}

执行source ~/.bashrc后,可以通过简单的命令来开启或关闭代理:

  • 输入proxy_on开启代理
  • 输入proxy_off关闭代理

结论

通过本文的配置步骤,我们成功在Ubuntu系统中设置了全局代理,并解决了Docker在代理环境下的网络连接问题。这些配置使得在网络受限的环境中也能顺利进行开发和部署工作。

需要注意的是,代理配置可能会因网络环境、代理服务器类型和应用程序的不同而需要调整。在实际应用中,可能需要根据具体情况进行微调。

参考资料