Використання Service для доступу до застосунку

Дізнайтесь про Service у Kubernetes. Ознайомтесь з тим, як мітки та селектори повʼязані з Service. Відкрийте доступ до застосунку по за межами Kubernetes кластера.

Мета

  • Дізнатись про Service у Kubernetes.
  • Ознайомитись з тим, як мітки та селектори повʼязані з Service.
  • Відкрити доступ до застосунку по за межами Kubernetes кластера.

Огляд Сервісів в Kubernetes

Існування Podʼів в Kubernetes є обмеженими за часом, також вони мають свій життєвий цикл. Коли робочий вузол припиняє існування, також втрачаються Podʼи, які виконуються на цьому вузлі. ReplicaSet може динамічно приводити кластер до бажаного стану шляхом створення нових Podʼів, щоб ваш застосунок продовжував працювати. Наприклад, розгляньмо обробник зображень, що має 3 копії. Ці копії (репліки) можуть бути взаємозамінні; система форонтенду не повинна перейматися репліками бекенду або навіть тим, чи Pod втрачено та створено наново. Проте кожен Pod в кластері Kubernetes має унікальну IP-адресу, навіть Podʼи на одному вузлі, тому потрібно мати спосіб автоматичного узгодження змін серед Podʼів, щоб ваші застосунки продовжували працювати.

Service в Kubernetes є абстракцією, яка визначає логічний набір Podʼів та політику доступу до них. Serviceʼи забезпечують слабку звʼязаність між залежними Podʼами. Service визначається за допомогою YAML або JSON, так само як і всі обʼєкти Kubernetes. Набір Podʼів, на які призначений Service, зазвичай визначається селектором міток (label selector) (див. нижче, чому selector іноді не включають у специфікацію Service).

Хоча кожний Pod має унікальну IP-адресу, ці IP не доступні за межі кластера без використання Service. Serviceʼи уможливлюють надходження трафіку до ваших застосунків. Serviceʼи можуть бути оприлюднені у різний спосіб, за допомогою type у spec Service:

  • ClusterIP (типове значення) — відкриває доступ до внутрішнього IP Service в кластері. Цей тип робить Service доступним лише зсередини кластера.
  • NodePort — відкриває доступ до Service на тому ж порті кожного обраного вузла в кластері за допомогою NAT. Робить Service доступним ззовні кластера за допомогою <NodeIP>:<NodePort>. Є надмножиною відносно ClusterIP.
  • LoadBalancer — створює зовнішній балансувальник навантаження в поточному хмарному середовищі (якщо підтримується) та призначає фіксовану зовнішню IP-адресу для Service. Є надмножиною відносно NodePort.
  • ExternalName — звʼязує Service з вмістом поля externalName (наприклад, foo.bar.example.com), повертаючи запис CNAME із його значенням. Не встановлюється жодного проксі. Цей тип вимагає v1.7 або вище kube-dns або CoreDNS версії 0.0.8 або вище.

Додаткову інформацію про різновиди Service можна знайти у посібнику Використання IP-адреси джерела. Дивіться також Підключення застосунків за допомогою Service.

Крім того, слід зауважити, що існують випадки використання Service, при яких не визначається selector у специфікації. Service, створений без selector, також не створить відповідний обʼєкт Endpoints. Це дозволяє користувачам вручну відкривати доступ Service на конкретні точки доступу. Ще одна можливість, чому може бути відсутній селектор — використання виключно type: ExternalName.

Зміст

  • Відкриття Podʼів для зовнішнього трафіка
  • Балансування навантаження трафіку між Podʼами
  • Використання міток

Service в Kubernetes – це рівень абстракції, який визначає логічний набір Podʼів і дозволяє експонування зовнішнього трафіку, балансування навантаження та виявлення служб для цих Podʼів.


Services та мітки (Labels)

Service маршрутизує трафік набору Podʼів. Service є абстракцією, яка дозволяє Podʼам зникати та реплікуватися в Kubernetes, не впливаючи на ваш застосунок. Виявлення та маршрутизація серед залежних Podʼів (таких як компоненти frontend та backend у застосунку) обробляються Serviceʼами Kubernetes.

Service визначають набір Podʼів за допомогою міток та селекторів, примітиву гуртування, який дозволяє логічно взаємодіяти з обʼєктами в Kubernetes. Мітки — це пари ключ/значення, призначені обʼєктам та можуть бути використані різними способами:

  • Призначення обʼєктів до оточення розробки, тестування та експлуатації
  • Вбудовування теґів версій
  • Класифікація обʼєкта за допомогою теґів


