环境变量 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 分钟就能定位解决。

相关推荐
馨谙1 小时前
使用 systemd 用户服务管理容器:从概念到实践
linux·容器
人工智能训练1 小时前
Windows中如何将Docker安装在E盘并将Docker的镜像和容器存储在E盘的安装目录下
linux·运维·前端·人工智能·windows·docker·容器
zzzsde2 小时前
【Linux】基础开发工具(1):软件包管理器&&vim编辑器
linux·运维·服务器
tan180°2 小时前
Linux网络TCP(上)(11)
linux·网络·c++·后端·tcp/ip
断水客2 小时前
如何在手机上搭建Linux学习环境
linux·运维·学习
会飞的土拨鼠呀2 小时前
ubuntu24安装snmp服务
linux·运维
胖好白2 小时前
【RK3588开发】模型部署全流程
linux·人工智能
司铭鸿2 小时前
图论中的协同寻径:如何找到最小带权子图实现双源共达?
linux·前端·数据结构·数据库·算法·图论
last demo3 小时前
nfs服务器
linux·运维·服务器·php