Это старая версия документа!
Для доступа к поду (наборам подов) используются сервисы (service). Service - абстракция, определяющая набор подов и политику доступа к ним. Так же берет на себя вопрос распределения нагрузки
При определении сервиса нужно указать селектор, определяющий выбор набора подов. Сервисы без селектора, обычно используются для обращения во вне кластера, там ендпоинт создается вручную
apiVersion: v1 kind Service metadata: name: service-my-pods spec: selector: app: my-pods ports: - protocol: TCP port: 80 targetPort: 8080
Шлет входящие запросы на поды с указанным селектором. В качестве targetPort можно использовать имена портов, если они определены в подах, это дает большую гибкость т.к. могут быть разные
Если targetPort (порт назначения) не указать то по умолчанию используется тот же что и port (входящий)
Создается сервис, присваивается IP и куб добавляет его в DNS, после чего к сервису можно обращаться по имени, к том же NS: «http://service-my-pods», если из другого то нужно указать NS: «service-my-pods.namespace.svc»
В деплойменте должен быть прописан порт, чтобы контейнер мог принимать на нем запросы, в т.ч от сервиса собсна
Стратегия распределения запросов между подами, по умолчанию «round robin»
apiVersion: v1 kind: Service metadata: name: tomcat-main spec: selector: app: tomcat ports: - protocol: TCP port: 80 targetPort: tomcat
apiVersion: apps/v1 kind: Deployment metadata: name: tomcat-deployment spec: replicas: 2 selector: matchLabels: app: tomcat template: metadata: labels: app: tomcat spec: containers: - name: tomcat image: tomcat:10-jdk15 ports: - containerPort: 8080 name: tomcat protocol: TCP
Пару примеров как смотреть в консоли
kubectl get pods -o wide kubectl get svc -o wide # Так виден назначенный IP kubectl get svc <my-service> -o yaml
kubectl get ep
В случае сервисов использующих селекторы, ендпоинты создаются автоматом, система сама находит IP нужных подов и формирует запись в endpoint
Под капотом происходит по сути NAT преобразование, этим заведует kube-proxy
EndpointSlice - это просто разбиение объектов на части, для практичности размеров записей, происходит автоматически
По сути сервис без указания (создания) своего IP, так он напрямую ссылается на IP пода (подов, через запятую). В таком варианте отсутствует NAT преобразование, но так же отсутствует и балансировка. В случае какой то специфики, может пригодится
Сервис k8s по умолчанию. Обеспечивает сервис внутри кластера, к которому могут обращаться другие приложения внутри кластера. Внешнего доступа нет
apiVersion: v1 kind: Service metadata: name: my-internal-service selector: app: my-app spec: type: ClusterIP ports: - name: http port: 80 targetPort: 80 protocol: TCP
kubectl proxy --port=8080 # Затем обратится по такому адресу http://localhost:8080/api/v1/proxy/namespaces//services/<SERVICE-NAME>:<PORT-NAME>/ http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/
Самый примитивный способ направить внешний трафик в сервис. Открывает указанный порт для всех Nodes и трафик на этот порт перенаправляется сервису
Открываемый порт можно указать самому (nodePort), но лучше оставить автоматике
Из минусов то что один порт-одно приложение, кол-во портов ограничено, но самое главное что IP могут меняться и они разные на всех нодах
apiVersion: v1 kind: Service metadata: name: service-front namespace: my-namespace spec: selector: app: my-front ports: - protocol: TCP port: 3000
На всех нодах открывается рандомный порт, по IP ноды и этому порту, будет доступен сервис. Порт виден в oc describe svc/my-service (NodePort)
apiVersion: v1 kind: Service metadata: name: my-nodeport-service selector: app: my-app spec: type: NodePort ports: - name: http port: 80 targetPort: 80 nodePort: 30036 protocol: TCP
Стандартный способ предоставления сервиса в интернете. Сервис предоставляет IP адрес, этот адрес будет направлять весь трафик на сервис
Весь трафик указанного порта направляется н сервис, нет фильтрации, маршрутизации и проч, направляется трафик разных типов
НО, каждому сервису нужен свой IP
Ingress - ресурс k8s где создается описание конфигурации Ingress Controller
Ingress Controller - обрабатывает трафик, его конфигурация формируется из всех Ingress объектов внутри кластера
Вместе создают единую точку входа для трафика и выполняют роль прокси и балансировщика (?)
Ingress Controller - физический софт, расположенный на одном из подов, в основном на сервисной ноде, выполняет роль единой точки входа графика в кластер, а так же роль балансировки.
В одном кластере может быть установлено несколько IC, в зависимости от конфигурации и настроек кластера. Так же , в функции IC входит первичная маршрутизация, согласно правилам, описанным в Ingress. Реализаций IC очень много
Ingress это yaml/json шаблон k8s, который описывает правила маршрутизации графика из IC до сервисов кластера
В системах «openshift» шаблон «Ingress» заменяет шаблон «route», выполняющий аналогичные функции
Revers proxy в Ingress Controller слушает порты с HTTP/HTTPS-соединениями, трафик может попадать на порты тремя способами:
NodePort
Непонятно, похоже что нужен «LoadBalancer» т.к. в URL нужно включать порт что пробросился ин ноды
HostPort
Открываются порты (вроде как на всех нодах), надо настраивать DNS, с перечислением всех нод
Host Network
тут вообще борода
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: my-ingress spec: backend: serviceName: other servicePort: 8080 rules: - host: foo.mydomain.com http: paths: - backend: serviceName: foo servicePort: 8080 - host: mydomain.com http: paths: - path: /bar/* backend: serviceName: bar servicePort: 8080