Развернутый Nginx Ingress Controller, но служба с типом LoadBalancer имеет ожидающий внешний IP-адрес

У меня есть кластер k3s (облегченный k8s), работающий на моем Raspberry PI. Итак, я использую не какой-либо облачный кластер, а медвежий металл на моем Raspberry PI.

Я развернул приложение с этим манифестом:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
  namespace: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-world
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
        - name: hello-world
          image: bashofmann/rancher-demo:1.0.0
          imagePullPolicy: Always
          resources:
            requests:
              cpu: 200m
          ports:
          - containerPort: 8080
            name: web
            protocol: TCP

Я также создал службу для перенаправления трафика в модуль приложения. Его манифест:

apiVersion: v1
kind: Service
metadata:
  name: demo-app-svc
  namespace: myapp
spec:
  selector:
    app: hello-world
  ports:
  - name: web
    protocol: TCP
    port: 31113
    targetPort: 8080

Затем я создал Ingress для правил маршрутизации:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ing
  namespace: myapp
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx 
  rules:
  - host: myapp.com
    http:
      paths:
      - pathType: Prefix
        path: /
        backend:
          service:
            name: demo-app-svc 
            port:
              number: 31113

Я успешно развернул вышеупомянутый модуль приложения, сервис и Ingress в своем кластере k3s. Как указано в манифестах, они находятся в пространстве имен myapp.

Следующее, что я хотел бы сделать, — это развернуть Kubernetes Nginx Ingress Controller, чтобы клиенты вне кластера могли получить доступ к развернутому приложению.

Итак, я развернул его:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.2/deploy/static/provider/cloud/deploy.yaml

Приведенная выше команда успешно развернула Ingress Controller в пространстве имен ingress-nginx вместе с другими объектами, как показано ниже с помощью команды k get all -n ingress-nginx:

Как вы можете видеть выше, внешний IP-адрес типа LoadBalancer имеет значение service. Таким образом, клиент вне кластера по-прежнему не может получить доступ к модулю приложения.

Почему это так и что мне не хватает при развертывании Nginx Ingress Controller на машине медвежьего металла? Цель состоит в том, чтобы иметь внешний IP-адрес, который можно использовать для доступа к пакету приложений из внешнего кластера, как я могу этого добиться?

===== Обновление =====

Основываясь на приведенном ниже ответе @David Kruk, я решил использовать контроллер Traefik Ingress по умолчанию k3s.

Итак, я удалил все развернутые ресурсы Nginx Ingress Controller с помощью <pending> .

Затем я проверил сервис типа k delete all --all -n ingress-nginx, связанный с Traefik Ingress:

LoadBalancer этого сервиса Traefik — это именно IP-адрес моего Raspberry PI!

Итак, я добавил этот IP-адрес в external IP, чтобы сопоставить его с именем хоста, определенным в моем объекте Ingress:

192.168.10.203 myapp.com

Я открыл браузер и использовал адрес http://myapp.com с правилами маршрутизации, определенными в моем объекте /etc/hosts (см. манифест для моего входа выше), я надеялся, что теперь смогу увидеть развернутое веб-приложение. Но получайте Ingress. Чего мне сейчас не хватает для доступа к моему развернутому приложению?

Еще один побочный вопрос: я заметил, что когда я проверяю развернутый объект 404 Page Not Found, его IP-адрес пуст, интересно, должен ли я видеть IP-адрес для этого объекта или нет, когда Traefik Ingress Controller вступает в силу?

Еще одна проблема: теперь, когда я повторно развертываю свой входной манифест с помощью Ingress, я получаю сообщение об ошибке:

Resource: "networking.k8s.io/v1, Resource=ingresses", GroupVersionKind: "networking.k8s.io/v1, Kind=Ingress"
...
for: "ingress.yaml": error when patching "ingress.yaml": Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io": failed to call webhook: Post "https://ingress-nginx-controller-admission.ingress-nginx.svc:443/networking/v1/ingresses?timeout=10s": service "ingress-nginx-controller-admission" not found

Похоже, даже я решил использовать Traefik Ingress Controller, мне все равно нужно установить Nginx Ingress Controller. Я запутался сейчас, кто-нибудь может объяснить это?

Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
1
0
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не эксперт по K3S, но мне кажется, что я нашел документацию, посвященную вашей проблеме.

Взглянем:

Балансировщик нагрузки службы

В вашем кластере K3s можно использовать любой балансировщик нагрузки службы (LB). По умолчанию K3s предоставляет балансировщик нагрузки, известный как ServiceLB (ранее Klipper Load Balancer), который использует доступные хост-порты.

Upstream Kubernetes позволяет создавать службы типа LoadBalancer, но не включает реализацию балансировщика нагрузки по умолчанию, поэтому эти службы останутся pending, пока они не будут установлены. Многим размещенным службам требуется облачный провайдер, такой как Amazon EC2 или Microsoft Azure, чтобы предложить реализацию внешней балансировки нагрузки. Напротив, K3s ServiceLB позволяет использовать службы LoadBalancer без облачного провайдера или какой-либо дополнительной настройки.

Как работает сервис LB

Контроллер ServiceLB отслеживает Kubernetes Services с полем spec.type, установленным на LoadBalancer.

Для каждой службы LoadBalancer создается DaemonSet в пространстве имен kube-system. Этот DaemonSet, в свою очередь, создает поды с префиксом svc- на каждом узле. Эти поды используют iptables для перенаправления трафика из NodePort пода на адрес и порт ClusterIP службы.

Если модуль ServiceLB работает на узле с настроенным внешним IP-адресом, внешний IP-адрес узла заносится в список адресов status.loadBalancer.ingress службы. В противном случае используется внутренний IP-адрес узла.

Если создается несколько служб LoadBalancer, для каждой службы создается отдельный DaemonSet.

На одном узле можно разместить несколько Сервисов, если они используют разные порты.

Если вы попытаетесь создать службу LoadBalancer, которая прослушивает порт 80, ServiceLB попытается найти свободный хост в кластере для порта 80. Если хост с этим портом недоступен, LB останется в состоянии ожидания.

-- Docs.k3s.io: Сеть

В качестве возможного решения я бы рекомендовал использовать Traefik, так как это контроллер Ingress по умолчанию в K3S.

Статус Pending на вашем LoadBalancer, скорее всего, вызван другой службой, используемой на этом порту (Traefik).

Если вы хотите по-прежнему использовать NGINX, на той же странице документации объясняется, как отключить Traefik.


ОБНОВЛЯТЬ

Я был бы осторожнее с удалением ресурсов, как это сделали вы. Следующая команда:

  • k delete all --all -n ingress-nginx

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

  • kubectl create -f ...

Использовать:

  • kubectl delete -f ...

Я предполагаю, что вы не изменили свое определение Ingress, поэтому вы получаете сообщение об ошибке, и kubectl get ingress показывает неверные результаты.

Что вам нужно будет сделать:

spec:
  ingressClassName: nginx # <-- DELETE IT OR CHANGE TO "traefik"

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

Спасибо! Не могли бы вы проверить мой обновленный пост выше на основе вашего ответа?

user842225 21.02.2023 08:59

@ user842225 Я воспроизвел вашу настройку и обновил ответ. Взглянем.

Dawid Kruk 21.02.2023 18:56

Привет спасибо! Я также понял и точно так, как вы сказали.

user842225 22.02.2023 07:46

Другие вопросы по теме