У меня есть кластер Kubernetes, на котором я запускаю брокер ZeroMQ внутри. Я настроил службу, чтобы этот брокер можно было найти модулями в кластере, используя следующий шаблон Helm:
#values.yaml
zmqServiceType:
type: ClusterIP
zmqPub:
port: 31339
zmqSub:
port: 31342
zmqWsSub:
port: 31343
-----
#service.yaml
apiVersion: v1
kind: Service
metadata:
name: zmq-broker
labels:
{{ include "zmq-broker.labels" . | indent 4 }}
spec:
type: {{ .Values.zmqServiceType.type }}
ports:
- name: zmq-sub
port: {{ .Values.zmqSub.port }}
protocol: TCP
- name: zmq-pub
port: {{ .Values.zmqPub.port }}
protocol: TCP
- name: zmq-ws-sub
port: {{ .Values.zmqWsSub.port }}
protocol: TCP
externalIPs:
#Master node IP external address
- 10.2.1.100
selector:
app.kubernetes.io/name: {{ include "zmq-broker.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
Это отлично работает в кластере, модули могут найти брокера без проблем с конечной точкой zmq "tcp: // zmq-broker:" .
Однако я также хотел бы открыть доступ к zmq-брокеру, чтобы к нему можно было получить доступ извне кластера.
Я знаю, что могу сделать это очень просто, запустив kubectl port-forward:
kubectl port-forward <ZMQ_BROKER_POD> 31342:31342 31339:31339 31343:31343
Но у этого есть два недостатка: он требует, чтобы команда kubectl port-forward выполнялась все время, и нужно знать, какой модуль брокер работает на априори (плюс, насколько я понимаю, он не предназначен для производственной среды).
Я бы предпочел способ сопоставить внешние порты не с модулем, а со службой , так что они всегда найдут его, независимо от имени модуля. Технически не имеет значения, какой физический узел мы подключаем к внутренней службе, но мы предпочитаем сделать его главным узлом. У нас нет необходимости в балансировке нагрузки, поскольку в системе работает только один брокер.
Я предполагал, что все, что мне нужно, - это раздел externalIPs в файле служб, но это, похоже, не так. Раздел externalIPs действительно создает процесс прослушивания на главном узле, но, похоже, он не пересылает TCP-трафик.
Возможно ли то, что я пытаюсь сделать здесь, и если да, то как?
Изменить: Я переместил внешний IP-адрес на один из рабочих узлов, и он работает нормально, но какой бы IP я ни использовал на главном узле, он не будет пересылать трафик. Есть ли что-то особенное в главном узле K8s, из-за которого он не пересылает внешний IP-трафик?
Это произошло из-за проблемы маршрутизации.
Главный узел не смог правильно выполнить маршрутизацию к рабочим узлам, поскольку Flannel использовал неправильный интерфейс.
Карта Шлема в том виде, в котором она написана, верна. Как только мы исправили проблему с маршрутизацией, все заработало.
Если вы оказались в похожей ситуации, когда главный узел не работает, а рабочие узлы работают, то следующее может подтвердить наличие той же проблемы:
запустите
ip route
На рабочих узлах и главном узел с несколькими запущенными модулями. Вы должны увидеть IP-адреса модуля (10.244.X.X, если используется CIDR по умолчанию) как на головном узле, так и на рабочих узлах. В нашем случае мы не видели маршруты на мастер-ноде.
Было также подтверждено, что проблема связана с фланелью, при просмотре журналов для фланелевых модулей:
kubectl logs <Flannel_Pod_Name> --namespace kube-system
Это показало ошибки при запуске модуля головного узла, а именно ошибку «нет маршрута к хосту», когда он пытался создайте записи маршрутизации для модулей. Журналы рабочего узла показали, что фланель успешно создает маршруты.
Исправление состоит в том, чтобы гарантировать, что маршрут по умолчанию на вашем главном узле проходит через устройство, имеющее IP-адрес, который взаимодействует с вашими рабочими узлами (для нас наш маршрут по умолчанию на главном узле изначально был в сети 192.X, но должен был быть в сети 10.X для общения с рабочими узлами).