Labels и Annotations — пары ключ/значение на объектах Kubernetes. Разница: labels используются для выборки через Selector, annotations — нет. Service, Deployment и ReplicaSet связываются с Pod через Selector по labels.
[source: kubernetes.io/docs/concepts/overview/working-with-objects/labels/]
Labels
Label — пара ключ/значение, прикреплённая к объекту. Используется для идентификации, группировки и выборки объектов через Selector.
Синтаксис
Ключ состоит из необязательного префикса и имени, разделённых /:
- Префикс — DNS-поддомен, до 253 символов (например,
app.kubernetes.io/) - Имя — до 63 символов, начинается и заканчивается буквенно-цифровым символом, допускаются
-,_,.
Значение — до 63 символов, те же правила что и для имени, может быть пустой строкой.
metadata:
labels:
app: frontend
environment: production
tier: web
version: v2.1.0
app.kubernetes.io/name: frontend
app.kubernetes.io/component: web
Рекомендованные labels
Kubernetes рекомендует использовать стандартные ключи с префиксом app.kubernetes.io/:
[source: kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/]
Стандартные labels помогают инструментам (Helm, Argo CD, Lens) корректно отображать зависимости.
Управление labels через kubectl
# Добавить label
kubectl label pod nginx-pod tier=frontend
# Изменить существующий label
kubectl label pod nginx-pod tier=backend --overwrite
# Удалить label
kubectl label pod nginx-pod tier-
# Показать labels
kubectl get pods --show-labels
# Показать конкретные labels как столбцы
kubectl get pods -L app,environment
Selectors
Selector фильтрует объекты по labels. Используется в Service, Deployment, ReplicaSet, Job и других ресурсах для определения, с какими Pod работать.
[source: kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors]
Equality-based (на основе равенства)
# Равенство
kubectl get pods -l environment=production
# Неравенство
kubectl get pods -l environment!=staging
# Несколько условий (AND)
kubectl get pods -l "app=frontend,environment=production"
Set-based (на основе множеств)
# Значение входит в множество
kubectl get pods -l "environment in (production,staging)"
# Значение не входит в множество
kubectl get pods -l "environment notin (dev,test)"
# Label существует (любое значение)
kubectl get pods -l "release"
# Label не существует
kubectl get pods -l "!canary"
Selectors в манифестах
matchLabels — equality-based, короткая форма:
selector:
matchLabels:
app: frontend
environment: production
matchExpressions — set-based, гибкая форма:
selector:
matchExpressions:
- key: environment
operator: In
values:
- production
- staging
- key: tier
operator: NotIn
values:
- test
- key: release
operator: Exists
- key: canary
operator: DoesNotExist
Операторы matchExpressions: In, NotIn, Exists, DoesNotExist. При указании и matchLabels, и matchExpressions все условия объединяются через AND.
Критическое правило для Deployment и ReplicaSet
spec.selector.matchLabels в Deployment/ReplicaSet должен совпадать с spec.template.metadata.labels. API Server отклонит манифест при несовпадении. Более того, selector у Deployment и ReplicaSet неизменяем после создания — изменить его можно только пересозданием объекта.
spec:
selector:
matchLabels:
app: nginx # должно совпадать
template:
metadata:
labels:
app: nginx # должно совпадать
Annotations
Annotations — пары ключ/значение для хранения произвольных метаданных. Не используются для выборки объектов, не влияют на поведение Kubernetes напрямую.
[source: kubernetes.io/docs/concepts/overview/working-with-objects/annotations/]
metadata:
annotations:
description: "Main frontend application"
build.version: "git-sha-a1b2c3d"
contact: "[email protected]"
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
nginx.ingress.kubernetes.io/rewrite-target: /
Ограничения: ключ — те же правила что у labels. Значение — произвольная строка без ограничения длины (в отличие от labels: 63 символа).
kubectl.kubernetes.io/last-applied-configuration
Специальная annotation, которую kubectl apply добавляет автоматически. Хранит последний применённый манифест в JSON. Используется для вычисления трёхстороннего diff при следующем apply. Из-за неё kubectl apply знает, что было удалено из манифеста.
# Просмотреть annotations
kubectl describe pod nginx-pod
# Добавить annotation
kubectl annotate pod nginx-pod description="My app"
# Изменить annotation
kubectl annotate pod nginx-pod description="Updated" --overwrite
# Удалить annotation
kubectl annotate pod nginx-pod description-
Labels vs Annotations: когда что
Если данные нужны для выборки или группировки — labels. Если для информации, инструментов или автоматизации — annotations.
Минимальный набор labels для production Pod: app.kubernetes.io/name, environment, app.kubernetes.io/version.
Типичные ошибки
Опечатка в label у Pod и Selector у Service. Service не найдёт endpoint — трафик некуда направлять. Диагностика: kubectl get endpoints <service-name> — пустой список означает несовпадение labels.
Слишком общий Selector. Selector app: nginx может подобрать Pod из разных Deployment, если они используют одинаковый label. Добавляй уточняющие labels: app: nginx, environment: production, tier: frontend.
Хранить секреты в annotations. Annotations видны всем, у кого есть доступ на чтение объекта. Секреты — только в Secret.
Изменять selector у существующего Deployment. Selector у Deployment immutable. Попытка изменить через kubectl apply получит ошибку. Нужно удалить Deployment и создать заново (с даунтаймом) или использовать canary-стратегию через отдельный Deployment.
Альтернативы
Для сложной группировки объектов, выходящей за рамки labels:
- Namespaces — изолируют группы объектов на уровне кластера (глава 04)
- Owner References — автоматически проставляются Kubernetes для связи Deployment → ReplicaSet → Pod; прямое использование не требуется
- Field Selectors — фильтрация по полям объекта (
status.phase=Running), но не по произвольным данным
← 02: Pod