Подтвердить что ты не робот

Kubernetes: служба, расположенная в другом пространстве имен

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

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

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

  1. Определите сервис serviceX в namespaceA serviceX, без селектора (поскольку POD, который я хочу выбрать, не находится в namespaceA).
  2. Определите службу (которую я также назвал serviceX) в namespaceB, а затем
  3. Определите объект 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, но с разными характеристиками производительности. Некоторые арендаторы получают доступ к одному из них, другие арендаторы имеют доступ к другому.

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

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

4b9b3361

Ответ 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-x.namespace-b.svc.cluster.local
  ports:
  - port: 80

Ответ 2

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

Ответ 3

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

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

это будет похоже на: servicename.namespacename.svc.cluster.local

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

Для бывших

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

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

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