小编典典

位于另一个命名空间中的服务

all

我一直在尝试找到一种方法来在一个命名空间中定义一个服务,该服务链接到在另一个命名空间中运行的 Pod。我知道 Pod 中运行的容器可以通过在集群 DNS
中引用它namespaceA来访问serviceX定义的.
也就是说,我希望代码只是查找然后能够访问它。namespaceB``serviceX.namespaceB.svc.cluster.local``serviceX``serviceX

Kubernetes文档表明这是可能的。它说您定义没有选择器的服务的原因之一是 您希望将您的服务指向另一个命名空间或另一个集群中的服务

这表明我应该:

  1. 在 中定义一个serviceX服务namespaceA,没有选择器(因为我要选择的 POD 不在 中namespaceA)。
  2. 在 中定义一个服务(我也叫它serviceXnamespaceB,然后
  3. 定义一个 Endpoints 对象 innamespaceA以指向serviceXin namespaceB

这是我无法完成的第三步。

首先,我尝试以这种方式定义 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是强制性的。所以,我的下一个尝试是为 in
分配一个固定的 ClusterIP 地址serviceXnamespaceB并将其放在 IP
字段中(请注意,service_cluster_ip_range配置为192.168.0.0/16192.168.1.1并被分配为serviceXin的
ClusterIP namespaceBserviceX在子网上namespaceA自动分配了一个不同的 ClusterIP
192.168.0.0/16) :

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 预路由才能完成此操作。

我发现唯一可行但不是一个令人满意的解决方案的唯一方法是查找提供的 Pod 的实际 IP 地址,serviceX并将namespaceB该地址放在
Endpoints 对象中namespaceA。当然,这并不令人满意,因为 Pod IP 地址可能会随着时间而改变。这就是服务 IP 要解决的问题。

那么,有没有一种方法可以满足文档的承诺,即我可以将一个命名空间中的 服务 指向在不同命名空间中运行的服务?

一位评论者质疑您为什么要这样做 - 这是一个对我来说有意义的用例,至少:

假设您有一个多租户系统,其中还包括一个可以在租户之间共享的通用数据访问功能。现在想象一下,这个数据访问函数有不同风格的通用
API,但性能特征不同。一些租户可以访问其中一个,其他租户可以访问另一个。

每个租户的 pod
都在自己的命名空间中运行,但每个人都需要访问这些常见的数据访问服务之一,这些服务必然位于另一个命名空间中(因为它由多个租户访问)。但是,如果他们的订阅发生更改以访问性能更高的服务,您不希望租户必须更改他们的代码。

一个潜在的解决方案(我能想到的最简洁的解决方案,如果它有效的话)是在每个租户的数据访问服务的命名空间中包含一个服务定义,每个服务定义都针对适当的端点进行配置。该服务定义将被配置为指向每个租户有权使用的正确数据访问服务。


阅读 94

收藏
2022-06-24

共1个答案

小编典典

我偶然发现了同样的问题,并找到了一个不需要任何静态 ip 配置的好解决方案:

您可以通过它的DNS 名称(如您所提到的)访问服务: servicename.namespace.svc.cluster.local

您可以使用该 DNS 名称通过本地服务在另一个命名空间中引用它:

kind: Service
apiVersion: v1
metadata:
  name: service-y
  namespace: namespace-a
spec:
  type: ExternalName
  externalName: service-y.namespace-b.svc.cluster.local
  ports:
  - port: 80
2022-06-24