June 16, 2020

Изучаем Ingress в Kubernetes

Я занимаюсь тем, что изучаю, как работает Ingress в Kubernetes. Моя цель настроить авто-маштабируемый Nginx кластер, который будет служить реверс прокси для Подов в нескольких Деплойментах. Сразу мне не было очевидно, как это сделать. По умолчанию подразумевается, что Поды не будут доступны снаружи кластера. Исправить ситуацию можно или связав их с Сервисом нужного типа (NodePort или LoadBalancer) или задействовав Ингрес. Но что такое Ингрес? Как я должен поставить Nginx между Ингресом и группой Подов? Эта статья расскажет вам о моем путешествии по загруженной специфическими терминами документации Kubernetes и его исходному коду для поиска ответов.

Статья немаленькая, поэтому если вас интересует только какой-то краткий вывод - пролистайте сразу в конец статьи.

Создать Сервис достаточно просто ...но как направить на него Nginx? И как связаны Nginx и Ingress?

Как всё начиналось

Предположим я создаю Деплоймент для контейнера 'echoserver' на порту 8080:

kubectl run hello-minikube --image=k8s.gcr.io/echoserver:1.4 --port=8080

Сейчас я ещё не думаю об автоматическом маштабировании. Как мне настроить реверс прокси Nginx для этого набора Подов? Интуиция мне подсказывала, что надо опубликовать этот Деплоймент с помощью Сервиса, после чего установить реверс прокси Nginx и направить на этот Деплоймент. Но как найти IP адрес Деплоймента? Как рассказать о нём Nginx? И как в конце концов пренастраивать Nginx когда этот IP адрес поменяется?

Гипотетически Kubernetes должен иметь API, в которому можно сделать запрос. Погуглив словосочетание "Kubernetes Nginx", я нашел довольно интересные ресурсы:

До этого я уже слышал об Ингресе, но считал, что он устанавливает балансер от облачного провайдера, в котором кластер Kubernetes устанавливается. Но результаты поиска дали понять, что существует несколько видов Ингреса (которые на самом деле являются Ингрес Контроллерами), часть из которых явно используют Nginx. Но как всё это работает? Почему каждый из них имеет свою специфику? В любом случае, я верил, что ключом, как сказать Nginx об IP адресах моих Сервисов/Подов является изучение механизма работы Ингрес контроллеров.

Установка Nginx Ингрес контроллера

Но прежде чем выяснять, как работает Nginx Ингрес контроллер, я должен сначала его установить. Изучив документацию по Ингресу и ссылку выше - [kubernetes/ingress-nginx] я сформировал следующий конфиг:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    # Avoid the Google Compute Engine controller from processing this Ingress.
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: hello-minikube
          servicePort: 80

Я применил его на моём Minikube и ... ничего не произошло.

Немного погуглив я понял, что Kubernetes никак не обрабатывает такой ресурс, как Ингрес. Необходимо вручную создавать Ингрес контроллер. Тот же Google Cloud's Kubernetes Engine по умолчанию создает "Google Cloud controller", которые отвечает за ресурсы Ингрес и предоставляет балансировщики Google Cloud.

Аннотация kubernetes.io/ingress.class говорит Google Cloud controller, что необходимо игнорировать такой ресурс, как Ингрес.

Minikube по умолчанию не предоставляет Nginx Ингрес контроллер, его нужно отдельно устанавливать или включать, как дополнение. Kubernetes/ingress-nginx документация довольно подробно описывает, как это сделать. В Minikube это делается командой:

minikube addons enable ingress

В результате открывается порт на моем ноутбуке. Рабочую ссылку можно получить командой

minikube service nginx-ingress --url