【发布时间】:2016-09-10 07:52:51
【问题描述】:
我一直在尝试找到一种方法来在一个命名空间中定义一个服务,该服务链接到在另一个命名空间中运行的 Pod。我知道在namespaceA 中运行的 Pod 中的容器可以通过在集群 DNS 中将其引用为serviceX.namespaceB.svc.cluster.local 来访问在namespaceB 中定义的serviceX,但我宁愿没有容器内的代码需要了解serviceX 的位置。也就是说,我希望代码只查找serviceX,然后能够访问它。
Kubernetes documentation 表明这是可能的。它说您定义没有选择器的服务的原因之一是您希望将您的服务指向另一个命名空间或另一个集群中的服务。
这表明我应该:
- 在
namespaceA中定义一个serviceX服务,没有选择器(因为我要选择的POD 不在namespaceA中)。 - 在
namespaceB中定义一个服务(我也叫serviceX),然后 - 在
namespaceA中定义一个Endpoints 对象以指向namespaceB中的serviceX。
这是我未能完成的第三步。
首先,我尝试以这种方式定义 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 的用途。但是,这导致了一个错误,指出addresses 数组中的ip 字段是强制性的。所以,我的下一个尝试是在namespaceB 中为serviceX 分配一个固定的ClusterIP 地址,并将其放在IP 字段中(注意service_cluster_ip_range 被配置为192.168.0.0/16,而192.168.1.1 被分配为在namespaceB 中serviceX 的ClusterIP;namespaceA 中的serviceX 在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
这已被接受,但对 namespaceA 中的 serviceX 的访问没有被转发到 namespaceB 中的 Pod - 它们超时。查看 iptables 设置,看起来它必须执行两次 NAT 预路由才能完成。
我发现唯一可行但不是令人满意的解决方案的唯一方法是在namespaceB 中查找提供serviceX 的Pod 的实际IP 地址,并将该地址放入namespaceA 的Endpoints 对象中。当然,这并不令人满意,因为 Pod IP 地址可能会随着时间而改变。这就是服务 IP 要解决的问题。
那么,有没有一种方法可以满足文档的承诺,即我可以将一个命名空间中的服务指向在不同命名空间中运行的服务?
一位评论者质疑您为什么要这样做 - 这是一个至少对我来说有意义的用例:
假设您有一个多租户系统,其中还包括一个可以在租户之间共享的通用数据访问功能。现在想象一下,这个数据访问函数有不同风格的通用 API,但性能特征不同。一些租户可以访问其中一个,其他租户可以访问另一个。
每个租户的 pod 都在自己的命名空间中运行,但每个人都需要访问这些常见的数据访问服务之一,这些服务必然位于另一个命名空间中(因为它由多个租户访问)。但是,如果租户更改订阅以访问性能更高的服务,您不希望租户必须更改其代码。
一个潜在的解决方案(我能想到的最简洁的解决方案,如果它有效的话)是在每个租户的命名空间中包含一个服务定义,用于数据访问服务,每个服务定义都针对适当的端点进行配置。此服务定义将被配置为指向每个租户有权使用的正确数据访问服务。
【问题讨论】:
-
命名空间的重点是隔离,所以我认为如果你需要跨越命名空间,你至少需要知道它的位置!
-
那么,当文档建议您可以通过不定义选择器并暗示定义端点来指示在一个命名空间中定义的服务访问不同命名空间中的服务时,文档意味着什么?这肯定有有效的用例——我在问题中添加了其中一个。文档只是误导,还是有一种我还没有弄清楚的方法?
-
我不确定,抱歉。我所知道的是我使用他们的 fqdn 访问多个命名空间中的服务。我特别用 vpn 来做这件事,因为我有 1 个 vpn pod,并且我通过它的所有服务进行连接。但是您需要知道命名空间并提供 fqdn。我建议你在 slack 频道上提问。
-
使用 fqdn 是我目前使用的解决方案。不过,如果没有必要,我的用例会得到更好的服务(现在添加到问题中)。
-
我也想知道文档指的是什么,但是我可以使用 fqdn 作为我用例的令人满意的解决方案。
标签: kubernetes