Я пытался найти способ определить службу в одном пространстве имен, которая связана с модулем, работающим в другом пространстве имен. Я знаю, что контейнеры в serviceX
Pod, работающем в namespaceA
могут обращаться к serviceX
определенному в namespaceB
, ссылаясь на него в DNS кластера как serviceX.namespaceB.svc.cluster.local
, но я бы не хотел, чтобы код внутри контейнера должен был знать о расположение serviceX
. То есть я хочу, чтобы код просто serviceX
и затем serviceX
доступ к нему.
Документация Kubernetes предполагает, что это возможно. В нем говорится, что одной из причин, по которой вы определяете службу без селектора, является то, что вы хотите указать свою службу для службы в другом пространстве имен или в другом кластере.
Это подсказывает мне, что я должен:
- Определите сервис
serviceX
вnamespaceA
serviceX
, без селектора (поскольку POD, который я хочу выбрать, не находится вnamespaceA
). - Определите службу (которую я также назвал
serviceX
) вnamespaceB
, а затем - Определите объект Endpoints в
namespaceA
чтобы он указывал наserviceX
в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
является обязательным. Итак, моей следующей попыткой было назначить фиксированный адрес ClusterIP для serviceX
в namespaceB
и поместить его в поле IP (обратите внимание, что service_cluster_ip_range
настроен как 192.168.0.0/16
, а 192.168.1.1
был назначен в качестве ClusterIP для serviceX
в namespaceB
; serviceX
в 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
в namespaceA
serviceX
не перенаправлялся в Pod в namespaceB
serviceX
- они истекли. Глядя на настройку iptables, похоже, что для этого нужно было бы дважды выполнить предварительную маршрутизацию NAT.
Единственное, что я обнаружил, что это сработало, но не является удовлетворительным решением, - это поиск фактического IP-адреса Pod, предоставляющего serviceX
в namespaceB
и помещение этого адреса в объект Endpoints в namespaceA
. Конечно, это неудовлетворительно, потому что IP-адрес Pod может со временем меняться. Это проблема IP-адресов службы, чтобы решить.
Итак, есть ли способ удовлетворить то, что кажется обещанием документации, что я могу указать службу в одном пространстве имен службе, работающей в другом пространстве имен?
Комментатор спросил, почему вы хотели бы сделать это - вот пример использования, который имеет смысл для меня, по крайней мере:
Допустим, у вас есть мультитенантная система, которая также включает в себя общую функцию доступа к данным, которая может совместно использоваться арендаторами. Теперь представьте, что существуют разные варианты этой функции доступа к данным с общими API, но с разными характеристиками производительности. Некоторые арендаторы получают доступ к одному из них, другие арендаторы имеют доступ к другому.
Каждый модуль арендатора работает в своих собственных пространствах имен, но каждому из них требуется доступ к одной из этих общих служб доступа к данным, которые обязательно будут находиться в другом пространстве имен (поскольку к нему обращаются несколько арендаторов). Но вы не хотели бы, чтобы арендатор изменил свой код, если его подписка изменится, чтобы получить доступ к высокопроизводительной службе.
Потенциальное решение (самое чистое, которое я могу придумать, если бы оно работало) состоит в том, чтобы включить определение службы в каждое пространство имен арендатора для службы доступа к данным, причем каждое из них настроено для соответствующей конечной точки. Это определение службы будет настроено так, чтобы указывать на соответствующую службу доступа к данным, которую каждый арендатор имеет право использовать.