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

相关推荐
一叶之秋141244 分钟前
Linux基础IO
linux·运维·服务器
longerxin20204 小时前
在 Linux 上使用 SCP 将文件传输到 Windows(已开启 SSH)
linux·运维·ssh
王正南8 小时前
kali-linux 虚拟机连接安卓模拟器
android·linux·运维·虚拟机连接模拟器·安卓模拟器,linux虚拟机
吳所畏惧8 小时前
Linux环境/麒麟V10SP3下离线安装Redis、修改默认密码并设置Redis开机自启动
linux·运维·服务器·redis·中间件·架构·ssh
yueguangni8 小时前
sysstat 版本 10.1.5 是 CentOS 7 的默认版本,默认情况下确实不显示 %wait 字段。需要升级到新版sysstat
linux·运维·centos
萧曵 丶10 小时前
Linux 业务场景常用命令详解
linux·运维·服务器
豆是浪个10 小时前
Linux(Centos 7.6)命令详解:ps
linux·windows·centos
Run_Teenage11 小时前
Linux:深刻理解缓冲区
linux
youxiao_9011 小时前
kubernetes 概念与安装(一)
linux·运维·服务器
凡梦千华11 小时前
logrotate日志切割
linux·运维·服务器