Начало работы с нуля | Обнаружение сервисов и балансировка нагрузки в Kubernetes

Kubernetes

Автор | Технический эксперт Alibaba Си Хэн

Источник спроса

Зачем вам нужно обнаружение сервисов

В кластере K8s приложения развертываются через модули.В отличие от традиционного развертывания приложений, традиционные приложения развертываются на заданной машине.Мы знаем, как вызывать IP-адреса других машин. Однако в кластере K8s приложения развертываются через поды, а жизненный цикл подов недолгий. В течение жизненного цикла модуля, например, при его создании или уничтожении, его IP-адрес будет меняться, поэтому традиционный метод развертывания не может быть использован, а IP-адрес не может быть указан для доступа к указанному приложению.

Кроме того, при развертывании приложений K8s, хотя я ранее изучил режим развертывания приложений, мне все еще нужно создать группу pod, а затем эти группы pod должны предоставить унифицированную запись доступа и как контролировать нагрузку трафика баланс этой группы. Например, тестовая среда, предварительная версия и онлайн-среда должны поддерживать один и тот же шаблон развертывания и метод доступа в процессе развертывания. Потому что таким образом вы можете использовать один и тот же набор прикладных шаблонов для публикации напрямую в разных средах.

Сервис: обнаружение сервисов и балансировка нагрузки в Kubernetes.

Наконец, служба приложения должна быть открыта для доступа извне и должна быть предоставлена ​​внешним пользователям для вызова. В предыдущем разделе мы узнали, что сеть пода не является тем же сегментом сети, что и машина, так как же открыть сеть пода для внешнего доступа? Здесь требуется обнаружение службы.

file

В K8s обнаружение служб и балансировка нагрузки являются службами K8s. На рисунке выше показана архитектура Сервиса в K8s Сервис K8s обеспечивает доступ к внешней сети и сети pod, то есть доступ к внешней сети возможен через сервис, а доступ к сети pod также возможен через K8s Услуга.

Внизу K8s подключается к другому набору модулей, то есть он может балансировать нагрузку на набор модулей через службу K8s, что эквивалентно решению повторяющейся проблемы, упомянутой выше, или предоставлению унифицированной записи доступа для обнаружения службы, и затем можно получить доступ к внешней сети, разрешить доступ между различными модулями и предоставить единый адрес доступа.

2. Интерпретация вариантов использования

Давайте интерпретируем реальный вариант использования и посмотрим, как объявить и использовать службу pod K8s?

Синтаксис службы

file

Прежде всего, давайте посмотрим на грамматику службы K8s.Приведенное выше изображение на самом деле является структурой объявления K8s. В этой структуре много синтаксиса и много общего с некоторыми стандартными объектами K8s, представленными ранее. Например, метка label делает некоторые выборки, селектор делает некоторые выборки, а метка объявляет некоторые из своих меток.

Здесь есть новая точка знаний, которая заключается в том, чтобы определить протокол и порт для обнаружения службы службы K8s. Продолжайте смотреть на этот шаблон, который объявляет службу K8s с именем my-service, которая имеет метку app:my-service, и выбирает модуль с меткой app:MyApp в качестве своего бэкенда.

Последний — это протокол и порт обнаружения определенной службы.В этом примере мы определяем протокол TCP, порт — 80, а порт назначения — 9376. В результате доступ к порту службы 80 будет направлен на targetPort серверной части, то есть до тех пор, пока порт доступа 80 этой службы будет балансировать нагрузку на серверное приложение: порт 9376 модуля меток MyApp.

Создание и просмотр услуг

Как создать только что объявленный объект службы и какой эффект он имеет после создания? Через простую команду:

  • kubectl apply -f service.yaml

или

  • kubectl created -f service.yaml

Приведенная выше команда может просто создать такую ​​службу. После создания вы можете пройти:

  • kubectl discribe service

Чтобы увидеть результат после создания сервиса.

file

После того, как сервис будет создан, вы увидите, что его имя — my-service. Пространство имен, метка и селектор такие же, как мы объявили ранее. После объявления здесь будет сгенерирован IP-адрес. Этот IP-адрес является IP-адресом службы. К этому IP-адресу могут получить доступ другие модули в кластере. , что эквивалентно передаче этого IP-адреса обеспечивает единую запись доступа для модуля, а также обнаружение службы.

Также есть атрибут Endpoints, который мы можем увидеть через Endpoints: Какие поды выбираются объявленным ранее селектором? И в каком состоянии эти капсулы? Например, через селектор мы видим, что он выбирает IP этих подов и порт targetPort, объявленный этими подами.

file

