Балансировка нагрузки для нескольких контейнеров одного и того же приложения в модуле

У меня есть сценарий, в котором мне нужно запустить два экземпляра контейнера приложения в одном модуле. Я настроил их для прослушивания на разных портах. Ниже показано, как выглядит манифест развертывания. Pod отлично запускается с ожидаемым количеством контейнеров. Я даже могу подключиться к обоим портам на podIP из других модулей.

kind: Deployment
metadata:
  labels:
    service: app1-service
  name: app1-dep
  namespace: exp
spec:
  template:
    spec:
      contianers:
        - image: app1:1.20
          name: app1
          ports:
          - containerPort: 9000
            protocol: TCP
        - image: app1:1.20
          name: app1-s1
          ports:
          - containerPort: 9001
            protocol: TCP

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

apiVersion: v1
kind: Service
metadata:
  name: app1
  namespace: exp
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 9000
  selector:
    service: app1-service
  sessionAffinity: None
  type: ClusterIP

---
apiVersion: v1
kind: Service
metadata:
  name: app1-s1
  namespace: exp
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 9001
  selector:
    service: app1-service
  sessionAffinity: None
  type: ClusterIP

Я хочу, чтобы оба экземпляра контейнера находились за одной службой, которая выполняет циклический перебор между обоими контейнерами. Как я могу этого добиться? Возможно ли это в сфере услуг? Или мне нужно изучить Ingress для чего-то вроде этого?


person Naga    schedule 21.07.2019    source источник
comment
Почему у вас это настроено таким образом, вместо того, чтобы развертывание управляло несколькими репликами Pod с одной копией контейнера каждая? (... в этом случае обычная Служба будет циклически перебирать реплики без специальной конфигурации.)   -  person David Maze    schedule 21.07.2019
comment
Множественные реплики капсул - вот как это у нас сейчас есть. Однако есть приложение, которое потребляет около 50 ГБ ОЗУ для данных, отображаемых в memroy, но только 10-ю часть системного процессора. Я пытаюсь получить больше экземпляров контейнера в модуле по сравнению с репликами модуля, чтобы лучше использовать ресурсы кластера. Таким образом, два экземпляра приложения используют одну и ту же общую память, поскольку они оба в конечном итоге хотят получить доступ к какой-то части этих 50 ГБ. И все это, не касаясь приложения, чтобы на самом деле использовать больше ресурсов ЦП и пропускной способности.   -  person Naga    schedule 21.07.2019
comment
Но почему бы просто не сделать их отдельными развертываниями или наборами реплик с разным количеством реплик? Таким образом, он открывает возможность иметь разные аннотации узлов для узлов разного размера, а затем вы можете создавать правила сродства для разных развертываний, чтобы закрепить модули с более высоким использованием памяти на узлах с более высоким уровнем памяти и наоборот.   -  person Andy Shinn    schedule 22.07.2019
comment
Мы действительно используем отдельные развертывания, каждое из которых имеет несколько реплик. Проблема, которую я пытаюсь решить, - это уменьшение объема памяти. если у меня есть 5 реплик, это будет, например, 5 модулей по 50 ГБ, которые будут созданы и могут / не могут быть на одном узле. Итак, если бы у меня было два экземпляра контейнера приложения, которые могут использовать общую память 50 ГБ, я потенциально мог бы уменьшить количество реплик и уменьшить использование ресурсов в кластере. Один из вариантов, который я рассмотрю, - это попытка закрепить эти модули приложений на одном узле с помощью правил сходства и посмотреть на совместное использование IPC между модулями.   -  person Naga    schedule 22.07.2019


Ответы (3)


Сервисы Kubernetes имеют три режима прокси: iptables (по умолчанию), userspace, IPVS.

  • Userspace: это более старый способ, и он распространяется по циклическому алгоритму как единственный способ.
  • Iptables: по умолчанию, случайным образом выбирается один модуль и придерживается его.
  • IPVS: Имеет несколько способов распределения трафика, но сначала вы должны установить его на своем узле, например, на узле centos с помощью этой команды: yum install ipvsadm, а затем сделать его доступным.

Как я уже сказал, сервис Kubernetes по умолчанию не имеет циклического перебора. Для активации IPVS необходимо добавить параметр в kube-proxy

--proxy-mode=ipvs

--ipvs-scheduler=rr (для выбора кругового алгоритма)

person EAT    schedule 21.07.2019
comment
IPvs - это то, что мы настроили по умолчанию. И да, ipvs предназначен для лучшей балансировки нагрузки. Но в случае, о котором я говорю выше, требуется способ сопоставить один исходный порт с несколькими целевыми портами. И пока могу найти рабочее решение. - person Naga; 22.07.2019
comment
Службы подключаются к конечным точкам, а конечные точки определяются адресом и портом, поэтому не должно возникнуть проблем с использованием нескольких конечных точек с одним и тем же адресом. - person EAT; 22.07.2019

Можно открыть несколько портов с помощью одной службы. В манифесте Kubernetes-service spec.ports[] - это массив. Таким образом, в нем можно указать несколько портов. Например, см. Ниже:

apiVersion: v1
kind: Service
metadata:
  name: app1
  namespace: exp
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 9000
  - name: http-s1
    port: 81
    protocol: TCP
    targetPort: 9001
  selector:
    service: app1-service
  sessionAffinity: None
  type: ClusterIP

Теперь имя хоста такое же, за исключением порта, и по умолчанию kube-proxy в режиме пользовательского пространства выбирает серверную часть с помощью алгоритма циклического перебора.

person Shudipta Sharma    schedule 21.07.2019
comment
Я должен был пояснить, что мне нужен один IP-адрес и порт, за которыми стоят оба экземпляра контейнера. Я пробовал то, что вы предлагали, но с этим мне понадобится что-то вроде входа, которое будет балансировать нагрузку между обоими портами службы. Я пытаюсь увидеть, есть ли что-нибудь в служебной зоне. Может быть, специальная служба и настройка конечных точек заставят меня работать. - person Naga; 21.07.2019

Я бы разделил приложение на два разных развертывания, по одному контейнеру в каждом развертывании. Я бы установил одинаковые метки для обоих развертываний и атаковал бы их обе с помощью одной единственной службы.

Таким образом, вам даже не нужно запускать их на разных портах.

Позже, если вы захотите, чтобы один из них получал больше трафика, я бы просто поиграл с количеством реплик каждого развертывания.

person suren    schedule 21.07.2019