Службы (Service) Kubernetes
Служба Kubernetes – это ресурс, который формирует единую постоянную точку входа в группу модулей, предоставляющих одну и туже службу. Каждая служба имеет IP-адрес и порт, которые никогда не меняются до тех пор, пока существует служба. Клиенты могут открывать подключения к этому IP-адресу и порту, а затем маршрутизировать эти подключения в один из модулей, поддерживающих эту службу. Благодаря этому, клиентам службы не требуется знать расположение отдельных модулей, предоставляющих службу, что позволяет перемещать данные модули по кластеру в любое время. Подключения к службе сбалансированы по нагрузке на всех поддерживающих модулях.
Создание службы
Создать службу (т.е создать объект Service) можно с помощью команды kubectl expose или путем отправки YAML на сервер API Kubernetes.
Для того чтобы создать службу с помощью команды, надо сообщить Kubernetes обеспечить доступ к контроллеру репликации:
$ kubectl expose replicationcontroller kubia --type=LoadBalancer --name kubia-http-service "kubia-http" exposed
Команда expose создаст ресурс Service с тем же селектором модуля, что и используемый контроллером репликации, обеспечивая доступ ко всем своим модулям через единый IP-адрес и порт.
Службы – это такие же объекты, как и модули (Pod) и узлы (Node), поэтому созданный объект службы можно просмотреть и узнать внешний IP-адрес можно выполнив команду
$ kubectl get services
Для создания службы с помощью дескриптора yaml, создайте файл с именем kubia-vc.yaml с содержимым ниже и примените команду создания $ kubectl create —f kubia-vc.yaml.
apiVersion: v1 kind: Service metadata: name: kubia spec: ports: – port: 80 targetPort: 8080 selector: app: kubia
Манифест определяет службу под названием kubia, которая будет принимать подключения к порту 80 и маршрутизировать каждое подключение на порт 8080 одного из модулей, который соответствует селектору меток app=kubia.
Запросы к службе можно отправлять из кластера несколькими способами:
- очевидным способом является создание модуля, который будет отправлять запрос на кластерный IP-адрес службы и регистрировать отклик. Далее можно просмотреть лог модуля, чтобы узнать, каков был отклик службы;
- можно подключиться к одному из узлов Kubernetes посредством команды ssh и применить команду curl;
- можно выполнить команду curl внутри одного из существующих модулей с помощью команды
kubectl exec.
Для удаленного выполнения произвольных команд в работающих контейнерах с помощью kubectl exec (3 вариант), выведите список модулей с помощью команды kubectl get pods и выберите один из них в качестве цели для команды exec.
Также потребуется получить кластерный IP службы (используя команду kubectl get svc).
$ kubectl exec имя-модуля -- curl -s http://адрес–кластера
Двойное тире (—) в команде является сигналом для kubectl об окончании командных параметров. Все, что после двойного тире это команда, которая должна быть выполнена внутри модуля.
Конфигурирование сохранения сессий в службах
Каждый новый вызов будет попадать на другой модуль, потому что служебный прокси обычно передает каждое подключение в случайно выбираемый соответствующий службе модуль, даже если подключения поступают от того же клиента. Чтобы все запросы, сделанные определенным клиентом, всякий раз перенаправлялись в один и тот же модуль, свойству службы sessionAffinity можно присвоить значение ClientIP (вместо None, которое используется по умолчанию), как показано в следующем ниже листинге.
apiVersion: v1 kind: Service spec: sessionAffinity: ClientIP ...
Система Kubernetes поддерживает только два типа сохранения сессий: None и ClientIP. У нее нет параметра сохранения сессий на основе файлов cookie, необходимо понимать, что службы Kubernetes не работают на уровне HTTP. Службы работают с пакетами TCP и UDP и не заботятся о полезной нагрузке, которую они несут. Поскольку файлы cookie являются конструкцией протокола HTTP, службы о них не знают, поэтому сохранение сессий не может быть основано на файлах cookie.
Обеспечение доступа к нескольким портам в одной и той же службе
Службы могут поддерживать несколько портов. Например, если модули прослушивали два порта – скажем, 8080 для HTTP и 8443 для HTTPS, – вы можете использовать одну службу для перенаправления портов 80 и 443 на порты 8080 и 8443 модуля. В таких случаях не требуется создавать две разные службы. Использование единой мультипортовой службы позволяет обеспечивать доступ ко всем портам службы через единый кластерный IP.
Во время создания службы с несколькими портами для каждого порта указывайте имя. Свойство spec ресурса многопортовой службы показано в следующем ниже листинге.
apiVersion: v1 kind: Service metadata: name: kubia spec: ports: – name: http port: 80 targetPort: 8080 – name: https port: 443 targetPort: 8443 selector: app: kubia
Селектор меток применяется ко всей службе в целом – он не может быть настроен для каждого порта индивидуально. Если хотите, чтобы разные порты увязывались с разными подмножествами модулей, необходимо создать две службы.
Использование именованных портов
Можно дать порту каждого модуля имя и ссылаться на него по имени в спецификации службы. Это делает спецификацию службы немного яснее, в особенности если номера портов не стандартны.
Ниже показано задание имен портов в определении модуля:
kind: Pod spec: containers: – name: kubia ports: – name: http containerPort: 8080 – name: https containerPort: 8443
Далее в спецификации службы можно обращаться к этим портам по имени:
apiVersion: v1 kind: Service spec: ports: – name: http port: 80 targetPort: http – name: https port: 443 targetPort: https
Преимущество именования портов заключается в том, что в дальнейшем позволяет вам изменять номера портов без необходимости изменять спецификацию службы.
Kubernetes предоставляет клиентским модулям возможность обнаруживать IP-адрес и порт службы.
При запуске модуля, Kubernetes инициализирует набор переменных среды, указывающих на каждую службу существующую в данный момент. Если вы создаете службу перед созданием клиентских модулей, процессы в этих модулях могут получить IP-адрес и порт службы путем проверки их переменных среды.
Показать список переменных среды службы в контейнере командой:
$ kubectl exec имя-контейнера env
Обнаружение служб через DNS
Модуль kube-dns запускает DNS-сервер, для использования которого автоматически настраиваются все остальные модули, работающие в кластере (Kubernetes делает это изменяя файл /etc/resolv.conf каждого контейнера). Любой DNS-запрос, выполняемый процессом, запущенным в модуле, будет обрабатываться собственным DNS-сервером Kubernetes, который знает все службы, работающие в системе.
С помощью свойства dnsPolicy в поле spec ресурса каждого модуля можно настроить, будет модуль использовать внутренний DNS-сервер или нет. Каждая служба получает DNS-запись во внутреннем DNS-сервере, и клиентские модули, которые знают имя службы, могут обращаться к ней через полностью квалифицированное доменное имя (FQDN) вместо использования переменных среды.
Пример подключения к службе через FQDN
backend-database.default.svc.cluster.local
где backend-database соответствует имени службы, default обозначает пространство имен, в котором определена служба, и svc.cluster.local – это настраиваемый доменный суффикс кластера, используемый во всех именах локальных служб кластера.
Когда модуль интерфейса находится в том же пространстве имен, что и модуль базы данных, можно опустить суффикс svc.cluster.local и даже пространство имен. В результате можно ссылаться на службу просто как backend-database.
Реклама: Всегда хотели iphone 15 pro по распродаже? Приобретайте по ссылке.
Запуск оболочки bash в контейнере модуля
Для запуска bash (или любой другой оболочки) внутри контейнера модуля используют команду kubectl exec. Для того чтобы правильно использовать оболочку, необходимо в команду kubectl exec передать параметр –it, благодаря этому вы можете изучить контейнер, без необходимости выполнять kubectl exec для каждой команды, которую вы хотите применить:
$ kubectl exec -it имя_контейнера bash
Когда вы находитесь внутри контейнера, команду curl можно использовать для доступа к службе kubia любым из способов:
root@имя_контейнера:/# curl http://kubia.default.svc.cluster.local root@имя_контейнера:/# curl http://kubia.default root@имя_контейнера:/# curl http://kubia
0