Фактическая архитектура показана выше. После того, как сервис будет создан, он создаст виртуальный IP-адрес и порт в кластере, в кластере все поды и ноды смогут получить доступ к сервису через такой IP-адрес и порт. Служба подключит выбранный модуль и его IP-адрес к серверной части. Таким образом, при доступе через IP-адрес сервиса можно сбалансировать нагрузку на эти поды на бэкенде.

Когда жизненный цикл пода изменится, например, один из подов будет уничтожен, сервис автоматически удалит под из бэкенда. Это достигается: даже если жизненный цикл пода изменится, конечные точки, к которым он обращается, не изменятся.

Служба доступа в кластере

Как в кластере другие модули получают доступ к созданному нами сервису? Есть три способа:

  • Во-первых, мы можем получить к нему доступ через виртуальный IP-адрес службы.Например, недавно созданная служба my-service, через службу kubectl get svc или kubectl disscribe, вы можете увидеть, что ее виртуальный IP-адрес — 172.29.3.27, порт равен 80, а затем к адресу этой службы можно получить прямой доступ в модуле через этот виртуальный IP-адрес и порт.
  • Второй способ — получить прямой доступ к имени службы, полагаясь на разрешение DNS, то есть поды в одном и том же пространстве имен могут напрямую обращаться к только что объявленной службе через имя службы. В разных пространствах имен мы можем добавить «.» к имени службы, а затем добавить пространство имен, в котором находится служба, для доступа к службе. Например, если мы используем curl для прямого доступа к ней, то есть my-service:80 , мы можем получить доступ к сервису.
  • Третий — доступ через переменные среды.Когда модуль в том же пространстве имен запускается, K8s помещает некоторые IP-адреса, порты и некоторые простые конфигурации службы в модуль K8s с помощью переменных среды. После запуска контейнера пода K8s, читая переменные окружения системы, он считывает адрес, сконфигурированный другими службами в пространстве имен, или номер своего порта и т. д. Например, в поде в кластере вы можете напрямую получить значение переменной окружения через curl $, например MYSERVICESERVICEHOST — один из его IP-адресов, МОЙСЛУЖБА - это МОЕ, которое мы только что объявилиСЕРВИС, СЕРВИСPORT — это его номер порта, поэтому вы также можете запросить службу MY_SERVICE в кластере.

Headless Service

Особой формой обслуживания является Headless Service. Когда служба будет создана, вы можете указать clusterIP:None и сказать K8s, что мне не нужен clusterIP (то есть виртуальный IP в только что упомянутом кластере), и тогда K8s не будет назначать виртуальный IP-адрес этой службе. , у него нет виртуального IP-адреса Как добиться балансировки нагрузки и единого доступа?

Это работает следующим образом: модули могут быть напрямую преобразованы в IP-адреса всех внутренних модулей с помощью DNS через имя_службы, а адреса всех внутренних модулей могут быть преобразованы во все внутренние модули с помощью DNS-записей A. и клиент выбирает внутренний модуль. IP-адрес, эта запись A будет меняться в зависимости от жизненного цикла модуля, и возвращаемый список записей A также будет меняться, поэтому клиентское приложение должно возвращать все DNS из записи A. на IP-адрес в списке записей A, клиент самостоятельно выбирает подходящий адрес для доступа к модулю.

file

На приведенном выше рисунке вы можете увидеть отличие от только что объявленного нами шаблона, то есть добавление clusterIP:None посередине, что означает, что виртуальный IP-адрес не требуется. Фактический эффект заключается в том, что когда модуль кластера обращается к my-service, он напрямую разрешает IP-адреса всех служб, соответствующих этому модулю, возвращает его модулю, а затем выбирает IP-адрес в модуле для доступа к нему. напрямую.

Предоставление службы за пределами кластера

В предыдущем разделе узлы или модули в кластере получают доступ к службе. Как можно открыть службу для внешнего мира? Как на самом деле выставить приложение в общедоступную сеть для доступа? Здесь также есть два типа службы для решения этой проблемы: NodePort и LoadBalancer.

  • Метод NodePort заключается в том, чтобы выставить порт на узле на узле кластера (то есть на хосте узла кластера), что эквивалентно уровню переадресации после доступа к порту на узле, переадресация на Над виртуальным IP-адресом находится виртуальный IP-адрес службы на узле в данный момент.
  • Тип LoadBalancer — это еще один уровень преобразования в NodePort, только что упомянутый NodePort фактически является портом на каждом узле в кластере, а LoadBalancer — это еще один балансировщик нагрузки перед всеми узлами. Например, если вы устанавливаете SLB в облаке Alibaba, этот балансировщик нагрузки обеспечит унифицированную запись и балансировку нагрузки всего трафика, который он затрагивает, для модулей узлов каждого узла кластера. Затем модуль узла преобразуется в ClusterIP для доступа к фактическому модулю.

