Несколько месяцев назад я написал статью о контроллере Kubernetes Nginx Ingress, которая занимает второе место по популярности в этом блоге. Основная ее тема — использование Kubernetes Ingress для локальных развертываний. Впрочем, большинство пользователей использует Kubernetes в облаке AWS и общедоступных облачных сервисах других поставщиков. Однако проблема заключается в том, что для каждого сервиса типа LoadBalancer AWS создает новый балансировщик ELB (Elastic Load Balancer). Это может оказаться слишком дорогим удовольствием. Если взять на вооружение Kubernetes Ingress, потребуется лишь один ELB.
Как это работает?
Для лучшего понимания я приведу несколько схем. Без контроллера Ingress для каждого предоставленного сервиса будет создаваться отдельный классический балансировщик ELB:
При использовании Ingress потребуется только один такой балансировщик ELB, направляющий все запросы на прокси-под Ingress, выполняемый в кластере:
Рассмотрим стоимость балансировщика нагрузки Classic Load Balancer:
Надо оплачивать каждый полный или неполный час работы балансировщика нагрузок Classic Load Balancer и за каждый гигабайт данных, переданный с его помощью.
Это означает, что при использовании кластера в регионе US East придется заплатить примерно $18,25 за каждый предоставленный сервис. Еще надо оплачивать каждый гигабайт обработанных данных. Ingress позволяет снизить расходы на AWS при большом количестве предоставляемых сервисов. Разумеется, для обеспечения высокой доступности можно использовать несколько реплик прокси-пода Ingress.
Развертывание Nginx Ingress
Существует большое количество доступных вариантов контроллера Ingress, например, Traefik, Voyager (для HAProxy), Contour (для Envoy), или даже контроллер Ingress AWS ALB (альфа-версия), который несколько отличается от остальных. В этой публикации я рассматриваю контроллер Ingress Nginx, сейчас наиболее распространенный. В отличие от предыдущей статьи о контроллере Ingress Nginx, на этот раз для развертывания я использую Helm:
cat > values.yaml <<EOF
controller:
replicaCount: 2
config:
use-proxy-protocol: "true"
service:
annotations:
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*'
EOF
helm install --name ingress
--namespace ingress
-f values.yaml
stable/nginx-ingress
Примечание. В работе Helm есть проблема, связанная с тем, что логические значения не анализируются в качестве строковых при использовании аргумента set. Поэтому я создал файл со значениями, а не обновил значения по умолчанию через --set
и --set-string
.
Проверка подов Ingress выводит два сервиса, контроллер и серверную часть по умолчанию:
kubectl get pod -n ingress --selector=app=nginx-ingress
NAME READY STATUS RESTARTS AGE
ingress-nginx-ingress-controller-8689c87db7-jlwxv 1/1 Running 0 5m
ingress-nginx-ingress-controller-8689c87db7-kv859 1/1 Running 0 5m
ingress-nginx-ingress-default-backend-5f5888cc9b-jdjrp 1/1 Running 0 5m
Здесь следует объяснить некоторые моменты. Поскольку все запросы будут идти через под контроллера Ingress, желательно иметь как минимум две его реплики. По сути это внутренний прокси-сервер. Контроллер использует серверную часть по умолчанию для маршрутизации несуществующих ресурсов Ingress. Серверная часть по умолчанию довольно проста. Для получения исходных IP-адресов в журнале прокси-сервера Ingress я активировал протокол прокси-соединения для Nginx и ELB с помощью следующих двух настроек:
--set controller.service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-proxy-protocol"='*'
--set-string controller.config.use-proxy-protocol=true
Протокол прокси-соединения предназначен для связи прокси-серверов без потери данных клиента.
А в качестве бонуса теперь можно легко получить автоматический DNS. Сначала создайте запись DNS A с использованием метасимволов, например, *.test.example.com
, которая будет указывать на контроллер Ingress ELB. Адрес ELB можно получить с помощью этой команды:
kubectl get svc ingress-nginx-ingress-controller -o jsonpath='{.status.loadBalancer.ingress[0].hostname}' -n ingress
a00950ebcfd0411e740ee0207cf10ce8-1089949860.eu-west-1.elb.amazonaws.com
Затем при создании точки входа Ingress с хостом site1.test.example.com
можно будет сразу вводить эту строку в браузере. DNS разрешит имя без дополнительной настройки. Использование записи DNS с метасимволами — не самая лучшая идея, но она работает. Для детальной настройки DNS можно использовать внешний DNS для Kubernetes.
Заключение
Использование контроллера Ingress действительно помогает добиться более высокого уровня автоматизации. Но помните, что в случае его сбоя все ваши внешние конечные точки тоже выйдут из строя! В следующей статье я покажу, как настроить автоматическое обновление и установку SSL-сертификатов с помощью Let's Encrypt. После этого вы сможете по умолчанию использовать автоматический DNS с конечными точками SSL. Следите за новостями.
Автор: aSkobin