Що таке Service в Kubernetes
Поди в Kubernetes ефемерні: вони часто перезапускаються, переміщуються на інші вузли і щоразу отримують абсолютно нову динамічну IP-адресу:
🟢 Junior Level
30-секундна відповідь
Service (Сервіс) — це абстрактний об’єкт Kubernetes, що надає єдину стабільну точку входу (віртуальну IP-адресу та DNS-ім’я) і балансувальник навантаження транспортного рівня (L4) для динамічної групи подів.
Поди в Kubernetes ефемерні: вони часто перезапускаються, переміщуються на інші вузли і щоразу отримують абсолютно нову динамічну IP-адресу:
- Якби мікросервіси зверталися один до одного напряму за IP подів, будь-яке перезавантаження ламало б усю систему.
- Service вирішує цю проблему: сервіс отримує постійну віртуальну адресу (ClusterIP), яка ніколи не змінюється протягом усього життєвого циклу сервісу.
- Клієнти звертаються за стабільним іменем (наприклад,
http://payment-service:80), а Kubernetes автоматично перенаправляє та балансує мережеві пакети між здоровими подами.
Наочна аналогія з життя
Уявіть кол-центр великого банку:
- Оператори підтримки — це поди (вони йдуть на перерву, змінюються під час чергування, їхня кількість зростає в години пік).
- Service — це єдиний номер гарячої лінії (наприклад,
0-800-100-000). - Клієнту не потрібно знати домашній телефон або прізвище конкретного чергового оператора. Клієнт набирає один спільний номер, а телефонна станція автоматично з’єднує його з будь-яким вільним оператором на лінії.
Базовий приклад маніфесту Service
apiVersion: v1
kind: Service
metadata:
name: payment-service
spec:
type: ClusterIP # Доступний лише всередині кластера
selector:
app: payment-service # Шукає всі поди з міткою app=payment-service
ports:
- name: http
port: 80 # Порт, на якому Service слухає запити
targetPort: 8080 # Порт всередині контейнера Pod (куди пересилати трафік)
Всередині кластера будь-який інший застосунок звертається до нього через DNS:
curl http://payment-service:80/api/v1/pay
🟡 Middle Level
Як Service знаходить поди: Селектори та Endpoints
Зв’язок між Service та подами є слабкозв’язаним і будується на мітках (Labels):
- У секції
spec.selectorсервіс вказує критерії пошуку (наприклад,app: payment-service). - Kubernetes безперервно сканує поди з такими мітками.
- IP-адреси всіх подів, які успішно пройшли перевірку
readinessProbe, автоматично заносяться в дочірній системний об’єкт —Endpoints(абоEndpointSlice): ```yaml apiVersion: v1 kind: Endpoints metadata: name: payment-service subsets:- addresses:
- ip: 10.244.1.15
- ip: 10.244.2.34 ports:
- port: 8080 ```
- addresses:
- Якщо под падає або зависає (readiness probe зазнає невдачі), контролер миттєво видаляє його IP зі списку
Endpoints, і трафік припиняє на нього надходити.
Розв’язання доменних імен (CoreDNS)
Кожен створений Service автоматично реєструється у вбудованому DNS-сервері кластера (CoreDNS). Повне доменне ім’я (FQDN) має вигляд: \(\mathbf{<service\text{-}name>.<namespace>.svc.cluster.local}\)
- У межах одного й того самого Namespace достатньо звернутися за коротким ім’ям:
http://payment-service. - При виклику з іншого Namespace вказується двокомпонентне ім’я:
http://payment-service.prod.
4 основні типи Service
| Тип | Де доступний | Для чого використовується |
| :— | :— | :— |
| ClusterIP (дефолт)| Лише всередині K8s кластера | Внутрішня міжсервісна взаємодія мікросервісів. |
| NodePort | На виділеному порту кожного фізичного вузла (Node) | Локальне тестування, налагодження (діапазон 30000–32767). |
| LoadBalancer | У публічному інтернеті | Створює зовнішній балансувальник хмарного провайдера (AWS NLB, GCP LB). |
| ExternalName | Всередині кластера як CNAME-аліас | Прокидання зовнішніх баз даних (наприклад, db.rds.amazonaws.com) у DNS K8s. |
🔴 Senior Level
Як працює ClusterIP під капотом: Магія kube-proxy
Senior-інженер зобов’язаний розуміти, що ClusterIP — це фіктивна віртуальна IP-адреса (Virtual IP / VIP).
- У кластері НЕМАЄ фізичного мережевого інтерфейсу, якому була б призначена ця IP-адреса.
- За обробку пакетів відповідає агент
kube-proxy, що функціонує на кожному вузлі в одному з трьох режимів:
[ Пакет на ClusterIP:80 ]
│
▼
[ Ядро Linux: Netfilter / iptables / IPVS ]
│ (DNAT підміна IP призначення на льоту)
▼
[ Реальний IP пода: 10.244.2.34:8080 ]
1. Режим iptables (за замовчуванням у більшості кластерів)
kube-proxyне перехоплює трафік сам. Він лише транслює конфігурацію сервісів у ланцюжки правилiptablesядра Linux у таблиціnat.- Для балансування використовується модуль ядра
statisticз імовірнісним механізмом (Random Probability):- Для 3 подів перше правило спрацьовує з імовірністю $1/3$, друге — $1/2$, третє забирає залишок.
- Проблема масштабування: додавання та перевірка правил вимагає лінійного обходу $O(N)$. При $10\,000+$ сервісів перерахунок правил починає утилізувати до 100% CPU одного ядра процесора.
2. Режим IPVS (IP Virtual Server)
- Використовує транспортний L4-балансувальник, вбудований безпосередньо в ядро Linux.
- Зберігає відповідності в хеш-таблицях з константною складністю пошуку $O(1)$.
- Підтримує складні алгоритми розподілу:
round-robin,least connections,source hashing. Ідеальний для великих кластерів під високим навантаженням.
3. eBPF (Cilium CNI)
- Повністю виключає
kube-proxyі стекiptables/conntrack. - Програми eBPF перехоплюють пакети безпосередньо на мережевому сокеті ядра через інтерфейс XDP (eXpress Data Path), забезпечуючи мінімально можливу затримку (Zero-overhead networking).
EndpointSlice API: Захист etcd від Watch Storm
У ранніх версіях Kubernetes (до 1.21) усі IP-адреси подів сервісу зберігалися в одному монолітному об’єкті Endpoints.
- Якщо у сервісу 5000 подів, то при падінні лише одного пода пересилався весь об’єкт розміром 2 МБ на всі вузли кластера.
- Це спричиняло перевантаження API-сервера та
etcd(Watch Storm). - Сучасне рішення —
EndpointSlice: K8s автоматично нарізає список ендпоінтів на компактні слайси по 100 адрес у кожному. При зміні одного пода оновлюється лише один слайс розміром у пару кілобайт.
Headless Service (clusterIP: None)
Якщо у специфікації вказати clusterIP: None:
- Kubernetes НЕ виділяє віртуальний VIP і не налаштовує правила балансування в
kube-proxy. - При DNS-запиті до сервісу CoreDNS повертає повний список A-записів з реальними IP-адресами всіх здорових подів.
- Застосування: розподілені Stateful-системи (Kafka, Cassandra, MongoDB), де Java-клієнт повинен сам керувати з’єднаннями до конкретних нод-лідерів і реплік.
4 Tricky Questions
1. Чому спроба надіслати ICMP-запит ping <ClusterIP> зсередини пода завжди завершується 100% втратою пакетів, хоча HTTP-запити через curl працюють миттєво?
Відповідь:
Віртуальна IP-адреса сервісу (ClusterIP) існує виключно як правило підміни мережевих адрес (DNAT) у підсистемі ядра Netfilter (iptables або IPVS).
Ці правила налаштовані суворо для протоколів TCP та UDP на певних портах.
Протокол ICMP (на якому працює утиліта ping) не має портів і не обробляється правилами трансляції сервісу. Оскільки мережевого інтерфейсу з таким IP фізично не існує в природі, ядру немає кому доставити ICMP Echo Request, і пакет мовчки відкидається.
2. Як налаштувати Service в Kubernetes для підключення до зовнішньої СУБД Oracle/PostgreSQL, розташованої поза кластером, використовуючи внутрішній Service Discovery?
Відповідь:
Створюється Service БЕЗ селектора (selector), і вручну оголошується об’єкт Endpoints з тим самим ім’ям:
apiVersion: v1
kind: Service
metadata:
name: external-oracle-db
spec:
ports:
- port: 1521
---
apiVersion: v1
kind: Endpoints
metadata:
name: external-oracle-db
subsets:
- addresses:
- ip: 192.168.10.50 # IP фізичного сервера БД поза K8s
ports:
- port: 1521
Java-застосунок всередині кластера використовує стабільне ім’я jdbc:oracle:thin:@external-oracle-db:1521/XEPDB1. Якщо фізичний IP бази даних зміниться, достатньо змінити маніфест Endpoints без перезапуску та переконфігурації мікросервісів.
3. У чому відмінність port від targetPort у специфікації Service, і що станеться, якщо targetPort пропущено?
Відповідь:
port: це TCP/UDP порт, який відкриває сам Service на своєму віртуальному ClusterIP. Саме до цього порту звертаються клієнти всередині кластера.targetPort: це реальний порт у контейнері пода, на якому слухає процес застосунку (наприклад, порт8080вбудованого Tomcat у Spring Boot). Ядро Linux транслює запити зportнаtargetPort.- Якщо
targetPortне вказано: Kubernetes за замовчуванням вважає, що значенняtargetPortсуворо дорівнює значеннюport.
4. Чому використання властивості sessionAffinity: ClientIP у Service може зламати балансування навантаження в мікросервісній архітектурі?
Відповідь:
При ввімкненні sessionAffinity: ClientIP kube-proxy скеровує всі запити від однієї IP-адреси клієнта на один і той самий фіксований под протягом заданого тайм-ауту.
В архітектурі з API Gateway (Ingress-контролер, Spring Cloud Gateway) абсолютно всі вхідні запити надходять до сервісу з однієї й тієї самої IP-адреси шлюзу.
У результаті sessionAffinity прив’яже весь вхідний клієнтський трафік до одного-єдиного пода, перевантажуючи його до падіння через вичерпання CPU або OOM, у той час як решта подів сервісу простоюватимуть із нульовим навантаженням.
🎯 Шпаргалка для інтерв’ю
Головне про Service
- Сутність: стабільний мережевий фасад (L4 VIP + DNS) для ефемерних подів.
- Пошук подів: через
spec.selectorза мітками (Labels). - Зв’язуючий об’єкт:
Endpoints/EndpointSlice(зберігає IP живих подів). - DNS: доступний за ім’ям
service-name(у тому ж namespace) або FQDNservice.namespace.svc.cluster.local. - Реалізація: агент
kube-proxyчерез правила ядраiptables(за замовчуванням) абоIPVS($O(1)$ для високих навантажень). - Headless:
clusterIP: None— CoreDNS повертає IP усіх подів напряму (для StatefulSet/Kafka).
Типи Service
| Тип Service | Область видимості | Призначення |
| :— | :— | :— |
| ClusterIP | Лише всередині кластера K8s | Стандарт за замовчуванням для міжсервісного спілкування |
| NodePort | Порт 30000–32767 на всіх вузлах | Доступ без хмарного балансувальника |
| LoadBalancer| Інтернет (зовнішній хмарний IP)| Продакшен точка входу через хмарний LB |
| ExternalName| Внутрішній CNAME редирект | Підключення зовнішніх систем за доменним ім’ям |
Червоні прапорці на співбесіді (Чого говорити не можна)
- ❌ «Service — це окремий контейнер з Nginx, який працює і проксує трафік» — Service це абстракція, реалізована через правила ядра iptables/IPVS.
- ❌ «ClusterIP можна пропінгувати утилітою ping» — віртуальний IP не відповідає на ICMP, тільки TCP/UDP.
- ❌ «Service балансує HTTP-трафік за URL та заголовками» — Service працює на L4 (TCP/IP). Маршрутизацією на L7 (HTTP-шляхи) займається Ingress.