# 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-адрес, которые используются для обеспечения доступа к группе подов. ```yaml 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 обеспечивает прямое взаимодействие между сервисами и подами. ```yaml 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 разделяются на куски, которые содержат небольшое количество конечных точек и могут динамически обновляться. ```yaml 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): ```yaml 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 отсутствует политика, которая ограничивает сетевой трафик между подами. Это означает, что если не задана явная политика для пода или неймспейса, то он может свободно общаться со всеми другими подами в кластере. ```yaml 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 ``` ```{note} 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`. [coredns]:https://coredns.io/