Модуль 5 / 19
Service, Endpoints и DNS
Содержание
1. Цели модуля
После модуля вы сможете объяснить стабильную адресацию Service поверх изменяемых Pod IP, связать selector с EndpointSlice, использовать кластерный DNS и диагностировать ситуацию, когда имя разрешается, но трафик не доходит до backend.
- Service и его типы
- selector и EndpointSlice
- DNS-имена между namespaces
- диагностика от клиента до Pod
2. Теория: сетевая модель Kubernetes
Каждый Pod получает собственный IP и доступен через кластерную сеть, но Pod является одноразовым: после замены его IP может измениться. Service отделяет клиентов от изменяемого набора backend Pods и предоставляет стабильный virtual IP и DNS name.
Контейнеры одного Pod используют localhost. Между Pods трафик идёт через pod network, а обращение к Service обрабатывает service proxy — kube-proxy или реализация сетевого плагина.
3. Теория: Service и порты
Selector Service выбирает Pods по labels. port — порт Service для клиента, targetPort — порт или имя порта контейнера. Именованный targetPort уменьшает связанность и позволяет менять номер порта backend без изменения клиента.
- ClusterIP доступен внутри кластера и используется по умолчанию
- NodePort публикует порт на Nodes и обычно является строительным блоком
- LoadBalancer запрашивает внешний балансировщик у поддерживаемой инфраструктуры
- ExternalName возвращает DNS CNAME и не создаёт proxy backend
- headless Service с clusterIP: None возвращает адреса endpoints напрямую
4. Теория: EndpointSlice и DNS
Control Plane создаёт EndpointSlices для Service с selector и включает подходящие backend endpoints. Используйте EndpointSlice API: устаревший Endpoints API ограничен и не является правильной основой для новых инструментов.
CoreDNS создаёт записи Service. В том же namespace достаточно web; из другого namespace используйте web.lab-network, полное имя — web.lab-network.svc.cluster.local. Успешный DNS lookup подтверждает существование Service, но не наличие готовых endpoints.
5. Методические указания
- Диагностируйте из Pod-клиента, а не с хоста
- Разделяйте DNS resolution, Service VIP, EndpointSlice и доступность Pod
- Сравнивайте Service selector с фактическими Pod labels
- Проверяйте port, targetPort, protocol и readiness endpoints
- Не используйте Pod IP как постоянный адрес приложения
- Для доступа извне выбирайте LoadBalancer, Gateway или Ingress осознанно, а не ClusterIP
6. Лабораторная работа: Deployment и Service
Сохраните многообъектный манифест как service-lab.yaml. Он создаёт namespace, три nginx Pods и ClusterIP Service с корректным selector.
apiVersion: v1
kind: Namespace
metadata:
name: lab-network
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: lab-network
spec:
replicas: 3
selector:
matchLabels:
app.kubernetes.io/name: web
template:
metadata:
labels:
app.kubernetes.io/name: web
spec:
containers:
- name: nginx
image: nginx:1.29-alpine
ports:
- name: http
containerPort: 80
readinessProbe:
httpGet:
path: /
port: http
periodSeconds: 3
---
apiVersion: v1
kind: Service
metadata:
name: web
namespace: lab-network
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: web
ports:
- name: http
port: 80
targetPort: http7. Лабораторная работа: DNS и трафик
Примените манифест, исследуйте EndpointSlice и выполните запросы из отдельного клиентского Pod по короткому и полному DNS-имени.
kubectl apply -f service-lab.yaml
kubectl rollout status deployment/web -n lab-network --timeout=120s
kubectl get service web -n lab-network
kubectl get endpointslices -n lab-network -l kubernetes.io/service-name=web -o wide
kubectl run client -n lab-network --image=busybox:1.37.0 --restart=Never -- sleep 3600
kubectl wait -n lab-network --for=condition=Ready pod/client --timeout=120s
kubectl exec -n lab-network client -- nslookup web
kubectl exec -n lab-network client -- nslookup web.lab-network.svc.cluster.local
kubectl exec -n lab-network client -- wget -qO- http://web
kubectl exec -n lab-network client -- cat /etc/resolv.confКритерий: Service имеет ClusterIP, EndpointSlice содержит три ready endpoint, оба DNS-имени разрешаются, HTTP возвращает страницу nginx.
8. Диагностика: Service без endpoints
Намеренно сломайте selector Service. DNS продолжит разрешать имя и ClusterIP сохранится, но EndpointSlice останется без подходящих endpoints, поэтому HTTP-запрос не выполнится.
kubectl patch service web -n lab-network --type=merge -p '{"spec":{"selector":{"app.kubernetes.io/name":"missing"}}}'
kubectl get service web -n lab-network -o yaml
kubectl get pods -n lab-network --show-labels
kubectl get endpointslices -n lab-network -l kubernetes.io/service-name=web -o yaml
kubectl exec -n lab-network client -- nslookup web
kubectl exec -n lab-network client -- wget -T 3 -qO- http://web
kubectl patch service web -n lab-network --type=merge -p '{"spec":{"selector":{"app.kubernetes.io/name":"web"}}}'
kubectl wait -n lab-network --for=jsonpath='{.endpoints[0].conditions.ready}'=true endpointslice -l kubernetes.io/service-name=web --timeout=60s
kubectl exec -n lab-network client -- wget -qO- http://web
kubectl delete namespace lab-networkАлгоритм: проверить Service и ports → сопоставить selector с Pod labels → изучить EndpointSlices и readiness → обратиться к Pod IP напрямую при необходимости → исправить минимальное поле.
9. Диагностика: DNS
Если не разрешается даже kubernetes.default, исследуйте resolv.conf клиента, Service и EndpointSlices kube-dns, затем Pods и логи CoreDNS.
kubectl exec -n lab-network client -- nslookup kubernetes.default
kubectl get service kube-dns -n kube-system
kubectl get endpointslices -n kube-system -l kubernetes.io/service-name=kube-dns
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns --tail=50Если kubernetes.default разрешается, а web нет, проблема обычно в имени, namespace или объекте Service, а не в работоспособности CoreDNS целиком.
10. Контроль и шпаргалка
- Почему Service переживает замену Pod?
- Чем port отличается от targetPort?
- Почему DNS может работать при пустом EndpointSlice?
- Когда headless Service полезнее ClusterIP?
- С какого слоя начинать диагностику из другого namespace?
Модуль освоен, если вы прослеживаете путь DNS → ClusterIP → EndpointSlice → ready Pod, находите несовпадение selector и labels и восстанавливаете доступ без пересоздания workload.
PDF для работы офлайн
Скачайте оформленную версию модуля для чтения без подключения к сети.