3. Демонстрация работы

Ниже приведена практическая демонстрация использования сервиса K8s в контейнерном сервисе Alibaba Cloud.

Создать сервис

Мы создали кластер контейнеров Alibaba Cloud, а затем настроили подключение с локального терминала к кластеру контейнеров Alibaba Cloud.

Прежде всего, мы можем передать kubectl get cs , мы видим, что мы нормально подключились к кластеру Alibaba Cloud Container Service.

file

Сегодня я буду использовать эти шаблоны, чтобы на практике испытать использование службы K8s в облачных сервисах Alibaba. Есть три шаблона, первый клиентский, который используется для имитации доступа к сервису K8s через сервис, а затем балансировка нагрузки на группу подов, объявленных в нашем сервисе.

file

В верхней части службы K8s, как только что было описано, мы создали шаблон службы K8s, в котором служба K8s будет балансировать нагрузку на порт 80 внутреннего модуля через порт 80, указанный внешним интерфейсом, а затем селектор выбирает метку run: nginx, некоторые из модулей идут в качестве его бэкэнда.

file

Потом создать набор подов с такой меткой, через что создать под? Это развертывание K8s, представленное ранее.Посредством развертывания мы можем легко создать набор модулей, а затем объявить на нем метку, такую ​​​​как run: nginx, и у него есть две копии, которые будут запускать два модуля одновременно.

file

Сначала создайте набор модулей, который должен создать это развертывание K8s, с помощью kubectl create -f service.yaml. Деплоймент тоже создан, посмотрим, создан ли pod. Как показано на рисунке ниже, оба модуля, созданные этим развертыванием, уже запущены. IP-адрес можно увидеть с помощью kubectl get pod -o wide. Фильтровать через -l, то есть по метке, run=nginx. Как показано на рисунке ниже, два модуля имеют IP-адреса 10.0.0.135 и 10.0.0.12 соответственно, и оба имеют метку run=nginx.

file

Далее давайте создадим сервис K8s, который будет выбирать эти два пода через только что представленный сервис. Сервис уже создан.

file

В соответствии с только что введенным, вы можете увидеть фактический статус этой службы через kubectl описать svc. Как показано на рисунке ниже, селектор только что созданной службы nginx имеет значение run=nginx, а адрес модуля, выбранный для серверной части с помощью селектора run=nginx, является адресом двух только что просмотренных модулей: 10.0.0.12 и 10.0. 0,135. Здесь вы можете видеть, что K8s генерирует для себя виртуальный IP-адрес в кластере, и через этот виртуальный IP-адрес он может балансировать нагрузку на следующие два пода.

file

Теперь перейдите к созданию клиентского модуля, чтобы на самом деле почувствовать, как получить доступ к этому сервису K8s, мы создаем клиентский модуль через client.yaml, kubectl get pod может видеть, что клиентский модуль создан и уже запущен.

file

Перейдите к поду через kubectl exec, войдите в под, чтобы испытать три только что упомянутых метода доступа, прежде всего, вы можете напрямую получить доступ к ClusterIP, сгенерированному для него K8s, который является виртуальным IP-адресом, получить доступ к этому IP-адресу через curl , это В стручке не установлен curl. Используйте wget IP-адрес и введите его, чтобы проверить. Видно, что доступ к фактическому IP-адресу через this может получить доступ к серверной части nginx.Этот виртуальный объект является единой записью.

file

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

file

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

file

Наконец, к введенному нами методу доступа также можно получить доступ через переменные среды.В этом модуле вы можете напрямую выполнить команду env, чтобы увидеть фактически введенные переменные среды. Взгляните на различные конфигурации службы nginx, которые были зарегистрированы.

file

Вы также можете получить доступ к такой переменной среды через wget, а затем получить доступ к одному из наших сервисов.

file

После представления этих трех методов доступа давайте посмотрим, как получить доступ через сеть вне службы. Мы напрямую модифицируем некоторые из сервисов, которые мы только что создали.

file

Наконец, мы добавляем тип LoadBalancer, который представляет собой метод внешнего доступа, который мы представили ранее.

file

Затем с помощью kubectl apply только что измененный контент вступит в силу непосредственно в созданном сервисе.

file

Теперь посмотрим, какие изменения будут внесены в сервис? С помощью kubectl get svc -o wide мы обнаружили, что только что созданный нами сервис nginx имеет дополнительный EXTERNAL-IP, который является IP-адресом для внешнего доступа. кластер. .

file

Тогда теперь на самом деле зайдите на этот внешний IP-адрес 39.98.21.187, почувствуйте, как выставить службу нашего приложения через службу, нажмите прямо в терминале, здесь вы можете увидеть, что мы напрямую обращаемся к конечной точке через внешнее приложение этого приложения, вы можете доступ к Этот сервис очень прост?

