openshift pod что это
Pods and Services
OpenShift Enterprise leverages the Kubernetes concept of a pod, which is one or more containers deployed together on one host, and the smallest compute unit that can be defined, deployed, and managed.
Pods are the rough equivalent of OpenShift Enterprise v2 gears, with containers the rough equivalent of v2 cartridge instances. Each pod is allocated its own internal IP address, therefore owning its entire port space, and containers within pods can share their local storage and networking.
Pods have a lifecycle; they are defined, then they are assigned to run on a node, then they run until their container(s) exit or they are removed for some other reason. Pods, depending on policy and exit code, may be removed after exiting, or may be retained to enable access to the logs of their containers.
OpenShift Enterprise treats pods as largely immutable; changes cannot be made to a pod definition while it is running. OpenShift Enterprise implements changes by terminating an existing pod and recreating it with modified configuration, base image(s), or both. Pods are also treated as expendable, and do not maintain state when recreated. Therefore manage pods with higher-level controllers, rather than directly by users.
The following example definition of a pod provides a long-running service, which is actually a part of the OpenShift Enterprise infrastructure: the private Docker registry. It demonstrates many features of pods, most of which are discussed in other topics and thus only briefly mentioned here.
Pods can be «tagged» with one or more labels, which can then be used to select and manage groups of pods in a single operation. The labels are stored in key-value format in the metadata hash. One label in this example is docker-registry=default. |
Pods must have a unique name within their namespace. A pod definition may specify the basis of a name with the generateName attribute and random characters will be added automatically to generate a unique name. |
containers specifies an array of container definitions; in this case (as with most), just one. |
Environment variables can be specified to pass necessary values to each container. |
Each container in the pod is instantiated from its own Docker image. |
The container can bind to ports which will be made available on the pod’s IP. |
OpenShift Enterprise defines a security context for containers which specifies whether they are allowed to run as privileged containers, run as a user of their choice, and more. The default context is very restrictive but administrators can modify this as needed. |
The container specifies where external storage volumes should be mounted within the container. In this case, there is a volume for storing the registry’s data, and one for access to credentials the registry needs for making requests against the OpenShift Enterprise API. |
Pods making requests against the OpenShift Enterprise API is a common enough pattern that there is a serviceAccount field for specifying which service account user the pod should authenticate as when making the requests. This enables fine-grained access control for custom infrastructure components. |
The pod defines storage volumes that are available to its container(s) to use. In this case, it provides an ephemeral volume for the registry storage and a secret volume containing the service account credentials. |
This pod definition does not include attributes that are filled by OpenShift Enterprise automatically after the pod is created and its lifecycle begins. The Kubernetes API documentation has complete details of the pod REST API object attributes, and the Kubernetes pod documentation has details about the functionality and purpose of pods.
Services
A Kubernetes service serves as an internal load balancer. It identifies a set of replicated pods in order to proxy the connections it receives to them. Backing pods can be added to or removed from a service arbitrarily while the service remains consistently available, enabling anything that depends on the service to refer to it at a consistent internal address.
Services are assigned an IP address and port pair that, when accessed, proxy to an appropriate backing pod. A service uses a label selector to find all the containers running that provide a certain network service on a certain port.
Like pods, services are REST objects. The following example shows the definition of a service for the pod defined above:
The service name docker-registry is also used to construct an environment variable with the service IP that is inserted into other pods in the same namespace. The maximum name length is 63 characters. |
The label selector identifies all pods with the docker-registry=default label attached as its backing pods. |
Virtual IP of the service, allocated automatically at creation from a pool of internal IPs. |
Port the service listens on. |
Port on the backing pods to which the service forwards connections. |
The Kubernetes service documentation has more information about services.
Labels
Labels are used to organize, group, or select API objects. For example, pods are «tagged» with labels, and then services use label selectors to identify the pods they proxy to. This makes it possible for services to reference groups of pods, even treating pods with potentially different Docker containers as related entities.
Most objects can include labels in their metadata. Labels can be used to group arbitrarily-related objects; for example, all of the pods, services, replication controllers, and deployment configurations of a particular application can be grouped.
Labels are simple key-value pairs, as in the following example:
A pod consisting of an nginx Docker container, with the label role=webserver.
A pod consisting of an Apache httpd Docker container, with the same label role=webserver.
A service or replication controller that is defined to use pods with the role=webserver label treats both of these pods as part of the same group.
The Kubernetes labels documentation has more information about labels.
Тестирование в Openshift: Внутреннее устройство кластера
Это продолжение серии из трех статей (первая статья, третья статья) об автоматизированном тестировании программных продуктов в Openshift Origin. В данной статье будут описаны основные объекты Openshift, а также описаны принципы работы кластера. Я осознано не делаю попытку описать все возможные объекты и их особенности, так как это очень трудоемкая задача, которая выходит за рамки данной статьи.
Кластер:
В целом работа кластера Openshift Origin не сильно отличается от других решений. Поступающие задачи распределяются по рабочим узлам на основе их загруженности, данное распределение берет на себя планировщик.
Для запуска контейнеров требуется Docker образа, которые могут быть загружены из внутреннего или внешнего регистра. Непосредственно запуск контейнеров происходит в различных контекстах безопасности (политики безопасности, которые ограничивают доступ контейнера к различным ресурсам).
По умолчанию контейнеры из разных проектов могут коммуницировать друг с другом с помощью overlay сети (выделяется одна большая подсеть, которая разбивается на более мелкие подсети для всех рабочих узлов кластера). Запущенному на рабочем узле контейнеру выделяется IP-адрес из той подсети, которая была назначена данному узлу. Сама overlay сеть построена на базе Open vSwitch, который использует VXLAN для связи между рабочими узлами.
На каждом рабочем узле запускается выделенныё экземпляр Dnsmasq, который перенаправляет все DNS запросы контейнеров на SkyDNS во внутреннюю сервисную подсеть.
Если контейнер аварийно завершил свою работу или просто не может быть проинициализирован, то задача по его развертыванию передается на другой рабочий узел.
Стоит отметить что:
SELinux не является строгим условием работы кластера. Отключение оного (не рекомендуется по соображениям безопасности) привнесет некое увелечение скорости (равно как и отключение мониторинга, кстати) при работе с контейнерами. Если SELinux мешает работе приложения в контейнере, присутствует возможность добавления исключения SELinux непосредственно на рабочем узле кластера.
По умолчанию используется LVM в качестве хранилища Docker Engine. Это далеко не самое быстрое решение, но можно использовать любой другой тип хранилища (BTRFS, например).
Стоит иметь ввиду, что название сервиса (см. Service) — это DNS имя, которое влечет за собой ограничения на длину и допустимые символы.
Чтобы сократить временные и аппаратные издержки при сборке Docker образов можно использовать так называемый «слоистый» подход (multi-stage в Docker). В данном подходе используются базовые и промежуточные образа, которые дополняют друг друга. Имеем базовый образ «centos:7» (полностью обновлен), имеем промежуточный образ «centos:7-tools» (установлены иструменты), имеем финальный образ «centos:7-app» (содержит «centos:7» и «centos:7-tools»). То есть вы можете создавать задачи сборки, которые основываются на других образах (см. BuildConfig).
Достаточно гибким решением является подход, когда существует один проект, который занимается только сборкой Docker образов с последующей «линковкой» данных образов в другие проекты (см. ImageStream). Это позволяет не плодить лишних сущностей в каждом проекте и приведет к некой унификации.
Большинству объектов в кластере можно присвоить произвольные метки, с помощью которых можно совершать массовые операции над данными объектами (удаление определенных контейнеров в проекте, например).
Стоит сразу побеспокоиться об удалении старых образов и забытых окружений. Если первое решается с помощью сборщика мусора/oadm prune, то второе требует проработки и ознакомлении всех участников с правилами совместной работы в Openshift Origin.
Любой кластер ограничен ресурсами, поэтому очень желательно организовать мониторинг хотя бы на уровне рабочих узлов (возможен мониторинг на уровне приложения в контейнере). Сделать это можно как с помощью готового решения Openshift Metrics, так и с помощью сторонних решений (Sysdig, например). При наличии метрик загруженности кластера (в целом или по проектно) можно организовать гибкую диспетчерезацию поступающих задач.
Особенно хочется отметить тот факт, что рабочие узлы могут быть динамически проинициализированы, а это значит, что вы можете расширить свой кластер Openshift Origin на существующих мощностях IaaS. То есть, во время предрелизного тестирования вы можете существенно расширить свои мощности и сократить время тестирования.
Объекты:
Project — объект является Kubernetes namespace. Верхний уровень абстракции, который содержит другие объекты. Созданные в проекте объекты не пересекаются с объектами в других проектах. На проект могут быть выставлены квоты, привилегии, метки узлов кластера и т.д. Вложенная иерархия и наследование между проектами отсутствуют, доступна «плоская» структура проектов. Существуюет несколько системных проектов (kube-system, openshift, openshift-infra), которые предназначены для нормального функционирования кластера.
Создание нового проекта:
Редактирование настроек проекта:
Pod — объект, который стал одним из решающих факторов, так как позволяет запускать произвольные команды внутри контейнера с помощью специальных хуков (и не только). Pod является основной рабочей единицей в кластере. Любой запущенный в кластере контйенер — Pod. По своей сути — группа из одного и более контейнеров, которые работают в единых для этих контейнеров namespaces (network, ipc, uts, cgroup), используют общее хранилище данных, секреты. Контейнеры, из которых состоит Pod, всегда запущены на одном узле кластера, а не распределены в одинаковых пропорциях по всем узлам (если Pod будет состоять из 10 контейнеров, все 10 будут работать на одном узле).
Secret — может являться строкой или файлом, предназначен для проброса чувствительной (хранится в открытом виде в etcd (поддержка шифрования в Kubernetes 1.7)) информации в Pod. Один Secret может содержать множество значений.
Использование Secret в BuildConfig:
ServiceAccount — специальный тип объекта, который предназначен для взаимодействия с ресурсам кластера. По своей сути является системным пользователем.
По умолчанию новый проект содержит три ServiceAccount:
Перечисленные служебные аккаунты:
Добавление прав администратора проекта ServiceAccount:
DeploymentConfig — это объект, который оперирует всё теми же Pod, но при этом привносит ряд дополнительных механизмов для управления жизненным циклом запущенных приложений, а именно:
ImageStream — по своей сути является «контейнером» для «ссылок» (ImageStreamTag), которые указывают на Docker образа или другие ImageStream.
Создание тага/ссылки на Docker образ между проектами:
Создание тага/ссылки на Docker образ, который расположен на Docker Hub:
BuildConfig — объект является сценарием того, как будет собран Docker образ и куда он будет помещен. Сборка нового образа может базироваться на других образах, за это отвечает секция «from:»
Источники сборки (то место, где размещены исходные данные для сборки):
Стратегии сборки (каким образом следует интерпретировать источник данных):
Назначение сборки (куда будет выгружен собранный образ):
Какие операции выполнит данный BuildConfig:
Service — объект, который стал одним из решающих факторов при выборе системы запуска сред, так как он позволяет гибко настраивать коммуникации между средами (что очень важно в тестировании). В случаях с использованием других систем требовались подготовительные манипуляции: выделить диапазоны IP-адресов, зарегистрировать DNS имена, осуществить проброс портов и т.д. и т.п. Service может быть объявлен до фактического развертывания приложения.
Что происходит во время публикации сервиса в проекте:
Разрешение DNS имени:
Заключение:
Все объекты кластера можно описать с помощью YAML, это, в свою очередь, дает возможность полностью автоматизировать любые процессы, которые протекают в Openshift Origin. Вся сложность в работе с кластером заключается в знании приципов работы и механизмов взаимодействия объектов. Такие рутинные операции как инициализация новых рабочих узлов берут на себя сценарии Ansible. Доступность API открывает возможность работать с кластером напрямую минуя посредников.
Все об OpenShift Egress. Часть 1
Про управление входящим в OpenShift трафиком (оно же Ingress) написано много в документации и различных статьях по его настройке. Но, кроме контроля входящего в кластер трафика, в работе зачастую требуется контроль исходящего трафика (Egress). А на эту тему информации, систематизирующей подходы и технические решения, значительно меньше. Постараемся заполнить эту нишу серией постов.
Итак, в каких ситуациях нужен контроль исходящего из кластера трафика?
Можно выделить три типовых сценария использования.
Доступ к внешнему ресурсу контролируется извне кластера
Например, есть внешняя база данных, доступ к которой контролируется межсетевым экраном, и требуется предоставить доступ к этой БД только для определенных POD кластера. По умолчанию POD при взаимодействии с внешними ресурсами используют IP-адрес узла кластера, поэтому задача не решается «в лоб».
Можно выделить несколько узлов исключительно под эти POD, но это зачастую не выход. Узлов понадобится несколько (нам же нужна отказоустойчивость), а требуемых POD может быть совсем немного. Узлы могут получать IP адреса по DHCP, что также затрудняет решение проблемы. Ну и, наконец, таких внешних «зон безопасности» может быть много, и выделять под каждую по два узла совсем не хочется.
Для определенных POD в кластере требуется доступ в изолированные сегменты сети
Типичным случаем здесь является организация доступа определенных POD к сегментам сети, расположенным в другом VLAN (которого нет на узлах кластера) или вообще на другом оборудовании (например, по требованиям PCI DSS).
Создавать по кластеру в каждом таком сегменте — дорого и к тому же тяжело поддерживать. А заводить требуемый VLAN на узлы кластера не будут: его для этого и сделали, чтобы доступ получило только то ПО и оборудование, которое участвует в этом критичном с точки зрения ИБ бизнес-процессе.
К пропускной способности или задержкам сети определенных POD предъявляются особые требования
Например, приложение требует для нормальной работы выделенного соединения 10G Ethernet и полностью его утилизирует. В этом случае также непонятно, как обеспечить эти требования в условиях одновременной работы десятков или сотен POD на одном рабочем узле. Не выделять же полностью узел кластера под один подобный POD.
На все вышеописанные сценарии есть решения, которые связаны с управлением исходящего из кластера OpenShift трафика. Попробуем разобраться, в каком случае какое решение по Egress применять, и как оно работает.
Egress IP и Egress Router
В OpenShift, начиная с версии 3.7, появилась возможность выделить фиксированные адреса на namespace, и именно с этих адресов все POD в этом namespace будут обращаться к внешним ресурсам кластера. Реализовано это средствами OpenShift SDN.
Всё работает, но непонятно, как именно:) Например, контейнер, как мы видели ранее, работает на узле shift-worker1. На этот узел был назначен адрес Egress IP = 192.168.111.226. Так почему же мы выходим из кластера с Egress IP = 192.168.111.225?
Ответ на этот вопрос дает статья How to Enable Static Egress IP in OCP. Давайте с ее помощью выясним, что же происходит «под капотом» OpenShift при использовании Egress IP.
Принадлежность к проекту определяется его virtual network ID (VNID), в нашем случае 0xe28820 — это шестнадцатеричное значение VNID для проекта egress.
OpenShift SDN заворачивает все подобные пакеты в tunnel interface vxlan0 с указанием, что доставить пакет надо на хост shift-worker0:
Таким образом, OpenShift SDN выбирает «основной» Egress IP-адрес, и все пакеты с проекта помечает меткой и отправляет на хост, содержащий «основной» Egress IP. На этом хосте iptables выполняет Source NAT, и задача решена. Если хост с «основным» Egress IP становится недоступен, то пакеты перенаправляются на следующий в списке Egress IP-адресов хост (в нашем случае это будет shift-worker1).
Если мы выключим хост shift-worker0, то наш тестовый POD «наружу» будет выходить уже с адресом 192.168.111.226, который мы присвоили узлу shift-worker1:
192.168.111.226 — — [30/Oct/2020:15:28:38 +0300] «GET /test HTTP/1.1» 200 8 «-» «curl/7.29.0»
Именно поэтому нам нужно как минимум два IP-адреса при использовании Egress IP. В случае отказа одного узла кластера POD мы сможем получить доступ к внешним ресурсам с заданных IP.
Описанная здесь схема организации Egress хорошо подходит для первого сценария использования, когда доступ к внешним по отношению к кластеру ресурсам определяется межсетевым экраном или самим ресурсом. Применительно к нашему стенду все POD в проекте «egress» (POD2 – POD4) при обращении «наружу» получат заранее определенные адреса (192.168.111.225 или 192.168.111.225) вне зависимости от того, на каком узле кластера они находятся. Остальные POD кластера при обращении к внешним ресурсам получат IP-адрес узла кластера и будут отвергнуты либо МЭ, либо приложением.
Если нужно сделать фиксированные Egress-адреса для нескольких проектов, то использовать Egress IP неудобно. В этом случае узлам кластера можно указать, какую подсеть использовать, а проекту — какой IP адрес из этой подсети взять.
После этого указываем проекту, какой IP-адрес использовать для исходящего трафика:
Разумеется, egressCIDR должен быть в той же подсети, что и основной IP-адрес узла. И выделять два адреса на проект в данном случае не требуется — при отказе узла используемый адрес «переедет» на другой доступный узел с установленным egressCIDR (при условии, что этот адрес в него входит).
Egress Router
Рассказывая про Egress в OpenShift, важно также упомянуть про Egress router. Он применялся еще до того, как появилась возможность контролировать исходящий трафик средствами Openshift SDN. В качестве решения использовался специальный POD, у которого один адрес находился в кластерной сети OpenShift, а другой получал внешний IP-адрес и доступ к физическому интерфейсу узла через macvlan CNI plugin.
Этот POD выступал в роли маршрутизатора между внутренней сетью кластера и внешними сетями за пределами OpenShift. Пример управления исходящим трафиком через Egress router можно посмотреть на странице Red Hat OpenShift Blog. Но так как конфигурация на базе OpenShfit SDN проще в настройке и поддержке, описание решения на базе Egress router в OpenShift версии 4 удалено из документации.
Vanilla Kubernetes
А что с управлением Egress трафиком в «ванильном» Kubernetes? К сожалению, единого решения здесь нет. Все зависит от возможностей SDN, который используется в работе кластера. Например, Calico позволяет отключить Source NAT для определенного пула IP-адресов. Но в этом случае вопросы маршрутизации трафика между POD кластера и внешним миром придется решать самостоятельно.
Резюме
В OpenShift можно штатными средствами SDN организовать контроль IP-адресации исходящего трафика, чтобы обеспечить требования внешних систем контроля доступа. При этом необходимо понимать возникающие в работе кластера технические нюансы:
Подмена IP-адресов здесь никак не поможет. Решением является использование CNI «meta-plugin» Multus. Multus CNI plugin стал доступен в качестве поддерживаемого компонента в OpenShift 4.1 и фактически позволяет организовать подключение POD к нескольким сетям одновременно.
Настройке и использованию Multus CNI Plugin в OpenShift посвятим вторую часть этого поста.
Список литературы
Автор: Сергей Артемов, руководитель отдела DevOps-решений «Инфосистемы Джет»
Pods and Services
OpenShift Container Platform leverages the Kubernetes concept of a pod, which is one or more containers deployed together on one host, and the smallest compute unit that can be defined, deployed, and managed.
Pods are the rough equivalent of a machine instance (physical or virtual) to a container. Each pod is allocated its own internal IP address, therefore owning its entire port space, and containers within pods can share their local storage and networking.
Pods have a lifecycle; they are defined, then they are assigned to run on a node, then they run until their container(s) exit or they are removed for some other reason. Pods, depending on policy and exit code, may be removed after exiting, or may be retained in order to enable access to the logs of their containers.
OpenShift Container Platform treats pods as largely immutable; changes cannot be made to a pod definition while it is running. OpenShift Container Platform implements changes by terminating an existing pod and recreating it with modified configuration, base image(s), or both. Pods are also treated as expendable, and do not maintain state when recreated. Therefore pods should usually be managed by higher-level controllers, rather than directly by users.
The recommended maximum number of pods per OpenShift Container Platform node host is 110.
Bare pods that are not managed by a replication controller will be not rescheduled upon node disruption.
Below is an example definition of a pod that provides a long-running service, which is actually a part of the OpenShift Container Platform infrastructure: the integrated container registry. It demonstrates many features of pods, most of which are discussed in other topics and thus only briefly mentioned here:
This pod definition does not include attributes that are filled by OpenShift Container Platform automatically after the pod is created and its lifecycle begins. The Kubernetes API documentation has complete details of the pod REST API object attributes, and the Kubernetes pod documentation has details about the functionality and purpose of pods.
Pod Restart Policy
A pod restart policy determines how OpenShift Container Platform responds when containers in that pod exit. The policy applies to all containers in that pod.
The possible values are:
Once bound to a node, a pod will never be bound to another node. This means that a controller is necessary in order for a pod to survive node failure:
Pods that are expected to terminate (such as batch computations)
OnFailure or Never
Pods that are expected to not terminate (such as web servers)
Pods that need to run one-per-machine
If an entire pod fails, OpenShift Container Platform starts a new pod. Developers need to address the possibility that applications might be restarted in a new pod. In particular, applications need to handle temporary files, locks, incomplete output, and so forth caused by previous runs.
For details on how OpenShift Container Platform uses restart policy with failed containers, see the Example States in the Kubernetes documentation.
Init Containers
An init container is a container in a pod that is started before the pod app containers are started. Init containers can share volumes, perform network operations, and perform computations before the remaining containers start. Init containers can also block or delay the startup of application containers until some precondition is met.
When a pod starts, after the network and volumes are initialized, the init containers are started in order. Each init container must exit successfully before the next is invoked. If an init container fails to start (due to the runtime) or exits with failure, it is retried according to the pod restart policy.
A pod cannot be ready until all init containers have succeeded.
See the Kubernetes documentation for some init container usage examples.
Init containers can include activeDeadlineSeconds on the pod and livenessProbe on the container to prevent init containers from failing forever. The active deadline includes init containers.
Services
A Kubernetes service serves as an internal load balancer. It identifies a set of replicated pods in order to proxy the connections it receives to them. Backing pods can be added to or removed from a service arbitrarily while the service remains consistently available, enabling anything that depends on the service to refer to it at a consistent address. The default service clusterIP addresses are from the OpenShift Container Platform internal network and they are used to permit pods to access each other.
To permit external access to the service, additional externalIP and ingressIP addresses that are external to the cluster can be assigned to the service. These externalIP addresses can also be virtual IP addresses that provide highly available access to the service.
Services are assigned an IP address and port pair that, when accessed, proxy to an appropriate backing pod. A service uses a label selector to find all the containers running that provide a certain network service on a certain port.
Like pods, services are REST objects. The following example shows the definition of a service for the pod defined above:
The service name docker-registry is also used to construct an environment variable with the service IP that is inserted into other pods in the same namespace. The maximum name length is 63 characters. |
The label selector identifies all pods with the docker-registry=default label attached as its backing pods. |
Virtual IP of the service, allocated automatically at creation from a pool of internal IPs. |
Port the service listens on. |
Port on the backing pods to which the service forwards connections. |
The Kubernetes documentation has more information on services.
Service externalIPs
In addition to the cluster’s internal IP addresses, the user can configure IP addresses that are external to the cluster. The administrator is responsible for ensuring that traffic arrives at a node with this IP.
The externalIPs must be selected by the cluster adminitrators from the externalIPNetworkCIDRs range configured in master-config.yaml file. When master-config.yaml is changed, the master services must be restarted.
List of external IP addresses on which the port is exposed. This list is in addition to the internal IP address list. |
Service ingressIPs
In non-cloud clusters, externalIP addresses can be automatically assigned from a pool of addresses. This eliminates the need for the administrator manually assigning them.
The pool is configured in /etc/origin/master/master-config.yaml file. After changing this file, restart the master service.
The ingressIPNetworkCIDR is set to 172.29.0.0/16 by default. If the cluster environment is not already using this private range, use the default range or set a custom range.
If you are using high availability, then this range must be less than 256 addresses.
Service NodePort
Setting the service type=NodePort will allocate a port from a flag-configured range (default: 30000-32767), and each node will proxy that port (the same port number on every node) into your service.
To specify a custom port just place the port number in the nodePort field. The custom port number must be in the configured range for nodePorts. When ‘master-config.yaml‘ is changed the master services must be restarted.
The service will be visible as both the :spec.ports[].nodePort and spec.clusterIp:spec.ports[].port
Setting a nodePort is a privileged operation.
Service Proxy Mode
OpenShift Container Platform has two different implementations of the service-routing infrastructure. The default implementation is entirely iptables-based, and uses probabilistic iptables rewriting rules to distribute incoming service connections between the endpoint pods. The older implementation uses a user space process to accept incoming connections and then proxy traffic between the client and one of the endpoint pods.
The iptables-based implementation is much more efficient, but it requires that all endpoints are always able to accept connections; the user space implementation is slower, but can try multiple endpoints in turn until it finds one that works. If you have good readiness checks (or generally reliable nodes and pods), then the iptables-based service proxy is the best choice. Otherwise, you can enable the user space-based proxy when installing, or after deploying the cluster by editing the node configuration file.
Headless services
If your application does not need load balancing or single-service IP addresses, you can create a headless service. When you create a headless service, no load-balancing or proxying is done and no cluster IP is allocated for this service. For such services, DNS is automatically configured depending on whether the service has selectors defined or not.
Services with selectors: For headless services that define selectors, the endpoints controller creates Endpoints records in the API and modifies the DNS configuration to return A records (addresses) that point directly to the pods backing the service.
Services without selectors: For headless services that do not define selectors, the endpoints controller does not create Endpoints records. However, the DNS system looks for and configures the following records:
For ExternalName type services, CNAME records.
For all other service types, A records for any endpoints that share a name with the service.
Creating a headless service
Creating a headless service is similar to creating a standard service, but you do not declare the ClusterIP address. To create a headless service, add the clusterIP: None parameter value to the service YAML definition.
For example, for a group of pods that you want to be a part of the same cluster or service.
You can define the headless service as:
Name of the headless service. |
Setting clusterIP variable to None declares a headless service. |
Selects all pods that have frontend label. |
Also, headless service does not have any IP address of its own.
Endpoint discovery by using a headless service
The benefit of using a headless service is that you can discover a pod’s IP address directly. Standard services act as load balancer or proxy and give access to the workload object by using the service name. With headless services, the service name resolves to the set of IP addresses of the pods that are grouped by the service.
When you look up the DNS A record for a standard service, you get the loadbalanced IP of the service.
But for a headless service, you get the list of IPs of individual pods.
Labels
Labels are used to organize, group, or select API objects. For example, pods are «tagged» with labels, and then services use label selectors to identify the pods they proxy to. This makes it possible for services to reference groups of pods, even treating pods with potentially different containers as related entities.
Most objects can include labels in their metadata. So labels can be used to group arbitrarily-related objects; for example, all of the pods, services, replication controllers, and deployment configurations of a particular application can be grouped.
Labels are simple key/value pairs, as in the following example:
A pod consisting of an nginx container, with the label role=webserver.
A pod consisting of an Apache httpd container, with the same label role=webserver.
A service or replication controller that is defined to use pods with the role=webserver label treats both of these pods as part of the same group.
The Kubernetes documentation has more information on labels.
Endpoints
The servers that back a service are called its endpoints, and are specified by an object of type Endpoints with the same name as the service. When a service is backed by pods, those pods are normally specified by a label selector in the service specification, and OpenShift Container Platform automatically creates the Endpoints object pointing to those pods.
In some cases, you may want to create a service but have it be backed by external hosts rather than by pods in the OpenShift Container Platform cluster. In this case, you can leave out the selector field in the service, and create the Endpoints object manually.
Note that OpenShift Container Platform will not let most users manually create an Endpoints object that points to an IP address in the network blocks reserved for pod and service IPs. Only cluster admins or other users with permission to create resources under endpoints/restricted can create such Endpoint objects.