Skip to content

Установка Ingress-контроллера в Kubernetes

Case 1. Установка Ingress-контроллера через манифест

Для начала, установим Ingress-контроллер с помощью команды kubectl apply:

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

Case 2. Установка Ingress-контроллера через Helm

Первое, что нужно сделать, чтобы получить возможность установить наш ingress-контроллер, это добавить его репозиторий в helm-клиент с помощью следующих команд:

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

Настройка параметров развёртывания контроллера

Далее необходимо создать файл nginx-values.yaml. Для моего случая получилось следующее:

controller:
  replicaCount: 2
  service:
    type: NodePort
    externalTrafficPolicy: Local
    nodePorts:
      http: 31080
      https: 31443
  ingressClassResource:
    default: true
  watchIngressWithoutClass: true
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app.kubernetes.io/component
            operator: In
            values:
            - controller
          - key: app.kubernetes.io/instance
            operator: In
            values:
            - ingress-nginx
          - key: app.kubernetes.io/name
            operator: In
            values:
            - ingress-nginx
        topologyKey: "kubernetes.io/hostname"

Далее я поясню значение этих настроек.

Способ публикации ingress-контроллера

Так как предполагается использовать в качестве балансировщика нагрузки внешний неуправляемый кластером роутер, сервис контроллера нужно публиковать с помощью controller.service.type: NodePort, а не LoadBalancer.

Чтобы настроить DNAT на внешнем роутере, необходимо зафиксировать порты для HTTP и HTTPS, прописав их с помощью controller.nodePorts.http: 31080 и controller.nodePorts.https: 31443, соответственно.

Изменение количества реплик

Сервис с типом NodePort по умолчанию выполняет SNAT, что приводит к тому, что исходный IP в запросах будет соответствовать IP узла Kubernetes-кластера, принявшего запрос.

Таким образом, в логах web-приложений IP-адрес присутствовать не будет. Рекомендуемым способом сохранения IP-адреса клиента для сервиса с типом NodePort является установка spec.externalTrafficPolicy в Local.

Однако, это означает, что пакеты, полученные узлом, не имеющим запущенного экземпляра ingress controller, будут отброшены. Чтобы избежать этого, на каждом узле кластера, указанном в балансировщике нагрузки роутера (в моём случае worker-узлы), необходимо запустить экземпляр контроллера. Это делается с помощью настройки controller.replicaCount: 2 (по числу worker-узлов). Чтобы гарантировать присутствие пода контроллера на каждом узле, настраивается controller.affinity.

Класс ingress-контроллера по умолчанию

В одном кластере одновременно могут использоваться различные продуты, выступающие в качестве ingress-контроллеров.

При создании ingress-ресурса можно (и желательно) указать так называемый класс контроллера, соответствующий ingress-продукту (в данном случае nginx == NGINX Ingress Controller).

Однако, пользователь может и не указать его. Чтобы кластер работал предсказуемым образом, один из классов ingress-контроллера рекомендуется пометить как используемым по умолчанию. Для этого предназначена настройка controller.ingressClassResource.default: true.

Для большей надёжности и для совместимости с ingress-ресурсами, созданными до установки данного ingress-контроллера, также используется возможность NGINX Ingress Controller по отслеживанию ingress-ресурсов без указанного класса ingress-контроллера: controller.watchIngressWithoutClass: true.

Если вставить в секцию

controller:
    service:
        externalIPs:
            - 12.34.56.78
то создаются правила в
iptables
-A KUBE-SERVICES -d 12.34.56.78/32 -p tcp -m comment --comment "ingress-nginx/ingress-nginx-controller:http external IP" -m tcp --dport 80 -j KUBE-EXT-CG5I4G2RS3ZVWGLK
-A KUBE-SERVICES -d 12.34.56.78/32 -p tcp -m comment --comment "ingress-nginx/ingress-nginx-controller:https external IP" -m tcp --dport 443 -j KUBE-EXT-EDNDUDH2C75GIR6O

Развёртывание ingress-контроллера в кластере

Выполняем следующую команду:

helm install ingress-nginx ingress-nginx/ingress-nginx
    --namespace ingress-nginx --create-namespace
    --values ingress-nginx-values.yaml

Если вы хотите перед развёртыванием в кластере проанализировать полученные ресурсы, в данную команду можно добавить пару ключей: --dry-run --debug.

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

kubectl wait --namespace ingress-nginx
  --for=condition=ready pod
  --selector=app.kubernetes.io/component=controller
  --timeout=120s