Я пытался найти способ определить службу в одном пространстве имен, которая связана с модулем, работающим в другом пространстве имен. Я знаю, что контейнеры в запущенном Pod namespaceA
могут получить доступ к serviceX
определенному в namespaceB
, указав его в DNS кластера как serviceX.namespaceB.svc.cluster.local
, но я бы предпочел не иметь код внутри контейнера, который должен знать о местонахождении serviceX
. То есть я хочу, чтобы код просто выполнял поиск, serviceX
а затем имел к нему доступ.
Документация Kubernetes предполагает, что это возможно. В нем говорится, что одна из причин, по которой вы должны определить службу без селектора, заключается в том, что вы хотите указать свою службу на службу в другом пространстве имен или в другом кластере .
Это подсказывает мне, что я должен:
- Определите
serviceX
службуnamespaceA
без селектора (поскольку 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
массиве является обязательным. Итак, моя следующая попытка состояла в том, чтобы назначить фиксированный IP-адрес ClusterIP для serviceX
in namespaceB
и поместить его в поле IP (обратите внимание, что service_cluster_ip_range
он настроен как 192.168.0.0/16
и 192.168.1.1
был назначен как ClusterIP для serviceX
in namespaceB
; serviceX
in 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.
Единственным , что я нашел , что работало - но не является удовлетворительным решением - это для поиска фактического IP - адреса Pod , обеспечивающий serviceX
в namespaceB
и поместить этот адрес в объекте Endpoints в namespaceA
. Это, конечно, неудовлетворительно, потому что IP-адрес модуля может со временем измениться. Это проблема IP-адресов служб, которую нужно решить.
Итак, есть ли способ выполнить то, что, кажется, является обещанием документации, что я могу указать службу в одном пространстве имен на службу, работающую в другом пространстве имен?
Комментатор спросил, зачем вам это нужно - вот пример использования, который, по крайней мере, для меня имеет смысл:
Допустим, у вас есть мультитенантная система, которая также включает в себя общую функцию доступа к данным, которая может совместно использоваться арендаторами. Теперь представьте, что существуют разные варианты этой функции доступа к данным с общими API-интерфейсами, но с разными характеристиками производительности. Одни арендаторы получают доступ к одному из них, другие - к другому.
Модули каждого клиента работают в своих собственных пространствах имен, но каждый из них должен иметь доступ к одной из этих общих служб доступа к данным, которая обязательно будет в другом пространстве имен (поскольку к нему обращаются несколько клиентов). Но вы бы не хотели, чтобы арендатору пришлось менять свой код, если его подписка изменится для доступа к более высокопроизводительной службе.
Потенциальное решение (самое чистое, о котором я могу думать, если бы оно только работало) - включить определение службы в пространство имен каждого клиента для службы доступа к данным, причем каждое из них настроено для соответствующей конечной точки. Это определение службы должно быть настроено так, чтобы указывать на соответствующую службу доступа к данным, которую имеет право использовать каждый арендатор.
источник
Ответы:
Я наткнулся на ту же проблему и нашел хорошее решение, которое не требует статической конфигурации IP:
Вы можете получить доступ к службе через ее DNS-имя (как упомянуто вами): servicename.namespace.svc.cluster.local
Вы можете использовать это DNS-имя для ссылки на него в другом пространстве имен через локальную службу :
источник
Это так просто сделать
если вы хотите использовать его в качестве хоста и хотите разрешить его
Если вы используете посланник к любому другому шлюзу API для службы, расположенной в другом пространстве имен, всегда рекомендуется использовать:
это будет так:
servicename.namespacename.svc.cluster.local
это отправит запрос определенной службе внутри указанного вами пространства имен.
пример:
Здесь замените
<servicename>
и<namespace>
на соответствующее значение.В Kubernetes пространства имен используются для создания виртуальной среды, но все они связаны друг с другом.
источник
.svc.cluster.local
по умолчанию поддерживается внутреннее разрешение службы.Вы можете добиться этого, развернув что-то на более высоком уровне, чем службы с пространством имен, например балансировщик нагрузки службы https://github.com/kubernetes/contrib/tree/master/service-loadbalancer . Если вы хотите ограничить его одним пространством имен, используйте аргумент "--namespace = ns" (по умолчанию он используется для всех пространств имен: https://github.com/kubernetes/contrib/blob/master/service-loadbalancer/service_loadbalancer.go # L715 ). Это хорошо работает для L7, но немного беспорядочно для L4.
источник