В этой статье описана сетевая модель и принципы работы Kubernetes-сети. Также рассмотрено создание Kubernetes-балансировщиков для доступа к приложениям.
Если вы не знакомы с понятиями сервисов и подов (единиц развертывания) – начните со статьи “Основы Kubernetes”.
Сетевая модель кластера
В кластере Kubernetes каждый под получает собственный IP-адрес (идентификатор устройства в компьютерной сети) из диапазона Pod CIDR (бесклассовая междоменная маршрутизация), заданного при создании кластера. Поды могут обращаться друг к другу напрямую по IP-адресам, независимо от того, на какой ноде (группе серверов) они работают.
Для стабильного доступа к группе подов используются сервисы – они предоставляют постоянный адрес и распределяют трафик между подами.
Типы сервисов
- ClusterIP – доступен только внутри кластера. Сервис получает виртуальный IP-адрес из диапазона адресов сервисов. Используется для связи между компонентами приложения.
- NodePort – открывает фиксированный порт на каждой ноде кластера. Трафик, поступающий на этот порт, перенаправляется к подам сервиса.
- LoadBalancer – создает балансировщик нагрузки на стороне платформы. Подходит для предоставления доступа к приложению извне.
Создание сервиса ClusterIP
ClusterIP – тип сервиса по умолчанию. Он предоставляет стабильный внутренний адрес для группы подов, доступный только изнутри кластера. Используйте его для связи между компонентами приложения – например, чтобы frontend (внешний интерфейс) обращался к backend (серверная часть) по фиксированному имени.
apiVersion: v1
kind: Service
metadata:
name: backend
namespace: default
spec:
selector:
app: backend
ports:
- port: 8080
targetPort: 8080
type: ClusterIPПосле применения манифеста сервис будет доступен внутри кластера по имени backend (или полному DNS-имени (от англ. Domain Name System – система доменных имен) backend.default.svc.cluster.local) и по выделенному ClusterIP:
kubectl apply -f backend-service.yaml
kubectl get svc backend
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
backend ClusterIP 10.96.45.12 <none> 8080/TCP 5sДругие поды в кластере могут обращаться к этому сервису по имени:
http://backend:8080Создание сервиса NodePort
NodePort открывает фиксированный порт (из диапазона 30000–32767) на каждой ноде кластера. Трафик, поступающий на этот порт любой ноды, перенаправляется к подам сервиса.
apiVersion: v1
kind: Service
metadata:
name: frontend
namespace: default
spec:
selector:
app: frontend
ports:
- port: 80
targetPort: 80
nodePort: 30080
type: NodePortПосле применения сервис будет доступен на порту 30080 каждой ноды кластера:
kubectl apply -f frontend-nodeport.yaml
kubectl get svc frontend
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend NodePort 10.96.78.90 <none> 80:30080/TCP 5sБалансировщик нагрузки
При создании сервиса типа LoadBalancer платформа автоматически выделяет балансировщик, который распределяет входящий трафик между подами приложения.
Внешний и внутренний балансировщик
Тип балансировщика задается аннотацией lb.beget.com/type:
external – балансировщику назначается публичный IP-адрес, доступный из интернета. Подходит для:
- Веб-сайтов и веб-приложений
- Публичных API (интерфейсов программирования приложения)
- Любых сервисов, к которым обращаются внешние пользователи
internal – балансировщик доступен только внутри приватной сети. Подходит для:
- Внутренних API и межсервисного взаимодействия
- Баз данных и других сервисов, которые не должны быть доступны извне
- Компонентов, взаимодействующих только с другими сервисами в облаке
Создание внешнего балансировщика
Сохраните манифест в файл loadbalancer-external.yaml:
apiVersion: v1
kind: Service
metadata:
annotations:
lb.beget.com/algorithm: round_robin
lb.beget.com/healthcheck-interval-seconds: "60"
lb.beget.com/healthcheck-timeout-seconds: "5"
lb.beget.com/type: external
name: nginx
namespace: default
spec:
allocateLoadBalancerNodePorts: true
ports:
- port: 80
targetPort: nginx
selector:
app: nginx
type: LoadBalancerПримените манифест:
kubectl apply -f loadbalancer-external.yamlСоздание внутреннего балансировщика
Сохраните манифест в файл loadbalancer-internal.yaml:
apiVersion: v1
kind: Service
metadata:
annotations:
lb.beget.com/algorithm: round_robin
lb.beget.com/healthcheck-interval-seconds: "60"
lb.beget.com/healthcheck-timeout-seconds: "5"
lb.beget.com/type: internal
name: internal-api
namespace: default
spec:
allocateLoadBalancerNodePorts: true
ports:
- port: 8080
targetPort: api
selector:
app: internal-api
type: LoadBalancerПримените манифест:
kubectl apply -f loadbalancer-internal.yamlАннотации балансировщика
Управление параметрами балансировщика выполняется через аннотации в поле metadata.annotations манифеста.
Тип балансировщика
lb.beget.com/type– значения:external,internal. Тип балансировщика: публичный или приватный
Алгоритм балансировки
lb.beget.com/algorithm– значения:round_robin,least_connections. Алгоритм распределения трафика между подами
Проверки работоспособности (healthcheck)
Healthcheck-аннотации определяют, как балансировщик проверяет доступность backend-сервисов. Если сервис не отвечает в пределах тайм-аута, балансировщик перестает направлять на него трафик до восстановления.
lb.beget.com/healthcheck-interval-seconds– положительное целое число. Интервал между проверками (в секундах). По умолчанию – 5.lb.beget.com/healthcheck-timeout-seconds– положительное целое число. Тайм-аут ожидания ответа (в секундах). По умолчанию – 30.
Проверка статуса балансировщика
После применения манифеста убедитесь, что балансировщик создан и получил адрес:
kubectl get svc <имя-сервиса>Вместо <имя-сервиса> укажите имя из поля metadata.name вашего манифеста. В нашем примере это nginx:
Ожидаемый вывод для внешнего балансировщика:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx LoadBalancer 10.96.162.132 155.212.142.254 80:31160/TCP 10s- CLUSTER-IP – внутренний адрес сервиса в кластере
- EXTERNAL-IP – адрес, по которому балансировщик доступен извне (для external) или внутри приватной сети (для internal)
- PORT(S) – порт сервиса и назначенный NodePort
Если в колонке EXTERNAL-IP отображается <pending>, балансировщик еще создается. Повторите команду через некоторое время или используйте флаг --watch для отслеживания:
kubectl get svc nginx --watchОбычно выделение IP-адреса занимает не более минуты. Если статус <pending> сохраняется дольше нескольких минут – проверьте события сервиса командой kubectl describe svc nginx.
Удаление балансировщика
Для удаления балансировщика удалите соответствующий сервис:
kubectl delete svc nginxПосле удаления сервиса балансировщик на стороне платформы также будет удален, а выделенный IP-адрес освобожден.
Все статьи раздела
- Kubernetes (K8s) – обзор сервиса Managed Kubernetes (управляемый Kubernetes)
- Основы Kubernetes – ключевые понятия: кластер, ноды, поды, сервисы
- Создание и настройка кластера – конфигурация master-нод (узлов управляющего контура), сеть и worker-группы (групп узлов)
- Подключение к кластеру и работа с kubectl (консольный инструмент для управления Kubernetes) – kubeconfig (конфигурационный файл Kubernetes), подключение и первые команды
- Управление кластером – добавление нод, изменение конфигурации, обновление, удаление
- Сеть и балансировщик нагрузки – вы здесь
- Лимиты, квоты и ограничения – ограничения платформы, что можно и нельзя изменить
Если возникнут вопросы, напишите нам, пожалуйста, обращение в панели управления аккаунта (раздел “Помощь и поддержка”), а если вы захотите обсудить эту статью или наши продукты с коллегами по цеху и сотрудниками Beget – ждем вас в нашем сообществе в Telegram.