Labels и селекторы
По каким меткам объекты кластера находят друг друга и как их фильтровать через -l.
Что такое label
Label это пара ключ-значение в поле metadata.labels любого
ресурса. И ключ, и значение - строки.
metadata:
name: web-1
labels:
app: web
env: prod
Label служит не для описания. По нему объекты в кластере находят друг друга. Service по label находит свои Pod. Deployment по label считает, какие реплики принадлежат ему. NetworkPolicy - правило, которое ограничивает сетевой трафик между Pod. Она тоже опирается на label, чтобы выбрать, к каким Pod применяется. Pod без label почти бесполезен: ни один Service на него не наведётся.
Annotation - произвольная пометка на объекте (metadata.annotations).
Выглядит как label, но служит другому: это данные для инструментов.
По annotation нельзя фильтровать. Если значение нужно для поиска, клади его в label.
Если это просто заметка, клади в annotation.
| Признак | metadata.labels | metadata.annotations |
|---|---|---|
Фильтр -l | работает | не работает |
| Кто читает | Service, Deployment, NetworkPolicy | внешние инструменты |
| Что класть | значение для поиска | заметку |
Фильтрация через -l
Флаг -l (или --selector) фильтрует ресурсы по label. Простейшая
форма проверяет равенство:
kubectl get pod -l app=web
Команда покажет только Pod с label app=web. Условия можно соединять
через запятую, это логическое И:
kubectl get pod -l app=web,env=prod
Неравенство пишется через !=:
kubectl get pod -l env!=dev
Есть и более гибкий синтаксис на множествах (set-based):
kubectl get pod -l 'env in (prod, staging)'
kubectl get pod -l 'env notin (dev)'
kubectl get pod -l 'tier' # есть label tier с любым значением
kubectl get pod -l '!tier' # нет label tier вообще
Кавычки здесь обязательны. Без них оболочка интерпретирует скобки и восклицательный знак как спецсимволы, и команда сломается.
Большая буква -L работает иначе. kubectl get pod -L app,env не
фильтрует, а добавляет значения этих label в вывод как колонки.
Ещё один способ посмотреть метки:
kubectl get pod --show-labels
Команда kubectl label
Навесить label:
kubectl label pod web-1 tier=backend
Поменять значение существующего label (нужен --overwrite, иначе
ошибка):
kubectl label pod web-1 tier=frontend --overwrite
Снять label (суффикс - после ключа, без значения):
kubectl label pod web-1 tier-
Применить сразу к нескольким Pod по селектору:
kubectl label pod -l app=db tier=backend
kubectl label pod --all env-
-l app=db пройдётся по всем Pod, у которых уже есть label app=db.
--all берёт все Pod в namespace без условий.
Зачем это нужно
Service ищет свои Pod через поле spec.selector. Это label-селектор
такого же вида:
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- port: 80
Selector это не ссылка на объект, а совпадение строк. Никто не проверяет, что метка с такой парой ключ-значение вообще существует в кластере.
Ключи label регистрозависимы. app и App - это разные ключи. Если
в селекторе написать App: web, а Pod лежат с app: web, Service не
найдёт ни одного Pod. Ошибки при этом не будет, просто список endpoints (реальные адреса Pod за Service)
останется пустым.
Смотрят его так:
kubectl get endpointslice -l kubernetes.io/service-name=web
Старая команда kubectl get endpoints web выводит то же самое, но объект
v1 Endpoints deprecated с 1.33 и kubectl печатает про это
предупреждение.
Если снять label app=web у работающего Pod, он выпадет из Service.
Снаружи это выглядит как «Pod в статусе Running, а трафика нет».
Deployment держит свои Pod через spec.selector.matchLabels. Если у
Pod убрать подходящий label, Deployment перестанет его видеть и
поднимет новый Pod на замену. Старый Pod останется висеть в namespace
без управления. Это полезно для разбора инцидента: Pod жив, но
изолирован от системы.
Домашка
Теорию закрепляет задание на своём кластере: 3 шага с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.
./run.sh start k8s-labels-selectors # развернуть стартовое состояние
./run.sh verify k8s-labels-selectors # проверить текущий шаг
Коротко
- Label это пара ключ-значение в
metadata.labels, по ней объекты находят друг друга. - Annotation похожа на label, но по ней нельзя фильтровать.
-lфильтрует по меткам,-Lдобавляет их колонками в вывод.- Set-based селекторы (
in,notin,tier,!tier) требуют кавычек. kubectl labelвешает, меняет (--overwrite) и снимает (ключ-) метки, в том числе группой по-lили--all.- Ключи регистрозависимы: селектор
Appне найдёт Pod сapp, и ошибки не будет - endpoints просто останутся пустыми.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс