环境变量 HTTP_PROXY/HTTPS_PROXY 深度解析:为什么 cURL 行,Docker 不行?

关键词:HTTP_PROXY、HTTPS_PROXY、代理、Docker、containerd、cURL、systemd、Linux


一、前言

在 Linux 服务器或 Kubernetes 集群中,我们经常会遇到「命令行走代理成功,但后台服务始终连不通」的诡异现象。最典型的例子就是:

bash 复制代码
export HTTP_PROXY=http://192.168.1.100:7897
curl -I https://www.google.com     # ✅ 秒出 200
docker pull hello-world            # ❌ 卡住不动

本文将带你彻底搞懂:

  1. HTTP_PROXY / HTTPS_PROXY 到底影响了谁?
  2. 为什么 cURL 能用,Docker 却用不了
  3. 怎样让 系统级服务 也乖乖走代理?

二、HTTP_PROXY 是什么?

1. 定义

HTTP_PROXY / HTTPS_PROXY进程级别的环境变量 ,用于告诉 支持它的应用程序

"你的 HTTP/HTTPS 请求不要直接发,先发到这个代理地址,由它帮你转发。"

2. 作用域

  • 仅对「读取该变量」的进程有效
  • 谁启动时拿到,谁就用;拿不到就直连
  • 不会自动继承给「已运行」的系统服务

三、实验:同一台机器,三种不同结果

场景 是否走代理 原因
curl www.google.com curl 是当前 shell 子进程,继承了 HTTP_PROXY
wget www.google.com wget 同样读变量
docker pull hello-world dockerdsystemd 服务 ,启动时 没有 这些变量
kubelet 拉镜像 同上,也读不到终端里 export 的变量

四、底层原理:变量传递链条

text 复制代码
┌--------------------┐
│ 终端 export        │──┐
└--------------------┘  │ 继承
                        ▼
┌--------------------┐
│ curl / wget / 其他  │◀- 子进程,能用代理
└--------------------┘

┌--------------------┐
│ dockerd / kubelet  │◀- systemd 启动,**不继承**终端变量
└--------------------┘

结论

临时 export 只能影响「当前 shell 及后续子进程」
对「已开机启动」的系统服务无效!


五、实战:让 Docker 也走代理

1. 写入 systemd

bash 复制代码
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf <<'EOF'
[Service]
Environment="HTTP_PROXY=http://192.168.1.100:7897"
Environment="HTTPS_PROXY=http://192.168.1.100:7897"
Environment="NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
EOF

2. 重载 & 重启

bash 复制代码
sudo systemctl daemon-reload
sudo systemctl restart docker

3. 验证

bash 复制代码
docker info | grep -i proxy
# 输出里能看到刚写的地址
docker pull hello-world
# 秒拉完成

六、Kubernetes 场景扩展

1. 只让 镜像拉取 走代理

  • 仅给 containerd 配代理(kubelet 不配,避免它连 apiserver 也绕远路)

  • 同样写 systemd:

    bash 复制代码
    sudo mkdir -p /etc/systemd/system/containerd.service.d
    # 同上写 http-proxy.conf
    sudo systemctl restart containerd

2. 给 Pod 内业务 走代理

  • 在 Deployment/Helm 的 env 里显式写:

    yaml 复制代码
    env:
    - name: http_proxy
      value: "http://192.168.1.100:7897"
    - name: https_proxy
      value: "http://192.168.1.100:7897"

七、一张图总结

text 复制代码
终端 export HTTP_PROXY
   │
   ├─▶ 子进程(curl、wget、python 脚本...) ✅
   │
   ├─▶ 后台服务(dockerd、containerd、kubelet) ❌
   │     └─▶ 必须写 systemd 单元文件 ✅
   │
   └─▶ Pod 内容器 ✅
         └─▶ 在 YAML 里显式声明 env ✅

八、常见坑 checklist

现象 排查点
curl 行,Docker 不行 是否给 dockerd 写了 systemd 代理
重启后又失效 代理文件是否在 /etc/systemd/system/服务.service.d/ 目录
空格导致失败 cat -A 查看文件,确认 7897" 后面没有空格
kubelet 连不上 apiserver 不要把 kubelet 的代理指向外网;NO_PROXY 里加上集群内网、apiserver 地址

九、结语

HTTP_PROXY/HTTPS_PROXY 本身很简单,但**"谁能读到它"**决定了流量走向。

记住一句话:

临时 export 只能玩终端;要让系统服务走代理,就去 systemd 写文件!

把这篇博客收藏起来,下次再遇到「cURL 行,Docker 不行」的怪事,5 分钟就能定位解决。

相关推荐
爱吃山竹的大肚肚6 小时前
EasyPOI 大数据导出
java·linux·windows
极地星光6 小时前
dmesg 工具的核心功能与作用
linux
福尔摩斯张7 小时前
C++核心特性精讲:从C语言痛点出发,掌握现代C++编程精髓(超详细)
java·linux·c语言·数据结构·c++·驱动开发·算法
hgz07108 小时前
Linux服务器环境部署与JMeter压测准备
linux·服务器·jmeter
ShirleyWang0128 小时前
VMware如何导入vmdk文件
linux·数据库
Lueeee.8 小时前
内核menuconfig配置实验
linux
遇见火星8 小时前
常见Systemctl语句
linux·服务器·网络·systemctl
月明长歌9 小时前
【码道初阶】【LeetCode 110】平衡二叉树:如何用一个“Magic Number”将复杂度从O(N²)降为 O(N)?
linux·算法·leetcode
齐鲁大虾9 小时前
国产 Linux 系统核心优缺点与适用场景
linux·运维·服务器
skywalk81639 小时前
webvm 用浏览器启动的虚拟环境
linux·wasm