Network
В кластере kubernetes можно выделить три типа сетей:
Сеть нод(узлов) - данная сеть обеспечивает связь между узлами кластера.
Сеть подов - каждый под в кластере имеет свой уникальны IP адрес в этой сети, данная сеть связывает поды как на одной ноде так и на разных.
Сеть сервисов - виртуальная сеть, позволяющая обращаться к группе подов, распределяя трафик между ними.
Для обеспечения связности внутри кластера используются различные CNI плагины, которые обеспечивают подключение пода в подовую сеть на ноде, а также обеспечивают взаимодействие подов на разных нодах, например, создавая оверлейную сеть. Для управления сетью сервисов существует стандартный компонент kube-proxy, обеспечивающий распределение трафика от IP адреса сервиса к IP адресам подов.
Концепции
Service: это абстракция, которая предоставляет устойчивый IP-адрес и DNS-имя для группы связанных подов. Service может использоваться для балансировки нагрузки между несколькими экземплярами приложения или между различными приложениями в кластере.
Ingress: это объект, который управляет внешним доступом к сервисам в кластере. Ingress может маршрутизировать трафик на основе различных критериев, таких как путь URL и заголовки HTTP.
Network Policy: это объект, который определяет правила безопасности для сети Kubernetes. С помощью Network Policy можно ограничить трафик между различными сервисами и подами в кластере.
DNS: это сервис, который предоставляет разрешение имен для объектов Kubernetes. DNS-имена могут использоваться для связи между различными сервисами и подами в кластере.
Service/Endpoints
В Kubernetes сервис (Service) - это абстракция, которая представляет собой логическое имя и IP-адрес, которые используются для обеспечения доступа к группе подов.
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
name: nginx
spec:
ports:
- name: web
port: 80
protocol: TCP
targetPort: 8080
selector:
app: nginx
type: ClusterIP
Выбор подов как и в других ресурсах производится с помощью селектора по лейблам spec.selector
.
Поле spec.type
определяет тип сервиса, существует следующие типы:
ClusterIP: это тип сервиса, который назначает виртуальный IP-адрес сервису. Этот IP-адрес доступен только внутри кластера и используется для связи между подами в кластере.
NodePort: это тип сервиса, который открывает порт на каждой ноде кластера и перенаправляет трафик на соответствующий порт в подах, связанных с этим сервисом. Такой сервис доступен снаружи кластера через IP-адрес ноды и порт NodePort.
LoadBalancer: это тип сервиса, который создает внешний балансировщик нагрузки и назначает ему виртуальный IP-адрес. Балансировщик нагрузки перенаправляет трафик на соответствующие поды, связанные с этим сервисом. Такой сервис доступен снаружи кластера через IP-адрес балансировщика нагрузки.
ExternalName: в отличии от других типов не имеет селектор, он создает CNAME запись во внутреннем DNS, ссылающуюся на внешний ресурс.
Поле spec.ports
определяет в какие порты пода будет производиться перенаправление трафика:
name (опционально) - имя порта, которое можно использовать для ссылки на порт в других частях манифеста сервиса.
port - номер порта на сервисе.
targetPort - номер порта на поде, который сервис должен направлять входящие соединения.
protocol (опционально) - протокол порта (TCP или UDP). По умолчанию используется TCP.
nodePort (опционально) - номер порта на каждой ноде кластера, который будет проксировать входящие соединения на порт сервиса
Сервисы также могут использоваться для реализации масштабирования приложений, когда новые поды могут быть добавлены и удалены из группы подов, связанной с сервисом, без изменения IP-адреса и имени сервиса.
Каждый раз, когда создается новый сервис, Kubernetes создает объект Endpoints, который содержит список IP-адресов и портов, соответствующих конечным точкам, связанным с сервисом. Этот список конечных точек автоматически обновляется Kubernetes в соответствии с изменениями количества запущенных подов в кластере. Endpoints обеспечивает прямое взаимодействие между сервисами и подами.
apiVersion: v1
kind: Endpoints
metadata:
labels:
app: nginx
name: nginx
namespace: default
subsets:
- addresses:
- ip: 10.244.1.5
nodeName: kind-worker2
targetRef:
kind: Pod
name: nginx-deployment-76d6c9b8c-n6c4f
namespace: default
uid: 7ec844ca-36d9-4082-a7ea-e0cd8e95d390
- ip: 10.244.2.25
nodeName: kind-worker
targetRef:
kind: Pod
name: nginx-deployment-76d6c9b8c-9h2fn
namespace: default
uid: a93b7fd4-43b1-4c85-897b-3d150a8ec3dd
- ip: 10.244.2.26
nodeName: kind-worker
targetRef:
kind: Pod
name: nginx-deployment-76d6c9b8c-r9vll
namespace: default
uid: d31680a6-1aad-439c-84a2-aee8c5d1930e
ports:
- name: web
port: 8080
protocol: TCP
Endpointslices - это новый объект Kubernetes, который был введен в версии Kubernetes 1.19. Endpointslice является более эффективной и масштабируемой заменой Endpoints. Endpointslices разделяются на куски, которые содержат небольшое количество конечных точек и могут динамически обновляться.
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: nginx-k7j7n
addressType: IPv4
endpoints:
- addresses:
- 10.244.1.5
conditions:
ready: true
serving: true
terminating: false
nodeName: kind-worker2
targetRef:
kind: Pod
name: nginx-deployment-76d6c9b8c-n6c4f
namespace: default
uid: 7ec844ca-36d9-4082-a7ea-e0cd8e95d390
- addresses:
- 10.244.2.25
conditions:
ready: true
serving: true
terminating: false
nodeName: kind-worker
targetRef:
kind: Pod
name: nginx-deployment-76d6c9b8c-9h2fn
namespace: default
uid: a93b7fd4-43b1-4c85-897b-3d150a8ec3dd
- addresses:
- 10.244.2.26
conditions:
ready: true
serving: true
terminating: false
nodeName: kind-worker
targetRef:
kind: Pod
name: nginx-deployment-76d6c9b8c-r9vll
namespace: default
uid: d31680a6-1aad-439c-84a2-aee8c5d1930e
ports:
- name: web
port: 80
protocol: TCP
Ingress/Ingress controller
Ingress Controller - это компонент Kubernetes, который обрабатывает входящие HTTP/HTTPS-запросы в кластер и маршрутизирует их к соответствующим сервисам на основе правил, заданных в объекте Ingress.
Одним из самых популярных Ingress-контроллеров является Nginx Ingress Controller, который может быть настроен для обработки различных правил маршрутизации на основе Ingress. Он может выполнять функции балансировки нагрузки, управления маршрутизацией трафика, обеспечения безопасности и дополнительных функций.
Ingress - это объект Kubernetes, который определяет правила маршрутизации входящих запросов на основе их хост- и путь-сопоставления. Ingress можно использовать для настройки балансировки нагрузки, HTTPS-шифрования, аутентификации и авторизации входящих запросов.
Ingress определяет правила маршрутизации трафика, которые состоят из нескольких частей:
Правила (rules) - определяют, какие входящие запросы должны быть направлены на какой сервис. Каждое правило содержит один или несколько хостов, которые будут использоваться для маршрутизации, а также определяет, какой сервис должен быть использован для обработки запросов.
Правила маршрутизации (paths) - определяют, какой путь в URL-адресе запроса должен быть направлен на какой сервис. Маршруты определяются с помощью регулярных выражений и могут быть использованы для маршрутизации запросов, направленных на различные пути в приложении.
Сервисы (services) - определяются в качестве конечных точек для входящих запросов. Каждый сервис определяет, какой порт должен быть использован для обработки запросов.
Пример манифеста Ingress для приложения, которое использует два сервиса (frontend и backend), и доступно по двум хостам (app.example.com и api.example.com):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
name: http
- host: api.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: backend
port:
name: http
В этом примере Ingress определяет два правила маршрутизации - одно для хоста app.example.com, которое направляет запросы на сервис frontend, и одно для хоста api.example.com, которое направляет запросы на сервис backend.
Network Policies
Network Policy - это механизм в Kubernetes, который позволяет определить правила доступа к сетевым ресурсам в кластере. С помощью Network Policy можно настроить сегментацию сети и ограничить доступ к сервисам в кластере на уровне сети.
Сущности, с которыми определяются правила доступа, могут быть:
Pods
Namespaces
IP Blocks
По умолчанию в Kubernetes отсутствует политика, которая ограничивает сетевой трафик между подами. Это означает, что если не задана явная политика для пода или неймспейса, то он может свободно общаться со всеми другими подами в кластере.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: netpol
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
Примечание
Network Policies реализуются сетевыми плагинами кластера, таким образом нужно убедиться что используемый в кластере сетевой плагин поддерживает их.
DNS
В кластере Kubernetes имеется свой DNS сервер(по умолчанию используется coredns), который создает записи для ресурсов Pod и Service.
Service
Для обычных сервисов(не headless) создается запись вида svc-name.namespace.svc.cluster.local
,
которая разрешается в ClusterIP
сервиса.
Для headless сервисов(которые не имеют ClusterIP
) также создается данная запись, но разрешается
в IP адреса всех подов, которые отслеживает сервис через селектор.
Pod
Для подов создается запись вида pod-ip-address.namespace.pod.cluster.local
, например
172-17-0-3.default.pod.cluster.local
. Также для каждого пода за сервисом создается запись вида
pod-ip-address.svc-name.namespace.svc.cluster.local
.