EndpointSlices

API EndpointSlice — це механізм, який Kubernetes використовує, щоб ваш Service масштабувався для обробки великої кількості бекендів і дозволяє кластеру ефективно оновлювати свій список справних бекендів.
СТАН ФУНКЦІОНАЛУ: Kubernetes v1.21 [stable]

EndpointSlice API Kubernetes надає можливість відстежувати мережеві точки доступу в межах кластера Kubernetes. EndpointSlices пропонують більш масштабований та розширюваний альтернативний варіант Endpoints.

EndpointSlice API

У Kubernetes, EndpointSlice містить посилання на набір мережевих точок доступу. Панель управління автоматично створює EndpointSlices для будь-якої служби Kubernetes, яка має вказаний селектор. Ці EndpointSlices містять посилання на всі Podʼи, які відповідають селектору Service. EndpointSlices групують мережеві точки доступу за унікальними комбінаціями протоколу, номеру порту та імені Service. Імʼя обʼєкта EndpointSlice повинно бути дійсним імʼям піддомену DNS.

Наприклад, ось приклад обʼєкта EndpointSlice, яким володіє Service Kubernetes з імʼям example.

apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
  name: example-abc
  labels:
    kubernetes.io/service-name: example
addressType: IPv4
ports:
  - name: http
    protocol: TCP
    port: 80
endpoints:
  - addresses:
      - "10.1.2.3"
    conditions:
      ready: true
    hostname: pod-1
    nodeName: node-1
    zone: us-west2-a

Типово, панель управління створює та керує EndpointSlices так, щоб в кожному з них було не більше 100 мережевих точок доступу. Це можна налаштувати за допомогою прапорця --max-endpoints-per-slice kube-controller-manager, до максимуму 1000.

EndpointSlices можуть виступати джерелом правди для kube-proxy щодо того, як маршрутизувати внутрішній трафік.

Типи адрес

EndpointSlices підтримують три типи адрес:

  • IPv4
  • IPv6
  • FQDN (Fully Qualified Domain Name — Повністю Кваліфіковане Доменне Імʼя)

Кожен обʼєкт EndpointSlice представляє конкретний тип IP-адреси. Якщо у вас є Service, який доступний через IPv4 та IPv6, буде принаймні два обʼєкти EndpointSlice (один для IPv4 та один для IPv6).

Стани

API EndpointSlice зберігає стани точок доступу, які можуть бути корисні для споживачів. Три стани: ready, serving та terminating.

Ready

ready — це стан, який відповідає стану Ready Pod. Запущений Pod зі станом Ready встановленим в True повинен мати стан ready також встановлений в true. З міркувань сумісності, ready НІКОЛИ не буває true, коли Pod видаляється. Споживачі повинні звертатися до стану serving, щоб перевірити готовність Podʼів, які видаляються. Єдиний виняток є для Services з spec.publishNotReadyAddresses, встановленим в true. Podʼи для цих служб завжди матимуть стан ready, встановлений в true.

Serving

СТАН ФУНКЦІОНАЛУ: Kubernetes v1.26 [stable]

Стан serving майже ідентичний стану ready. Різниця полягає в тому, що споживачі API EndpointSlice повинні перевіряти стан serving, якщо їм важливо перевірити готовність Podʼів в той час, коли Pod також примусово припиняє свою роботу.

Terminating

СТАН ФУНКЦІОНАЛУ: Kubernetes v1.22 [beta]

Terminating — це стан, що вказує, чи Pod видаляється. Для Podʼів це буде будь-який Pod з встановленою часовою міткою видалення.

Інформація про топологію

Кожна точка доступу в межах EndpointSlice може містити відповідну інформацію про топологію. Інформація про топологію включає місцезнаходження точки доступу та інформацію про відповідний вузол та зону. Ця інформація доступна в наступних полях на кожній кінцевій точці в EndpointSlices:

  • nodeName — Назва вузла, на якому знаходиться ця точка доступу.
  • zone — Зона, в якій знаходиться ця точка доступу.

Управління

Зазвичай обʼєкти EndpointSlice створюються та керуються панеллю управління зокрема, контролером EndpointSlice. Є різноманітні інші випадки використання EndpointSlices, такі як реалізації Service mesh, які можуть призвести до інших сутностей або контролерів, які керують додатковими наборами EndpointSlices.

Щоб забезпечити можливість кількох сутностей керувати EndpointSlices без взаємодії одна з одною, Kubernetes визначає label endpointslice.kubernetes.io/managed-by, яка вказує сутність, яка керує EndpointSlice. Контролер встановлює значення endpointslice-controller.k8s.io для цієї мітки на всіх точках доступу, якими він керує. Інші сутності, які керують EndpointSlices, також повинні встановити унікальне значення для цієї мітки.

Власність

У більшості випадків EndpointSlices належать Service, за яким обʼєкт EndpointSlices стежить для виявлення точок доступу. Право власності вказується власником посиланням на кожен EndpointSlice, а також міткою kubernetes.io/service-name для простого пошуку всіх EndpointSlices, які належать Service.

