在 K8S 节点上使用非 Nodeport 默认端口范围暴漏服务

2024-03-07 09:15:49 浏览数 (1)

需求背景

  • 服务 A 部署在 K8S 中,集群外的服务 B 需要调用服务 A,同时调用服务 A 的端口是指定了的,必须是 5000,无法修改。
  • K8S 集群是客户的,我们只能部署服务,不能修改集群。
  • 服务 A 需要得到真实的客户端 IP。

解决方案一

通过 Nodeport 的方式暴漏服务 A。

5000 端口不在 Nodeport 默认端口范围内(30000-32767)。 修改 Nodeport 的端口范围,需要修改 kube-apiserver 配置,行不通。

解决方案二

服务 A 的 Pod 配置hostNetwork: true

服务 A 内部还有其他进程,监听了端口,容易和节点的其他进程冲突。同时还会暴漏服务 A 内部的其他服务。

解决方案三

新增一个 nginx Pod,并配置hostNetwork: true,dnsPolicy: ClusterFirstWithHostNet,通过七层代理来转发流量到服务 A 的 service。

服务 B 调用服务 A 时,原本是使用服务 A 的 ssl 证书。但是在七层代理下,会使用这个 nginx 的证书。而证书是服务 A 生成的,不太好自动配置给 nginx。

解决方案四

新增一个 nginx Pod,并配置hostNetwork: true,dnsPolicy: ClusterFirstWithHostNet,通过四层代理来转发流量到服务 A 的 service。nginx 启用 proxy protocol用来传递真实的客户端 IP

proxy protocol 需要后端应用支持,nginx、apache 这些都是支持了的,此方案可行。

解决方案五

新增一个 ubuntu Pod,并配置hostNetwork: true,通过 iptables 来转发流量。

  • 如果客户的 K8S kube-proxy 是 IPVS 方案
    • 将服务 A 通过 nodeport 暴漏到 30001,同时设置 iptables,将 5000 端口流量转发到 30001端口。
  • 如果客户的 K8S kube-proxy 是 iptables 方案
    • 由于在nat表里面对数据包进行dnat操作过后,数据包就不再执行nat表里面的其它规则,所以不能将流量转发到 service、nodeport,只能直接转发到服务 A 的 pod ip。
    • 由于 pod ip 不固定,假如 pod 重新创建,就需要更新 iptables 规则里的 pod ip,所以需要当前服务去 watch pod。

针对方案四中,后端应用不支持 proxy protocol 协议的情况,可以用这个方案。实现较为复杂。

0 人点赞