Kubernetes配置代理为什么总出错?HTTP_PROXY与NO_PROXY排查

节点、运行时和Pod不是同一个作用域,NO_PROXY也没有跨语言统一语法
发布于
9

Kubernetes环境里配置代理,最容易犯的错是把一组 HTTP_PROXYHTTPS_PROXYNO_PROXY 当作集群全局开关。实际上,节点上的容器运行时、kubelet、镜像构建工具和业务Pod都是不同进程,各自是否读取环境变量、何时读取、支持哪种 NO_PROXY 语法,都要单独确认。

代理只应用于确有授权的外部访问。API Server、Service、Pod和内部域名通常不应绕到公网代理。

一、先把代理配置对象分开

对象 代理可能影响什么 变更方式
节点操作系统 包管理器、系统命令 按工具或服务单独配置
容器运行时 拉取镜像、访问镜像仓库 systemd drop-in或运行时配置
kubelet 自身外部请求 服务环境与启动参数
构建任务 下载依赖、拉取源码 CI变量或Pod环境
业务Pod 应用发出的HTTP请求 Deployment、Secret或配置中心
运维终端 kubectl及本机工具 终端和工具自身设置

节点能拉镜像,不代表Pod自动获得相同代理;Pod能访问外网,也不代表容器运行时能拉取镜像。

二、HTTP_PROXY和HTTPS_PROXY分别做什么

它们是广泛使用的环境变量约定,不是由操作系统强制执行的统一标准。程序是否读取大写、小写变量,以及 HTTPS_PROXY 中接受哪种代理URL,取决于客户端实现。

配置时应查看具体运行时或库的文档,并避免同一进程同时存在值不同的大小写变量。否则不同依赖可能选择不同值,造成同一个Pod里部分请求成功、部分失败。

三、NO_PROXY至少应考虑哪些地址

  • localhost、127.0.0.1和本机服务;
  • Kubernetes API Server地址与域名;
  • 集群Service网段和Pod网段;
  • .svc.cluster.local等实际集群内部域名后缀;
  • 节点私有地址、内部镜像仓库和配置中心;
  • 云平台元数据地址,但以实际平台安全要求为准;
  • 必须直连的企业内网域名与地址段。

这些值必须来自当前集群配置,不能照抄网上的默认网段。集群域名也可能不是 cluster.local

四、NO_PROXY为什么经常“写了也不生效”

不同语言和工具对域名后缀、端口、通配符、IPv6和CIDR的支持并不完全一致。有的接受 .example.internal,有的要求完整主机名;有的支持CIDR,有的不支持。

不要先假定语法通用。应对当前应用使用的HTTP库做最小测试,并在配置中优先列出关键主机名和明确地址。逗号后是否允许空格也应按实现核对。

五、一个Deployment环境变量示意

env:
  - name: HTTP_PROXY
    valueFrom:
      secretKeyRef:
        name: outbound-proxy
        key: httpProxy
  - name: HTTPS_PROXY
    valueFrom:
      secretKeyRef:
        name: outbound-proxy
        key: httpsProxy
  - name: NO_PROXY
    value: "localhost,127.0.0.1,.svc,.cluster.local"

这里只展示结构,不是一份可直接复制到所有集群的值。代理URL若包含凭据,应放入受控Secret或外部密钥系统,不能提交到公开仓库。

六、修改Deployment后为什么旧Pod仍不生效

环境变量在进程启动时读取。更新Deployment模板通常会触发滚动发布,但手工修改ConfigMap或外部密钥不一定让所有进程立即重载。需要确认:

  • 新ReplicaSet是否生成;
  • 新Pod环境变量是否正确;
  • 应用是否在启动后又从配置文件覆盖;
  • 旧Pod是否仍承接流量;
  • 连接池是否复用旧代理连接。

代理连接池的影响可参考配置已变但仍使用旧出口的原因

七、按四条路径做验证

  1. 从Pod访问Kubernetes Service,确认内部流量没有绕代理;
  2. 从Pod访问企业内网服务,确认符合直连策略;
  3. 访问自有外部健康端点,确认代理认证与出口;
  4. 访问一个明确禁止或未授权的目标,确认策略能够阻止,而不是自动直连。

每次记录Pod、节点、镜像版本、配置哈希、DNS结果、状态码和出口。不要只在运维电脑上运行curl代替Pod内测试。

八、常见故障对应哪里

现象 优先检查
拉镜像失败但Pod内访问正常 容器运行时的代理与证书配置
Pod外网正常但API Server超时 NO_PROXY是否覆盖控制面地址
只有某语言应用失败 该语言HTTP库的变量和NO_PROXY语法
更新后部分Pod仍走旧出口 滚动发布、旧Pod与连接池
内部域名被代理返回502 Service后缀和内部网段是否排除

九、生产变更前的安全检查

在测试命名空间先验证,保留Deployment旧版本和回滚命令;不要把代理凭据写入kubectl命令历史或Pod日志。若代理变更会影响镜像拉取,还要确认回滚镜像已经在节点缓存或仓库路径可达。

代理账号密码的安全轮换可结合双凭据无中断切换流程

十、结论

Kubernetes代理排障的核心是“按进程和路径验证”。先明确谁读取变量,再验证内部直连、外部代理、DNS和回滚。只在集群级别粘贴一串环境变量,既容易让控制面绕远,也可能让未命中的业务悄悄直连。

常见问题(FAQ)

节点配置代理后,Pod会自动继承吗?
不会必然继承。节点系统、容器运行时、kubelet和业务Pod是不同进程,需要按各自配置方式处理。
NO_PROXY支持CIDR吗?
取决于具体语言、运行时和HTTP库,不能假定全部支持。应查看文档并对当前应用做最小测试。
为什么更新环境变量后部分Pod仍走旧代理?
可能有旧Pod仍在服务、应用未重载,或HTTP连接池仍复用旧连接,应核对滚动发布与连接生命周期。
代理URL可以直接写进Deployment吗?
若包含用户名密码不应直接写入仓库,应通过Kubernetes Secret或企业密钥系统注入并限制读取权限。

本文由作者原创/授权发布于极跃圈(jiyueip.com)未经许可,禁止转载。题图来自Unsplash,基于CC0协议。

声明:极跃圈(JIYUEIP.com)内网友所发表的所有内容及言论仅代表其本人,并不反映任何极跃圈(JIYUEIP.com)之意见及观点。

0 讨论
热门最新
总结
暂无总结
0 / 600