file

Наконец, давайте взглянем на использование службы для реализации службы обнаружения K8s, то есть адрес доступа службы не имеет ничего общего с жизненным циклом модуля. Давайте сначала посмотрим на два IP-адреса модуля, выбранные после текущего сервиса.

file

Теперь мы удаляем один из модулей и удаляем предыдущий модуль через kubectl delete.

file

Мы знаем, что развертывание позволит автоматически сгенерировать новый модуль, и теперь IP-адрес изменился на 137.

file

Теперь переходим к описанию службы только сейчас, как показано на рисунке ниже, вы можете видеть, что предыдущая конечная точка доступа состоит в том, что IP-адрес кластера не изменился, и IP-адрес внешнего LoadBalancer не изменился. Во всех случаях, которые не влияют на доступ клиента, IP-адрес пода серверной части автоматически помещается в серверную часть службы.

file

Это эквивалентно тому, что вы не заботитесь об изменении жизненного цикла пода при вызове компонента приложения.

Это все для демонстрации.

4. Архитектурный дизайн

Наконец, простой анализ дизайна K8s и некоторых принципов реализации.

Архитектура обнаружения сервисов Kubernetes

file

Как показано на рисунке выше, обнаружение службы K8s и служба K8s представляют собой такую ​​общую архитектуру.

K8s делится на главные узлы и рабочие узлы:

  • Мастер — это в основном контент, контролируемый K8s;
  • Внутри рабочего узла находится место, где фактически выполняется пользовательское приложение.

В главном узле K8s есть APIServer, где все объекты K8s управляются унифицированным образом.Все компоненты будут зарегистрированы на APIServer для отслеживания изменений этого объекта.Например,изменяется жизненный цикл нашего компонента pod , эти события.

Здесь есть три ключевых компонента:

  • Одним из них является Cloud Controller Manager, который отвечает за настройку балансировщика нагрузки LoadBalancer для внешнего доступа;
  • Другой — Coredns, который предназначен для наблюдения за изменением в модуле серверной части службы в APIServer через Coredns, для настройки разрешения DNS службы и для прямого доступа к виртуальному IP-адресу службы через имя службы или в Безголовый тип Сервиса Парсинг списков IP;
  • Затем в каждом узле будет компонент kube-proxy, который прослушивает изменения службы и модуля, а затем фактически настраивает модуль узла в кластере или доступ к виртуальному IP-адресу.

Как выглядит фактическая ссылка доступа? Например, доступ к Сервису из Client Pod3 внутри кластера аналогичен только что продемонстрированному эффекту. Client Pod3 сначала разрешает ServiceIP через Coredns. Coredns возвращает IP-адрес службы, соответствующий его ServiceName. Client Pod3 использует этот IP-адрес службы для выполнения запроса. После того, как его запрос достигнет сети хоста, он будет -proxy выполняет уровень обработки перехвата, а затем балансирует нагрузку для каждого фактического внутреннего модуля, таким образом реализуя балансировку нагрузки и обнаружение сервисов.

Для внешнего трафика, например, запрос, только что полученный через общедоступную сеть. Это балансировщик нагрузки, настроенный внешним диспетчером облачного контроллера балансировщика нагрузки для отслеживания изменений службы, а затем перенаправленный на NodePort на узле.NodePort также проходит через конфигурацию kube-proxy.iptables, преобразует трафик NodePort в ClusterIP и затем преобразует его в IP-адрес модуля в бэкэнде для балансировки нагрузки и обнаружения сервисов. Это полное обнаружение службы K8s и общая структура службы K8s.

следовать за

В последующей продвинутой части мы подробнее объясним принцип реализации службы K8s, а также навыки диагностики и устранения неполадок в сервисной сети.

Резюме этой статьи

На этом основное содержание этой статьи заканчивается, вот вам краткое изложение:

  1. Почему облачные сценарии требуют обнаружения служб и балансировки нагрузки?
  2. Как использовать службу Kubernetes для обнаружения служб и балансировки нагрузки в Kubernetes
  3. Компоненты, задействованные в Сервисе в кластере Kubernetes, и общий принцип реализации

Я считаю, что после изучения и освоения этой статьи вы сможете быстро и стандартно управлять сложными приложениями корпоративного уровня с помощью Kubernetes Service.

«Официальная учетная запись Alibaba Cloud Native WeChat (идентификатор: Alicloudnative) фокусируется на микросервисах, бессерверных технологиях, контейнерах, Service Mesh и других технических областях, фокусируется на популярных тенденциях облачных технологий и крупномасштабном внедрении облачных технологий, а также — самый знающий облачный разработчик. Технический общедоступный аккаунт».