我一直试图找到一种方法来在一个命名空间中定义服务,该服务链接到在另一个命名空间中运行的Pod。我知道运行Pod的容器namespaceA
可以通过在群集DNS中将其引用为来访问serviceX
定义的内容,但是我宁愿容器内的代码不需要知道的位置。也就是说,我希望代码只是查找然后可以访问它。namespaceB
serviceX.namespaceB.svc.cluster.local
serviceX
serviceX
该Kubernetes文档表明这是可能的。它说,没有选择器就定义服务的原因之一是,您想将服务指向另一个命名空间或另一个群集中的服务。
这表明我应该:
- 在中定义
serviceX
服务namespaceA
,不带选择器(因为我要选择的POD不在中namespaceA
)。 - 在中定义服务(我也称为
serviceX
)namespaceB
,然后 - 在中定义一个Endpoints对象
namespaceA
以指向serviceX
innamespaceB
。
这是我无法完成的第三步。
首先,我尝试以这种方式定义Endpoints对象:
kind: Endpoints
apiVersion: v1
metadata:
name: serviceX
namespace: namespaceA
subsets:
- addresses:
- targetRef:
kind: Service
namespace: namespaceB
name: serviceX
apiVersion: v1
ports:
- name: http
port: 3000
这似乎是合乎逻辑的方法,而且显然targetRef
是为了什么。但是,这导致一个错误,表明数组中的ip
字段addresses
是必填字段。因此,我的下一个尝试是为serviceX
in 分配一个固定的ClusterIP地址namespaceB
,并将其放在IP字段中(请注意,将in service_cluster_ip_range
配置为192.168.0.0/16
,并将192.168.1.1
其分配为serviceX
in 的ClusterIP namespaceB
;serviceX
in namespaceA
在192.168.0.0/16
子网中自动分配了一个不同的ClusterIP ) :
kind: Endpoints
apiVersion: v1
metadata:
name: serviceX
namespace: namespaceA
subsets:
- addresses:
- ip: 192.168.1.1
targetRef:
kind: Service
namespace: namespaceB
name: serviceX
apiVersion: v1
ports:
- name: http
port: 3000
那被接受了,但是进入serviceX
in的访问namespaceA
没有转发到Pod in- namespaceB
他们超时了。查看iptables设置,看起来它必须要做两次NAT预路由才能完成此任务。
但并不是一个令人满意的解决方案- -我确实发现了工作的唯一的事情是查找提供吊舱的实际IP地址serviceX
中namespaceB
,并把该地址在端点对象namespaceA
。当然,这并不令人满意,因为Pod IP地址可能会随着时间变化。这就是服务IP需要解决的问题。
因此,有没有一种方法可以满足文档中的承诺,即我可以将一个命名空间中的服务指向在另一个命名空间中运行的服务?
一位评论者质疑您为什么要执行此操作-这对我来说至少是一个用例:
假设您有一个多租户系统,该系统还包括可以在租户之间共享的通用数据访问功能。现在想象一下,使用通用API的数据访问功能有不同的风格,但是性能特征也不同。一些租户可以访问其中一个,其他租户可以访问另一个。
每个租户的Pod在各自的名称空间中运行,但是每个人都需要访问这些公共数据访问服务之一,该服务必定在另一个名称空间中(因为它被多个租户访问)。但是,如果租户的订阅发生更改以访问性能更高的服务,则您不希望租户更改其代码。
一个可能的解决方案(如果可以的话,我认为是最干净的解决方案)是在每个租户的数据访问服务的命名空间中包含一个服务定义,并为每个端点配置适当的端点。该服务定义将配置为指向每个租户有权使用的正确数据访问服务。