Віддзеркалення EndpointSlice

У деяких випадках застосунки створюють власні ресурси Endpoints. Щоб забезпечити що ці застосунки не повинні одночасно записувати як в ресурси Endpoints, так і в ресурси EndpointSlice, панель управління кластера віддзеркалює більшість ресурсів Endpoints на відповідні ресурси EndpointSlices.

Панель управління віддзеркалює ресурси Endpoints, якщо:

  • ресурс Endpoints має мітку endpointslice.kubernetes.io/skip-mirror встановлену в true.
  • ресурс Endpoints має анотацію control-plane.alpha.kubernetes.io/leader.
  • відповідний ресурс Service не існує.
  • відповідний ресурс Service має ненульовий селектор.

Окремі ресурси Endpoints можуть транслюватись в кілька ресурсів EndpointSlices. Це може відбуватись, якщо ресурс Endpoints має кілька підмножин або включає точки доступу з кількома сімействами IP (IPv4 та IPv6). Максимально 1000 адрес на підмножину буде віддзеркалено на EndpointSlices.

Розподіл EndpointSlices

Кожен EndpointSlice має набір портів, які застосовуються до всіх точок доступу ресурсу. При використанні іменованих портів для Service, Podʼи можуть мати різні номери цільового порту для того самого іменованого порту, що вимагає різних EndpointSlices. Це схоже на логіку того, як підмножини групуються з Endpoints.

Панель управління намагається заповнити EndpointSlices так повно, як це можливо, але не активно перерозподіляє їх. Логіка досить проста:

  1. Пройдіться по наявних EndpointSlices, вилучіть точки доступу, які вже не потрібні, і оновіть відповідні точки, які змінилися.
  2. Пройдіться по EndpointSlices, які були змінені на першому етапі, і заповніть їх будь-якими новими точками доступу, які потрібно додати.
  3. Якщо ще залишилися нові точки доступу для додавання, спробуйте додати їх в раніше не змінений EndpointSlice та/або створіть новий.

Важливо, що третій крок надає пріоритет обмеженню оновлень EndpointSlice над ідеально повним розподілом EndpointSlices. Наприклад, якщо є 10 нових точок доступу для додавання та 2 EndpointSlices з простором для ще 5 точок доступу кожна, цей підхід створить новий EndpointSlice замість заповнення 2 наявних EndpointSlices. Іншими словами, одне створення EndpointSlice краще, ніж кілька оновлень EndpointSlice.

З kube-proxy, який працює на кожному вузлі та слідкує за EndpointSlices, кожна зміна EndpointSlice стає відносно дорогою, оскільки вона буде передана кожному вузлу в кластері. Цей підхід призначений для обмеження кількості змін, які потрібно надіслати кожному вузлу, навіть якщо це може призвести до декількох EndpointSlices, які не є повністю заповненими.

На практиці це рідко трапляється. Більшість змін опрацьовуються контролером EndpointSlice буде достатньо малою, щоб поміститися в наявний EndpointSlice, і якщо ні, новий EndpointSlice, ймовірно, буде потрібен невдовзі. Поступові оновлення Deploymentʼів також надають природню перепаковку EndpointSlices з всіма Podʼами та їх відповідними точками доступу, що заміняються.

Дублікати endpoints

Через характер змін EndpointSlice точки доступу можуть бути представлені в більш ніж одному EndpointSlice одночасно. Це, природно, відбувається, оскільки зміни до різних обʼєктів EndpointSlice можуть надходити до клієнта Kubernetes watch / cache в різний час.

Порівняння з Endpoints

Оригінальний API Endpoints надавав простий і зрозумілий спосіб відстеження мережевих точок доступу в Kubernetes. Однак з ростом кластерів Kubernetes та Serviceʼів, які обробляють більше трафіку і надсилають трафік до більшої кількості підзадач, обмеження оригінального API стали більш помітними. Зокрема, до них входили проблеми масштабування до більшої кількості мережевих точок доступу.

Оскільки всі мережеві точки доступу для Service зберігалися в одному ресурсі Endpoints, ці обʼєкти Endpoints могли бути досить великими. Для служб, які залишалися стабільними (тобто тим самим набором точок доступу протягом тривалого періоду часу), вплив був менше помітний; навіть тоді деякі випадки використання Kubernetes працювали не дуже добре.

Коли у Service було багато точок доступу бекенду, а робочі навантаження або часто масштабуються, або до них часто вносилися нові зміни, кожне оновлення єдиного обʼєкта Endpoints для цього Service означало багато трафіку між компонентами кластера Kubernetes (в межах панелі управління, а також між вузлами та сервером API). Цей додатковий трафік також мав вартість у термінах використання ЦП.

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

EndpointSlices також включили інновації щодо нових можливостей, таких як мережі з подвійним стеком і маршрутизація з урахуванням топології.

Що далі

Змінено June 20, 2024 at 12:44 PM PST: Sync changest from andygol/k8s-website (36d05bc8a1)