Я пытался найти способ определить службу в одном пространстве имен, которая связана с модулем, работающим в другом пространстве имен. Я знаю, что контейнеры в поде, работающем в пространстве имен A, могут получить доступ к serviceX, определенному в namespaceB, ссылаясь на него в DNS кластера как serviceX.namespaceB.svc .cluster.local, но я бы предпочел, чтобы код внутри контейнера не знал о местонахождении serviceX. То есть я хочу, чтобы код просто просматривал serviceX, а затем имел к нему доступ.

Документация Kubernetes предполагает, что это возможно. В нем говорится, что одна из причин, по которой вы определяете службу без селектора, заключается в том, что вы хотите указать свою службу на службу в другом пространстве имен или в другом кластере.

Это подсказывает мне, что я должен:

  1. Определите службу serviceX в пространстве имен Aбез селектора (поскольку POD, который я хочу выбрать, не находится в пространстве имен A).
  2. Определите службу (которую я также назвал serviceX) в namespaceB, а затем
  3. Определите объект Endpoints в пространстве именA, чтобы он указывал на serviceX в пространстве именB.

Это третий шаг, который я не смог выполнить.

Сначала я попытался определить объект Endpoints следующим образом:

вид: Конечные точки
apiVersion: v1
метаданные:
  имя: serviceX
  пространство имен: пространство именA
подмножества:
  - адреса:
      - targetRef:
          вид: Сервис
          пространство имен: пространство именB
          имя: serviceX
          apiVersion: v1
    порты:
      - имя: http
        порт: 3000

Это казалось логичным подходом, и очевидно, для чего предназначен targetRef. Но это привело к ошибке, в которой говорилось, что поле ip в массиве адресов было обязательным. Итак, моей следующей попыткой было назначить фиксированный IP-адрес ClusterIP для serviceX в namespaceBи поместить его в поле IP (обратите внимание, что service_cluster_ip_range настроен как192.168.0.0 / 16и 192.168.1.1 был назначен как ClusterIP для serviceX в пространстве именB; serviceX в пространстве имен A был автоматически назначен другой IP-адрес ClusterIP в подсети 192.168.0.0 / 16):

вид: Конечные точки
apiVersion: v1
метаданные:
  имя: serviceX
  пространство имен: пространство именA
подмножества:
  - адреса:
        - IP: 192.168.1.1
          targetRef:
            вид: Сервис
            пространство имен: пространство именB
            имя: serviceX
            apiVersion: v1
    порты:
      - имя: http
        порт: 3000

Это было принято, но доступ к serviceX в namespaceA не был перенаправлен на Pod в namespaceB - время ожидания истекло. Глядя на настройку iptables, похоже, что для этого пришлось бы дважды выполнить предварительную маршрутизацию NAT.

Единственное, что я нашел, что сработало - но не является удовлетворительным решением - это найти фактический IP-адрес модуля, предоставляющего serviceX в namespaceB, и поместить этот адрес в объект Endpoints в пространстве имен A. Это, конечно, неудовлетворительно, потому что IP-адрес модуля может со временем измениться. Это проблема, которую нужно решить с помощью IP-адресов служб.

Итак, есть ли способ выполнить то, что кажется обещанием документации, о том, что я могу указать службу в одном пространстве имен на службу , работающую в другом пространстве имен?

Комментатор спросил, зачем вам это нужно - вот вариант использования, который имеет для меня смысл, по крайней мере:

Допустим, у вас есть мультитенантная система, которая также включает в себя общую функцию доступа к данным, которая может совместно использоваться между арендаторами. Теперь представьте, что существуют разные варианты этой функции доступа к данным с общими API-интерфейсами, но с разными характеристиками производительности. Одни арендаторы получают доступ к одному из них, другие - к другому.

Модули каждого клиента работают в своих собственных пространствах имен, но каждый из них должен иметь доступ к одной из этих общих служб доступа к данным, которая обязательно будет в другом пространстве имен (поскольку к нему обращаются несколько клиентов). Но вы бы не хотели, чтобы арендатору пришлось менять свой код, если его подписка изменится для доступа к более высокопроизводительной услуге.

• 100001 Это определение службы будет настроено так, чтобы указывать на соответствующую службу доступа к данным, которую имеет право использовать каждый арендатор.

David McKinley

Ответов: 4

Ответы (4)

Я наткнулся на ту же проблему и нашел хорошее решение, которое не требует статической конфигурации IP:

Вы можете получить доступ к сервису через его DNS-имя (как упомянуто вами): servicename.namespace.svc.cluster.local

Вы можете использовать это DNS-имя для ссылки на него в другом пространстве имен через локальную службу:

вид: Сервис
apiVersion: v1
метаданные:
  имя: service-y
  пространство имен: пространство имен-а
спецификация:
  тип: ExternalName
  externalName: service-y.namespace-b.svc.cluster.local
  порты:
  - порт: 80

Вы можете добиться этого, развернув что-то на более высоком уровне, чем службы с пространством имен, например, балансировщик нагрузки 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.

Для доступа к сервисам в двух разных пространствах имен вы можете использовать URL-адрес, подобный этому:

HTTP://..svc.cluster.local

Чтобы вывести список всех ваших пространств имен, вы можете использовать:

kubectl get namespace

И для обслуживания в этом пространстве имен вы можете просто использовать:

kubectl get services -n 

это вам поможет.

Это так просто сделать

, если вы хотите использовать его в качестве хоста и хотите разрешить его

Если вы используете представитель любого другого шлюза API для службы, расположенной в другом пространстве имен, всегда рекомендуется использовать:

            Use : 
            Use : .
            Not : ..svc.cluster.local

это будет выглядеть так: имя_службы.имя_пространства_имя.svc.cluster.local

это отправит запрос определенной службе внутри указанного вами пространства имен.

пример:

kind: Service
apiVersion: v1
metadata:
  name: service
spec:
  type: ExternalName
  externalName: ..svc.cluster.local

Здесь замените и на соответствующее значение.

В Kubernetes пространства имен используются для создания виртуальной среды, но все они связаны друг с другом.

2022 WebDevInsider