Обеспечение доступа к приложению, запущенному в кластере Kubernetes
В примере ниже рассматривается приложение Kubernetes, которое отвечает на HTTP-запросы на порт 8080. Для предоставления доступа к приложению используйте публичные или внутренние сервисы. Их IP-адреса не меняются в отличие от адресов подов и узлов кластера.
Чтобы опубликовать приложение, воспользуйтесь сервисом типа LoadBalancer. Вы можете организовать два вида доступа:
-
Публичный доступ по IP-адресу с внешним сетевым балансировщиком нагрузки Yandex Network Load Balancer.
-
Доступ из внутренних сетей по IP-адресу с внутренним сетевым балансировщиком.
Приложение будет доступно:
- Из подсетей Yandex Virtual Private Cloud.
- Из внутренних подсетей организации, подключенных к Yandex Cloud с помощью сервиса Yandex Cloud Interconnect.
- Через VPN.
При использовании внешнего балансировщика нагрузки в поле loadBalancerIP можно указать статический публичный IP-адрес. Такой адрес необходимо зарезервировать заранее. Во время резервирования публичного IP-адреса можно активировать защиту от DDoS-атак. Если не указывать статический публичный IP-адрес, то сетевому балансировщику нагрузки будет назначен динамический публичный IP-адрес.
Примечание
В отличие от IP-адреса пода или узла, который может меняться в случае обновления ресурсов группы узлов, статический публичный IP-адрес сервиса типа LoadBalancer не изменяется.
При использовании внутреннего балансировщика нагрузки можно указать внутренний IP-адрес. Убедитесь, что указанный внутренний IP-адрес не назначен какому-либо ресурсу в той же облачной сети.
Важно
Если вы в дальнейшем удалите из спецификации внутренний IP-адрес, он может быть автоматически назначен другому ресурсу в той же облачной сети. Рекомендуем выбирать IP-адрес ближе к концу диапазона IP-адресов выбранной подсети.
Чтобы обеспечить доступ к приложению Kubernetes:
- Подготовьтесь к работе
- Создайте приложение Kubernetes
- Создайте сервис типа LoadBalancer
- Проверьте доступность приложения
- (Опционально) Создайте объект NetworkPolicy
Как обеспечить доступ к приложению с помощью HTTPS?
См. документацию:
- Создание нового Kubernetes-проекта в Yandex Cloud
- Настройка L7-балансировщика Yandex Application Load Balancer с помощью Ingress-контроллера
- Установка Ingress-контроллера NGINX с менеджером для сертификатов Let's Encrypt®
- Установка Ingress-контроллера NGINX с сертификатом из Yandex Certificate Manager
Если созданные ресурсы вам больше не нужны, удалите их.
Перед началом работы
-
Установите kubectl
и настройте его на работу с созданным кластером. -
Подготовьте инфраструктуру:
ВручнуюTerraform-
Создайте облачную сеть и подсеть.
-
Создайте сервисный аккаунт с ролями
k8s.clusters.agent,vpc.publicAdminиload-balancer.admin. Рольload-balancer.adminнужна для создания сетевого балансировщика нагрузки. -
Создайте группы безопасности для кластера Managed Service for Kubernetes и входящих в него групп узлов.
Важно
От настройки групп безопасности зависит работоспособность и доступность кластера, а также запущенных в нем сервисов и приложений.
-
Создайте кластер Managed Service for Kubernetes и группу узлов с публичным доступом в интернет и с группами безопасности, подготовленными ранее.
-
Если у вас еще нет Terraform, установите его.
-
Получите данные для аутентификации. Вы можете добавить их в переменные окружения или указать далее в файле с настройками провайдера.
-
Настройте и инициализируйте провайдер. Чтобы не создавать конфигурационный файл с настройками провайдера вручную, скачайте его
. -
Поместите конфигурационный файл в отдельную рабочую директорию и укажите значения параметров. Если данные для аутентификации не были добавлены в переменные окружения, укажите их в конфигурационном файле.
-
Скачайте в ту же рабочую директорию файл конфигурации кластера Managed Service for Kubernetes k8s-load-balancer.tf
. В файле описаны:-
Сеть.
-
Кластер Managed Service for Kubernetes.
-
Сервисный аккаунт, необходимый для работы кластера и группы узлов Managed Service for Kubernetes.
-
Группы безопасности, которые содержат необходимые правила для кластера Managed Service for Kubernetes и входящих в него групп узлов.
Важно
От настройки групп безопасности зависит работоспособность и доступность кластера, а также запущенных в нем сервисов и приложений.
-
-
Укажите в файле конфигурации:
- Идентификатор каталога.
- Версию Kubernetes для кластера и групп узлов Managed Service for Kubernetes.
- Имя сервисного аккаунта кластера Managed Service for Kubernetes.
-
Проверьте корректность файлов конфигурации Terraform с помощью команды:
terraform validateЕсли в файлах конфигурации есть ошибки, Terraform на них укажет.
-
Создайте необходимую инфраструктуру:
-
Выполните команду для просмотра планируемых изменений:
terraform planЕсли конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены.
-
Если вас устраивают планируемые изменения, внесите их:
-
Выполните команду:
terraform apply -
Подтвердите изменение ресурсов.
-
Дождитесь завершения операции.
-
В указанном каталоге будут созданы все требуемые ресурсы. Проверить появление ресурсов и их настройки можно в консоли управления
.Ограничения по времени
Провайдер Terraform ограничивает время на выполнение операций с кластером и группой узлов Managed Service for Kubernetes:
- создание и изменение кластера — 30 минут;
- создание и изменение группы узлов — 60 минут;
- удаление группы узлов — 20 минут.
Операции, которые длятся дольше указанного времени, прерываются.
Как изменить эти ограничения?
Добавьте к описанию кластера и группы узлов блоки
timeouts(ресурсыyandex_kubernetes_clusterиyandex_kubernetes_node_groupсоответственно).Пример:
resource "yandex_kubernetes_node_group" "<имя_группы_узлов>" { ... timeouts { create = "1h30m" update = "1h30m" delete = "30m" } } -
-
Создайте приложение Kubernetes
-
Создайте файл
hello.yamlи добавьте в него спецификацию ресурса Deployment для создания приложения:apiVersion: apps/v1 kind: Deployment metadata: name: hello spec: replicas: 2 selector: matchLabels: app: hello template: metadata: labels: app: hello spec: containers: - name: hello-app image: cr.yandexcloud.kz/crpjd37scfv653nl11i9/hello:1.1 -
Создайте приложение:
kubectl apply -f hello.yaml -
Убедитесь, что приложение создано:
kubectl get deploymentРезультат:
NAME READY UP-TO-DATE AVAILABLE AGE hello 2/2 2 2 17h
Создайте сервис типа LoadBalancer
Когда вы создаете сервис типа LoadBalancer, контроллер Yandex Cloud в вашем каталоге устанавливает сетевой балансировщик нагрузки. Он тарифицируется по установленным в Network Load Balancer правилам тарификации.
Важно
- Созданный сетевой балансировщик тарифицируется согласно установленным правилам тарификации.
- Не изменяйте и не удаляйте сетевой балансировщик и целевые группы, которые будут автоматически созданы в вашем каталоге, через интерфейсы Yandex Cloud (консоль управления, Terraform, CLI и API). Это может привести к некорректной работе кластера.
Чтобы создать сервис типа LoadBalancer:
-
Выберите и подготовьте спецификацию сервиса в зависимости от нужного типа балансировщика:
Внешний балансировщикВнутренний балансировщик-
Создайте файл
load-balancer.yamlи добавьте в него следующую спецификацию сервиса:apiVersion: v1 kind: Service metadata: name: hello spec: type: LoadBalancer ports: - port: <порт_приложения> name: plaintext targetPort: 8080 selector: <Kubernetes-метки>В спецификации укажите:
-
spec.ports.port— порт приложения.В примере предполагается, что приложение Kubernetes доступно по протоколу HTTP, поэтому укажите значение
80. Если нужен доступ к приложению по HTTPS, укажите значение443. -
spec.selector— Kubernetes-метки, заданные в полеspec.selector.matchLabelsресурсаDeployment.В созданном ранее ресурсе
Deploymentиспользуется меткаapp: hello, поэтому укажите ее.
Подробнее о спецификации см. в справочнике сервиса.
-
-
(Опционально) Зарезервируйте статический публичный IP-адрес и добавьте его в спецификацию:
... spec: loadBalancerIP: <статический_IP-адрес> ...Примечание
Если не указать статический IP-адрес, сетевому балансировщику нагрузки будет назначен динамический IP-адрес.
-
Создайте файл
load-balancer.yamlи добавьте в него следующую спецификацию сервиса:apiVersion: v1 kind: Service metadata: name: hello annotations: yandex.cloud/load-balancer-type: internal yandex.cloud/subnet-id: <идентификатор_подсети_кластера> spec: type: LoadBalancer ports: - port: <порт_приложения> name: plaintext targetPort: 8080 selector: <Kubernetes-метки>В спецификации укажите:
-
yandex.cloud/subnet-id— идентификатор подсети, в которой расположен кластер. Идентификатор можно получить вместе с информацией о подсети. -
spec.ports.port— порт приложения.В примере предполагается, что приложение Kubernetes доступно по протоколу HTTP, поэтому укажите значение
80. Если нужен доступ к приложению по HTTPS, укажите значение443. -
spec.selector— Kubernetes-метки, заданные в полеspec.selector.matchLabelsресурсаDeployment.В созданном ранее ресурсе
Deploymentиспользуется меткаapp: hello, поэтому укажите ее.
Подробнее о спецификации см. в справочнике сервиса.
-
-
(Опционально) Зарезервируйте статический внутренний IP-адрес и добавьте его в спецификацию:
... spec: loadBalancerIP: <статический_IP-адрес> ...Примечание
Если не указать статический IP-адрес, сетевому балансировщику нагрузки будет назначен динамический IP-адрес.
-
-
(Опционально) Добавьте политику управления трафиком:
... spec: externalTrafficPolicy: <Cluster_или_Local> ...Возможные значения:
-
Cluster — трафик направляется на разные узлы Kubernetes (значение по умолчанию). В результате трафик распределяется равномерно, но у такого подхода есть недостатки:
- Пакет может прийти на прокси одного узла и без необходимости перенаправиться на другой узел. Такое поведение вызвает задержки во время выполнения операций и отправки пакетов.
- Под, который получает пакет, видит IP-адрес проксирующего узла, а не клиента. В результате исходный IP-адрес клиента не сохраняется.
-
Local — трафик проксируется и распределяется между подами на одном и том же узле. Трафик направляется на узел через порт, указанный в сервисе типа LoadBalancer или NodePort
.Так как трафик приходит на конкретный узел, он распределяется между узлами неравномерно. Зато IP-адрес клиента сохраняется.
Подробнее о политиках управления внешним трафиком читайте в документации Kubernetes
. -
-
(Опционально) Подключите проверки доступности узлов (health checks).
Сервисы типа
LoadBalancerв Managed Service for Kubernetes могут выполнять запросы на проверку состояния целевой группы. На основе полученных метрик Managed Service for Kubernetes принимает решение о доступности узлов.Чтобы включить проверки доступности узлов, укажите следующие аннотации в спецификации сервиса:
... metadata: ... annotations: yandex.cloud/load-balancer-healthcheck-healthy-threshold: "2" yandex.cloud/load-balancer-healthcheck-interval: "2s"Используемые аннотации:
yandex.cloud/load-balancer-healthcheck-healthy-threshold— количество последовательных удачных проверок, при достижении которого узел кластера считается доступным.yandex.cloud/load-balancer-healthcheck-interval— интервал выполнения проверок в секундах.
-
Создайте сетевой балансировщик нагрузки:
kubectl apply -f load-balancer.yaml
Проверьте доступность приложения
-
Посмотрите информацию о созданном сетевом балансировщике нагрузки и получите его IP-адрес:
Консоль управленияkubectl-
В консоли управления
выберите ваш каталог по умолчанию. -
Перейдите в сервис Network Load Balancer.
-
На вкладке Балансировщики отображен сетевой балансировщик нагрузки с префиксом
k8sв имени и уникальным идентификатором вашего кластера Kubernetes в описании.Скопируйте адрес балансировщика в столбце IP-адрес.
kubectl describe service helloРезультат:
Name: hello Namespace: default Labels: <none> Annotations: <none> Selector: app=hello Type: LoadBalancer IP: 172.20.169.7 LoadBalancer Ingress: 130.193.50.111 Port: plaintext 80/TCP TargetPort: 8080/TCP NodePort: plaintext 32302/TCP Endpoints: 10.1.130.4:8080 Session Affinity: None External Traffic Policy: Cluster Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal EnsuringLoadBalancer 2m43s service-controller Ensuring load balancer Normal EnsuredLoadBalancer 2m17s service-controller Ensured load balancerСкопируйте адрес балансировщика в поле
LoadBalancer Ingress. -
-
Убедитесь, что приложение доступно. Процесс проверки зависит от типа балансировщика:
Внешний балансировщикВнутренний балансировщикВыполните команду:
curl http://<IP-адрес_балансировщика>Результат:
Hello, world! Running in 'hello-********'-
В подсети кластера Managed Service for Kubernetes создайте виртуальную машину Linux.
Так как вы развернули внутренний сетевой балансировщик нагрузки, проверить доступ к приложению Kubernetes можно только из подсети кластера.
-
Проверьте доступность приложения Kubernetes:
curl http://<IP-адрес_балансировщика>Результат:
Hello, world! Running in 'hello-********'
Примечание
Если ресурс недоступен по указанному URL, то убедитесь, что группы безопасности для кластера Managed Service for Kubernetes и его групп узлов настроены корректно. Если отсутствует какое-либо из правил — добавьте его.
-
(Опционально) Создайте объект NetworkPolicy
Чтобы подключиться с определенных IP-адресов к сервисам, опубликованным через Network Load Balancer, включите сетевые политики в кластере. Для настройки доступа через балансировщик создайте объект NetworkPolicyIngress.
Пример настройки объекта NetworkPolicy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: whitelist-netpol
namespace: ns-example
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
# Диапазоны адресов, используемые балансировщиком для проверки состояния узлов.
- ipBlock:
cidr: 198.18.235.0/24
- ipBlock:
cidr: 198.18.248.0/24
# Диапазоны адресов подов.
- ipBlock:
cidr: 172.16.1.0/12
- ipBlock:
cidr: 172.16.2.0/12
Подробнее см. в справочнике ресурса NetworkPolicy.
Удалите созданные ресурсы
Удалите ресурсы, которые вы больше не будете использовать, чтобы за них не списывалась плата:
-
Удалите ресурсы в зависимости от способа их создания:
ВручнуюTerraform-
В терминале перейдите в директорию с планом инфраструктуры.
Важно
Убедитесь, что в директории нет Terraform-манифестов с ресурсами, которые вы хотите сохранить. Terraform удаляет все ресурсы, которые были созданы с помощью манифестов в текущей директории.
-
Удалите ресурсы:
-
Выполните команду:
terraform destroy -
Подтвердите удаление ресурсов и дождитесь завершения операции.
Все ресурсы, которые были описаны в Terraform-манифестах, будут удалены.
-
-
-
Если для доступа к кластеру Managed Service for Kubernetes или узлам использовались статические публичные IP-адреса, освободите и удалите их.