network
Service
Service - сущность Kubernetes, которая используется для организации сетевого взаимодействие между подами внутри кластера.
При создании Сервиса ему присваивается ip-адрес и dns-имя. Service является чем-то вроде прокси (балансировщика), который имеет четкую сетевую связь с подами, какие-бы они не имели ip-адреса и на каких-бы нодах они не находились. Связь задается с помощью меток и селекторов.
При использовании сервиса нам не нужно ничего знать о подах на которых крутится интересующее нас приложение, достаточно просто знать имя сервиса, и service уже сам перешлет запрос на наиболее подходящий pod.
Service в k8s создан потому что pod - сущность непостоянная, может менять ip-адрес, может находится в кластере таких же подов-реплик ReplicaSet, а обращаться к нему нужно. Тут и появляется сервис, который имеет постоянное имя, знает где находится нужный адресат; выполняет балансировку, если одинаковых подов несколько.
kubectl expose pod <имя_пода> --port=<порт_пода> --target-port=<целевой_порт_пода> --type=ClusterIP --name=<имя_сервиса>
# <порт_пода> - порт вашего пода, который вы хотите открыть через сервис.
# <целевой_порт_пода> - порт, на который трафик будет направлен внутри вашего пода.
# Посмотреть доступные сервисы
kubectl get svc
Сервис осуществляет проброс портов к поду, при необходимости меняя порт. Один сервис может обслуживать несколько портов. Все это определяется декларативным способом в yaml-манифесте.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
- name: https
protocol: TCP
port: 443
targetPort: 9377
# Когда поды метятся меткой app: my-app, они автоматически становятся частью этой службы,
# и их можно обнаружить и обращаться к ним по имени службы my-service.

Типы сервисов
ClusterIP - создает сервис, доступный только внутри кластера, по внутреннему виртуальному ip-адресу. Данный тип службы создается по умолчанию, если в спецификации явно не указан другой тип.
NodePort - создает сервис на каждой ноде кластера со статическим портом, в диапазоне от 30000 до 32767. Данный тип сервиса будет доступен как изнутри кластера, так и снаружи. При создании сервиса NodePort будет автоматически создан еще и сервис ClusterIP, к которому обращается сервис NodePort.
LoadBalancer - тип сервиса который работает только в связке с услугой loadbalancer от облачного провайдера. Делает доступным сервис снаружи кластера с помощью облачного балансировщика нагрузки. Автоматически создаются NodePort и ClusterIP сервисы, к которым обращается сервис LoadBalancer.
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
clusterIP: 10.0.171.239
type: LoadBalancer
ExternalName - тип сервиса, который позволяет обращаться к внешним серверам, имеющим доменное имя. Он создает виртуальный сервис, который перенаправляет все запросы к определенному доменному имени DNS.
Сервис ExternalName полезен, когда вам нужно обращаться к внешнему ресурсу, например, базе данных или API, и вам необходимо использовать его DNS-имя внутри кластера Kubernetes.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ExternalName
externalName: my.database.example.com
Endpoints
Endpoints - сущность k8s, которая представляет из себя набор ip-адресов и портов, которые связанны с определенными подами кластера.
Объект endpoints создается автоматически при создании service, если для сервиса указан селектор. Имя endpoints совпадает с именем создавшего его сервиса.
Если endpoints создан автоматически - он будет динамически обновляться, например, при перезапуске подов на которые он указывает.
При создании объекта deployment создается объект replicaset, который создает нужное количество подов. Что бы обращаться к этим подам - создается объект Endpoints, который хранит в себе ip-адреса и порты всех этих подов, и динамически их обновляет.
Endpoints может быть создан и вручную, например, для связи с приложением вне кластера.
apiVersion: v1
kind: Endpoints
metadata:
name: db-slave
namespace: db-conn
subsets:
- addresses:
- ip: 10.128.0.21
- ip: 10.128.0.22
ports:
- port: 5432
Ingress
Ingress - объект kubernetes позволяющий получать доступ к работающим внутри кластера приложениям. Можно сказать ingress делает публикацию внутренних приложений кластера во внешний мир.
Ingress работает с протоколами http/https, обращение к приложению происходит класически, по доменному имени. Так же ingress может обеспечивать балансировку нагрузки.

Ingress Controller
Для того что-бы Ingress смог получать запросы из внешнего мира необходим еще один компонент: Ingress Controller - компонент, который реализует правила, прописанные во внутренних объектах Ingress
Ingress Controller слушает изменения в объектах Ingress и применяет их, настраивая балансировку нагрузки, маршрутизацию и другие параметры в соответствии с определенными правилами.
Когда вы создаете объект Ingress в вашем кластере, Ingress Controller интерпретирует эти правила и обеспечивает их выполнение. Контроллер решает, как обрабатывать входящий трафик на основе конфигурации Ingress.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress # Имя ingress
spec:
rules: # Правила маршрутизации
- host: myapp.example.com # Доменное имя для которого применимы нижеперечисленные правила
http: # правила для протокола http
paths: # пути URI по которым приходят URL-запросы
- path: / # все запросы, поступающие на корень хоста, будут перенаправлены к службе my-service.
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80
# Правил маршрутизации может быть много, все они вычитываются Ingress Controler-ом и преобразуются в рабочие правила для revers-proxy сервера
# Функцию revers-proxy выполняет тот или иной Ingress controler