Перехід від Endpoints до EndpointSlices у Kubernetes

З моменту виходу початкової альфа-версії EndpointSlices (KEP-752) у v1.15 та їх загальної доступності з v1.21, мережеві можливості Kubernetes поступово відходять від застарілого API Endpoints
. Сучасні функції сервісів, такі як двохстекова мережа та вдосконалене розподілення трафіку, реалізуються виключно через EndpointSlices. Внаслідок цього всі проксі-сервіси, шлюзи в кластері та кастомні контролери були оновлені для роботи з ресурсами discovery.k8s.io/v1
EndpointSlice
, а не з v1
Endpoints
. На сьогоднішній день API Endpoints
існує переважно для збереження зворотної сумісності з існуючими робочими навантаженнями та автоматизаційними сценаріями.
З версією Kubernetes 1.33 API Endpoints
офіційно вважається застарілим. Будь-яка операція читання або запису з v1 Endpoints
тепер викликає попередження про застарілість від API сервера, спонукаючи користувачів переходити до EndpointSlice
API. Тим часом, KEP-4974 визначає плани щодо видалення вимоги до Endpoints controller з тестів на відповідність Kubernetes, оскільки більшість сучасних кластерів більше не покладаються на нього.
Згідно з політикою застарілості Kubernetes, тип Endpoints
може залишатися в режимі тільки для читання або з попередженням безстроково. Однак користувачі з автоматизацією, CI/CD процесами чи контролерами, які все ще запитують або генерують Endpoints
, повинні перейти на EndpointSlices
, щоб уникнути майбутніх проблем, скористатися новими мережевими функціями та зменшити витрати під час виконання.
Примітки щодо міграції з Endpoints на EndpointSlices
Використання EndpointSlices замість Endpoints
Найзначніша зміна при використанні EndpointSlices
полягає в тому, що один сервіс може відповідати кільком EndpointSlices
. У той час як кожен сервіс з селектором генерує лише один об’єкт Endpoints
, названий так само, як і сервіс.
$ kubectl get endpoints myservice
Попередження: v1 Endpoints застаріло у v1.33+; використовуйте discovery.k8s.io/v1 EndpointSlice
NAME ENDPOINTS AGE
myservice 10.180.3.17:443 2h
$ kubectl get endpointslice -l kubernetes.io/service-name=myservice
NAME ADDRESSTYPE PORTS ENDPOINTS AGE
myservice-7vzhx IPv4 443 10.180.3.17 35s
myservice-jcv8s IPv6 443 2001:db8:123::5 35s
Як видно, двохстекові сервіси генерують два слайси — один для IPv4 і один для IPv6. Старий об’єкт Endpoints
показує лише адреси основної сім’ї. Контролер EndpointSlice
також розподіляє слайси за визначеннями портів і обмежує кожен слайс максимум до 100 кінцевих точок, щоб зменшити розмір об’єкта. Оскільки імена слайсів генеруються з унікальними суфіксами, споживачі повинні перераховувати слайси за міткою:
kubectl get endpointslice -l kubernetes.io/service-name=myservice
Нижче наведені ключові сценарії, в яких виникають кілька слайсів:
- Розділення IP-сімей: Кожен
EndpointSlice
може містити лише одну сім’ю адрес. Отже, двохстекові сервіси генерують окремі слайси для IPv4 та IPv6. - Зміни портів під час розгортання: Якщо ви вносите зміни, які модифікують порти контейнерів (наприклад, порт 80 → 8080), Kubernetes створить окремі слайси для старих і нових портів до завершення розгортання.
- Обмеження кількості кінцевих точок: Щоб уникнути створення великих об’єктів, контролер розподіляє кінцеві точки на кілька слайсів, як тільки їх кількість перевищує 100 адрес на слайс.
Генерація EndpointSlices замість Endpoints
Для контролерів або YAML-описів, які генерують дані про кінцеві точки, перехід на EndpointSlices
є простим. Схема змінюється незначно — переходячи від subsets
до масивів endpoints
верхнього рівня з флагами conditions.ready
для кожної кінцевої точки — і вимагає додавання мітки та addressType
. Приклад:
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
generateName: myservice-
labels:
kubernetes.io/service-name: myservice
addressType: IPv4
endpoints:
- addresses: ["10.180.3.17"]
nodeName: node-4
conditions:
ready: true
- addresses: ["10.180.5.22"]
nodeName: node-9
conditions:
ready: true
- addresses: ["10.180.6.6"]
nodeName: node-8
conditions:
ready: false
ports:
- name: https
protocol: TCP
port: 443
Ключові відмінності:
- Необхідно вказати
addressType
(IPv4
абоIPv6
). - Мітка
kubernetes.io/service-name
пов’язує слайс зі своїм сервісом. - Кожен запис
endpoints
включає умови для кожної кінцевої точки (готова/не готова), замінюючи окремі масивиaddresses
таnotReadyAddresses
. - Великі набори кінцевих точок автоматично розподіляються на кілька слайсів контролером, тому ручне розподілення не потрібне, якщо не реалізується кастомний контролер.
Врахування продуктивності
EndpointSlices зменшують споживання пам’яті та пропускної здатності API сервера, обмежуючи розмір об’єктів. Тестування від Kubernetes SIG-Network вказує на зменшення навантаження на події спостереження до 50% у великих кластерах (10,000+ кінцевих точок). Менші JSON-документи означають менше навантаження на CPU на kube-apiserver та нижчу затримку в kube-proxy і кастомних контролерах, які спостерігають за сервісами в масштабах.
Експериментальні тести показують, що в кластері з 5,000 вузлів з двохстековою архітектурою Kube-Proxy на основі EndpointSlice споживає приблизно на 30% менше CPU в порівнянні зі спостереженням за застарілими Endpoints, завдяки інкрементним оновленням та меншим розмірам списків. Крім того, функціональні можливості, такі як EndpointSliceProxying
, можуть бути включені для поступового впровадження поліпшень проксі в середовищах з суворими вимогами до стабільності.
Найкращі практики міграції
- Аудит існуючих контролерів: Визначте будь-які кастомні контролери або сценарії, що використовують
CoreV1().Endpoints()
, та сплануйте оновлення доDiscoveryV1().EndpointSlices()
. - Оновлення CRD та інструментів: Якщо ви керуєте кастомними ресурсами, що генерують кінцеві точки, додайте підтримку
EndpointSlice
та протестуйте під v1.33+ з увімкненими попередженнями. - Управління функціональними можливостями: Переконайтеся, що функціональні можливості
EndpointSlice
таEndpointSliceProxying
увімкнені на обох API сервері та контролері-менеджері в тестових кластерах перед розгортанням у продакшені. - Поступове впровадження: Використовуйте двохстекові або мультіпортові тестові сервіси для перевірки поведінки розподілу слайсів та моніторингу метрик з kube-proxy та CNI плагінів.
Майбутні напрямки та дорожня карта
KEP-4974 передбачає остаточне видалення контролера Endpoints
з тестів на відповідність та можливу деактивацію в kube-controller-manager. Хоча API об’єкт може залишатися безстроково для сумісності, утримувачі SIG-Network розглядають режим видалення Endpoints як приховану функціональну можливість, що додатково зменшить навантаження на CPU контролера-менеджера в масштабних кластерах. У майбутніх вдосконаленнях discovery.k8s.io/v1
передбачаються більш детальні topologyHints
та розширена метадані кінцевих точок для інтеграцій з сервісними мережами.
З ростом впровадження Kubernetes у випадках використання на краю та в IoT, EndpointSlices закладають основи для ефективного виявлення сервісів у багатокластерному середовищі, дозволяючи федеративним контролерам агрегувати слайси з різних регіонів з мінімальними витратами. Організації, що планують майбутнє розширення, повинні завершити свою міграцію, щоб розблокувати ці вдосконалені мережеві можливості.