Мітки можна прикріплювати до обʼєктів при їх створенні або пізніше. Їх можна змінювати в будь-який час. Давайте зараз використаємо Service для надання доступу до нашого застосунку та застосуємо деякі мітки.

Крок 1: Створення нового Service

Перевіримо, що наш застосунок працює. Ми використовуватимемо команду kubectl get та переглядатимемо наявні Podʼи:

kubectl get pods

Якщо Podʼи не запущені, це означає, що обʼєкти з попередніх кроків були видалені. У цьому випадку поверніться та створіть Deployment з посібника Використання kubectl для створення Deployment. Зачекайте кілька секунд та перегляньте список Podʼів знову. Ви можете продовжити, як тільки побачите, що один Pod працює.

Далі виведемо список наявних Serviceʼів у нашому кластері:

kubectl get services

У нас є Service з назвою kubernetes, яка створюється стандартно, коли minikube запускає кластер. Щоб створити новий Service та зробити зовнішній трафік доступним для нього, ми використовуватимемо команду expose з параметром NodePort.

kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080

Давайте знову запустимо команду get services:

kubectl get services

Тепер у нас є робочий Service з назвою kubernetes-bootcamp. Тут ми бачимо, що Service отримав унікальний IP в кластері, внутрішній порт та зовнішній IP (IP вузла).

Щоб дізнатися, який порт був відкритий ззовні (для Serviceʼу з type: NodePort), ми запустимо команду describe service:

kubectl describe services/kubernetes-bootcamp

Створимо змінну середовища з назвою NODE_PORT, яка матиме значення порту вузла:

export NODE_PORT="$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')"
echo "NODE_PORT=$NODE_PORT"

Тепер ми можемо перевірити, що застосунок отримав доступ за межі кластера, використовуючи curl, IP-адресу вузла та зовнішній порт:

curl http://"$(minikube ip):$NODE_PORT"

І, ми отримуємо відповідь від сервера. Service — працює.

Крок 2: Використання міток

Deployment автоматично створив мітку для нашого Podʼа. За допомогою команди describe deployment ви можете побачити імʼя (ключ) цієї мітки:

kubectl describe deployment

Використаємо цю мітку для отримання списку наших Podʼів. Ми використовуватимемо команду kubectl get pods з -l як параметр, за яким слідують значення мітки:

kubectl get pods -l app=kubernetes-bootcamp

Ви можете зробити те саме, щоб вивести список поточних служб:

kubectl get services -l app=kubernetes-bootcamp

Отримайте назву Podʼа та збережіть її в змінній середовища POD_NAME:

export POD_NAME="$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')"
echo "Name of the Pod: $POD_NAME"

Для застосування нової мітки ми використовуємо команду label за якою слідує тип обʼєкта, назва обʼєкта та нова мітка:

kubectl label pods "$POD_NAME" version=v1

Це додасть нову мітку до нашого Podʼа (ми закріпили версію програми для Podʼа), і ми можемо перевірити це за допомогою команди describe pod:

kubectl describe pods "$POD_NAME"

Тут ми бачимо, що мітка тепер прикріплена до нашого Podʼа. І тепер ми можемо отримати список Podʼів, використовуючи нову мітку:

kubectl get pods -l version=v1

І, ми бачимо Pod.

Крок 3: Видалення Service

Для видалення Service ви можете використовувати команду delete service. Тут також можна використовувати мітки:

kubectl delete service -l app=kubernetes-bootcamp

Переконайтеся, що Service видалено:

kubectl get services

Це підтверджує, що наш Service видалено. Щоб переконатися, що маршрут більше не відкритий, ви можете перевірити раніше відкриті IP та порт за допомогою curl:

curl http://"$(minikube ip):$NODE_PORT"

Це доводить, що застосунок більше не доступний ззовні кластера. Ви можете переконатись, що застосунок все ще працює за допомогою curl зсередини Podʼа:

kubectl exec -ti $POD_NAME -- curl http://localhost:8080

Тут ми бачимо, що застосунок працює. Це тому, що Deployment управляє застосунком. Для припинення роботи застосунку вам слід видалити також й Deployment.

Одразу, як тільки ви будете готові, переходьте до Запуску кількох екземплярів вашого застосунку.

Змінено August 06, 2024 at 5:35 PM PST: upstream sync (dae4f254c1)