Вопрос 21 · Раздел 14

Что такое Namespace в Kubernetes?

Namespace — это как квартиры в многоквартирном доме. Все квартиры в одном здании (кластере), но у каждой свой номер (имя). В квартире 1 и квартире 2 может быть свой телевизор (P...

Версии по языкам: English Russian Ukrainian

🟢 Junior Level

Простое определение

Namespace (Пространство имён) — это способ логически разделить ресурсы внутри одного Kubernetes кластера. Представьте, что кластер — это большой компьютер, а Namespace’ы — это папки на этом компьютере. В каждой папке могут быть свои Pod’ы, Services, Deployment’ы с одинаковыми именами, и они не будут конфликтовать.

Namespace – это не физическое разделение (Pod’ы из разных namespace всё ещё могут общаться по сети). Это логическая группировка для удобства управления и изоляции RBAC.

Аналогия

Namespace — это как квартиры в многоквартирном доме. Все квартиры в одном здании (кластере), но у каждой свой номер (имя). В квартире 1 и квартире 2 может быть свой телевизор (Pod с именем web-app), и они не мешают друг другу.

Пример YAML

# Создание Namespace
apiVersion: v1
kind: Namespace
metadata:
  name: production

# Deployment в namespace production
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: app
          image: my-app:1.0

Пример kubectl

# Посмотреть все namespace'ы
kubectl get namespaces

# Посмотреть Pod'ы в конкретном namespace
kubectl get pods -n production

# Создать Pod в namespace
kubectl run my-pod --image=nginx -n staging

# Установить namespace по умолчанию (чтобы не писать -n каждый раз)
kubectl config set-context --current --namespace=production

Когда использовать

  • Разделение окружений: dev, staging, production в одном кластере
  • Разделение команд: каждая команда получает свой namespace
  • Ограничение ресурсов: установить квоты CPU/RAM на namespace
  • Изоляция: разные проекты не видят ресурсы друг друга

🟡 Middle Level

Как это работает

Namespace — это поле в metadata каждого Kubernetes объекта. API Server использует его для группировки и фильтрации ресурсов. Когда вы делаете kubectl get pods -n production, API Server возвращает только Pod’ы с metadata.namespace: production.

Два типа ресурсов:

  1. Namespace-scoped — принадлежат namespace’у: Pod, Service, Deployment, ConfigMap, Secret, PVC
  2. Cluster-scoped — не принадлежат никакому namespace’у: Node, PersistentVolume, StorageClass, ClusterRole, Namespace

DNS между namespace’ами:

# Внутри одного namespace
http://my-service

# Между namespace'ами (FQDN)
http://my-service.staging.svc.cluster.local
# Формат: <service-name>.<namespace>.svc.cluster.local

Практические сценарии

Сценарий 1: Разделение окружений

Кластер:
├── namespace: dev       — для разработки
├── namespace: staging   — для тестирования
├── namespace: production — для продакшена

Один кластер, три окружения. Команда деплоит в dev, QA тестирует в staging, production стабилен.

Сценарий 2: Resource Quotas

apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
  namespace: dev
spec:
  hard:
    requests.cpu: "10"
    requests.memory: 20Gi
    limits.cpu: "20"
    limits.memory: 40Gi
    pods: "50"
    services: "20"

Команда dev не может потребовать больше 10 CPU и 20Gi RAM, даже если кластер большой.

Сценарий 3: RBAC по namespace’ам

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: dev-reader
  namespace: dev
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-reader-binding
  namespace: dev
subjects:
  - kind: User
    name: developer@company.com
roleRef:
  kind: Role
  name: dev-reader
  apiGroup: rbac.authorization.k8s.io

Разработчик видит только namespace dev, не имеет доступа к production.

Таблица распространённых ошибок

Ошибка Последствие Решение
Использование namespace default Все ресурсы в одном namespace, нет изоляции Всегда создавать отдельные namespace’ы для каждого проекта
Забыть указать -n в kubectl Команды выполняются в default или текущем контексте, ресурсы “не найдены” Использовать kubectl config set-context --current --namespace=...
NetworkPolicy не настроен Pod’ы из разных namespace’ов общаются свободно, нет сетевой изоляции Настроить NetworkPolicy для ограничения меж-namespace трафика
ResourceQuota слишком строгий Pod’ы не могут стартовать, FailedScheduling из-за quota exceeded Мониторить kube_resourcequota метрики, настраивать квоты по фактическому потреблению
Cluster-scoped ресурсы путают с namespace-scoped Попытка создать PV или Node в namespace’е — ошибка Помнить: Node, PV, StorageClass, ClusterRole — cluster-scoped
Secrets не копируются между namespace’ами Deployment в staging работает, в production — нет, так как Secret не создан Использовать External Secrets Operator или копировать Secrets вручную

Сравнительная таблица: Стратегии организации Namespace

Стратегия Плюсы Минусы Когда использовать
По окружениям (dev, staging, prod) Просто, понятно, легко квотировать Все команды в одном namespace, возможен конфликт Маленькие команды, один продукт
По командам (team-a, team-b) Изоляция команд, независимый деплой Сложнее управлять окружениями внутри namespace Большие организации, мультитенантность
По продуктам (product-a, product-b) Полный цикл продукта в одном namespace Может быть дорого (квоты на каждый продукт) Несколько продуктов, разные SLA
Гибрид (team-a-dev, team-a-prod) Лучшее из обоих миров Больше namespace’ов, сложнее администрировать Средние и крупные организации

Когда НЕ использовать

  • Один проект, одна команда, один кластер — Namespace добавляет сложность без пользы (хотя всё равно лучше, чем default)
  • Нужна полная изоация — Namespace даёт только логическую, не физическую изоляцию. Для полной изоляции нужен отдельный кластер
  • Нужна общая конфигурация для всех — ConfigMap и Secrets не шарятся между namespace’ами. Если все сервисы используют один Config, придётся копировать в каждый namespace

🔴 Senior Level

Глубинная механика: API Server, etcd, и Controller Reconciliation

Хранение в etcd: Namespace — это не просто “папка”. Это полноценный Kubernetes объект (kind: Namespace), хранящийся в etcd по ключу:

/registry/namespaces/<name>

Ресурсы в namespace хранятся как:

/registry/pods/<namespace>/<pod-name>
/registry/services/<namespace>/<service-name>

API Server фильтрует ресурсы по metadata.namespace полю. Запрос GET /api/v1/namespaces/production/pods транслируется в etcd запрос с префиксом /registry/pods/production/.

Namespace Lifecycle Controller: kube-controller-manager запускает namespace контроллер, который управляет жизненным циклом namespace’ов:

  1. Termination: При kubectl delete namespace X, контроллер ставит status.phase: Terminating и начинает удалять все ресурсы в namespace’е
  2. Finalizer: Namespace имеет finalizer kubernetes. Он блокирует удаление, пока все ресурсы не удалены
  3. Garbage Collection: Контроллер итеративно удаляет ресурсы, но если какой-то ресурс имеет свой finalizer (например, PVC с persistentVolumeClaim), удаление namespace’а зависает

Discovery и DNS: CoreDNS (или kube-dns) обслуживает DNS-запросы внутри кластера. Для меж-namespace коммуникации:

my-service.staging.svc.cluster.local

CoreDNS резольвит это в ClusterIP Service’а через запись в etcd. Если Service в другом namespace удалён, DNS вердёт NXDOMAIN.

Admission Controllers:

  • LimitRanger — применяет LimitRange к namespace’у при создании Pod’ов
  • ResourceQuota — проверяет, не превышены ли квоты namespace’а
  • NamespaceLifecycle — отклоняет запросы к namespace’ам в Terminating состоянии

Trade-offs

Аспект Trade-off
Один кластер vs много кластеров Один кластер дешевле и проще управлять, но failure domain общий. Много кластеров = полная изоляция, но дороже и сложнее
Namespace-per-team vs Namespace-per-env Per-team = лучше изоляция команд. Per-env = проще CI/CD pipeline. Гибрид = лучшее, но сложнее
ResourceQuota строгий vs мягкий Строгий = предсказуемые ресурсы, но возможны FailedScheduling. Мягкий = гибкость, но риск resource starvation
NetworkPolicy strict vs permissive Strict = безопасность, но сложно поддерживать. Permissive = просто, но любой Pod может общаться с любым
Shared vs isolated Control Plane Shared (один API Server) дешевле. Isolated (отдельные кластеры) даёт failure domain isolation

Edge Cases (6+)

Edge Case 1: Namespace зависает в Terminating При kubectl delete namespace X namespace застревает в Terminating. Причина: какой-то ресурс имеет finalizer, который не может завершиться (например, external-provisioner для PVC не отвечает). Решение:

# Посмотреть, что блокирует
kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found -n X

# Принудительное удаление (dangerous!)
kubectl get namespace X -o json | jq '.spec.finalizers=[]' | kubectl replace --raw "/api/v1/namespaces/X/finalize" -f -

Edge Case 2: Default namespace ResourceQuota отсутствует По умолчанию namespace default не имеет ResourceQuota. Если разработчик случайно задеплоил в default, Pod может потреблять неограниченные ресурсы, starving другие namespace’ы.

Не используйте default namespace в продакшене – это плохая практика. Создайте отдельные namespace’ы для dev/staging/prod.

Решение: создать ResourceQuota для default и запретить его использование через Admission Webhook.

Edge Case 3: Cross-namespace Service с ExternalName

kind: Service
apiVersion: v1
metadata:
  name: external-db
  namespace: production
spec:
  type: ExternalName
  externalName: db.database.svc.cluster.local

Production сервис резольвит адрес в namespace database. Если database namespace удалён, Service молча возвращает NXDOMAIN только при DNS запросе — нет валидации при создании.

Edge Case 4: Cluster-scoped ресурсы “утекают” через namespace StorageClass — cluster-scoped. Если команда A создала StorageClass fast-ssd, команда B может использовать его в своём namespace без ограничений. Для изоляции нужно использовать StorageClass с allowedTopologies или RBAC на StorageClass.

Edge Case 5: LimitRange + HPA конфликт LimitRange устанавливает max CPU на контейнер (например, 2 CPU). HPA хочет масштабировать Pod до 4 CPU. Pod не может запросить больше LimitRange max, HPA не может добавить реплики с нужными ресурсами. Результат: HPA stuck, application underperforming.

Edge Case 6: Namespace и Pod Security Standards (PSS) Kubernetes 1.25+ заменил PodSecurityPolicy на Pod Security Admission (PSA). PSA применяется на уровне namespace через label:

metadata:
  labels:
    pod-security.kubernetes.io/enforce: "restricted"
    pod-security.kubernetes.io/audit: "restricted"
    pod-security.kubernetes.io/warn: "restricted"

Если namespace не имеет PSA labels, применяется cluster-wide default (обычно baseline). Это может создать false sense of security.

Edge Case 7: Service Mesh sidecar injection и namespace Istio/Venice injects sidecar на уровне namespace через label:

metadata:
  labels:
    istio-injection: "enabled"

Если namespace не имеет label, sidecar не инжектируется. Pod работает без mTLS, без observability. При миграции между namespace’ами легко забыть про label.

Performance Numbers

Метрика Значение
API Server namespace filter latency ~1-5ms для запроса к namespace с 100 ресурсами
etcd key prefix scan (per namespace) ~5-20ms для namespace с 500 ресурсами
Namespace deletion (1000 ресурсов) 10-60 секунд (зависит от finalizer’ов)
CoreDNS cross-namespace resolution 1-5ms
Maximum namespaces per cluster Не ограничен (практически ~10000, упирается в etcd capacity)
ResourceQuota evaluation latency ~1-10ms при создании Pod’а
NetworkPolicy across namespaces ~5-20ms latency overhead (iptables/ipvs rules)

Security

  • Namespace ≠ Security Boundary — Pod в namespace A может получить доступ к Pod в namespace B по умолчанию. Для изоляции нужен NetworkPolicy + RBAC
  • RBAC namespace-scoped (Role) vs cluster-scoped (ClusterRole) — Role ограничена namespace’ом, ClusterRole — весь кластер. Не путайте!
  • Secrets isolation — Secrets видны только в своём namespace’е. Но администратор кластера (с ClusterRole) может читать Secrets из всех namespace’ов
  • Pod Security Admission (PSA) — применяется на уровне namespace. Используйте restricted для production namespace’ов
  • Admission Webhooks — можно создать ValidatingAdmissionWebhook, запрещающий деплой в namespace default или требующий определённые labels
  • Service Account токены — автоматически создаются в каждом namespace. Не шарьте Service Account между namespace’ами — это нарушение изоляции
  • NetworkPolicy — единственный способ изолировать сеть между namespace’ами:
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: deny-cross-namespace
      namespace: production
    spec:
      podSelector: {}
      policyTypes:
        - Ingress
      ingress:
        - from:
            - namespaceSelector:
                matchLabels:
                  kubernetes.io/metadata.name: production
    

Production War Story

Ситуация: Крупная компания, 50 команд, один кластер с 50 namespace’ами (по одному на команду). Каждая команда управляла своим namespace’ом: dev, staging, production внутри одного namespace. Одна команда (team-payments) создала Deployment без ResourceQuota и LimitRange, с requests.cpu: "100" на 50 Pod’ов.

Что произошло:

  1. 50 Pod’ов запросили 5000 CPU, но кластер имел только 2000 CPU
  2. Pod’ы зависли в Pending, kube-scheduler не мог разместить
  3. API Server начал тормозить из-за большого количества FailedScheduling events
  4. kube-controller-manager начал backlog reconciliation, latency API Server выросла до 5 секунд
  5. Все 50 команд начали испытывать проблемы с деплоями и health checks
  6. 4-часовой outage, пока администраторы не удалили rogue Deployment

Post-mortem и fix:

  1. Внедрены ResourceQuota на каждый namespace (max CPU, memory, pods)
  2. Запрещён деплой без LimitRange через ValidatingAdmissionWebhook
  3. Namespace-per-env стратегия вместо namespace-per-team: team-payments-dev, team-payments-prod
  4. Мониторинг kube_resourcequota с alert’ами при приближении к лимитам
  5. RBAC: команды могут деплоить только в свои namespace’ы
  6. Введён “cluster capacity planning” процесс — квоты пересматриваются ежемесячно

Мониторинг после fix:

# Alert: Namespace приближается к ResourceQuota
kube_resourcequota{type="used"} / kube_resourcequota{type="hard"} > 0.8

# Alert: Pod'ы в Pending > 5 минут
sum(kube_pod_status_phase{phase="Pending"}) by (namespace) > 5

# Alert: API Server latency
histogram_quantile(0.99, apiserver_request_duration_seconds_bucket) > 1

Monitoring (Prometheus/Grafana)

Ключевые метрики:

# ResourceQuota usage по namespace'ам
kube_resourcequota{type="used"} / kube_resourcequota{type="hard"}

# Pod count по namespace'ам
sum(kube_pod_status_phase) by (namespace, phase)

# Namespace в Terminating > 5 минут
kube_namespace_status_phase{phase="Terminating"}

# API Server requests latency
histogram_quantile(0.99, apiserver_request_duration_seconds_bucket)

# etcd request latency
histogram_quantile(0.99, etcd_request_duration_seconds_bucket)

# Failed scheduling events
rate(kube_pod_status_reason_condition{reason="FailedScheduling"}[5m])

Grafana Dashboard панели:

  1. ResourceQuota usage heatmap (по namespace’ам) — красный при > 80%
  2. Pod count и status distribution — Pending/Running/Failed
  3. API Server latency p99 — alert при > 1 секунды
  4. Namespace lifecycle events — creation/deletion rate
  5. Cross-namespace network traffic — через NetworkPolicy metrics
  6. etcd storage usage — namespace ключи занимают ~5-10% от etcd

Highload Best Practices

  1. Используйте namespace-per-env стратегиюteam-a-dev, team-a-prod вместо одного namespace для всех env
  2. ResourceQuota на каждый namespace — без квот один namespace может захватить весь кластер
  3. LimitRange по умолчанию — чтобы Pod’ы без requests/limits не стартовали без дефолтных значений
  4. NetworkPolicy deny-by-default — запретите меж-namespace трафик, разрешайте только нужное
  5. Pod Security Admission restricted для production namespace’ов
  6. ValidatingAdmissionWebhook — запретите деплой в default namespace, требуйте labels
  7. Monitor ResourceQuota usage — alert при 80% utilisation
  8. Избегайте >100 namespace’ов в одном кластере — API Server и etcd начинают тормозить при большом количестве namespace’ов
  9. Используйте kubectl contextskubectl config use-context team-a-prod для избежания ошибок деплоя “не туда”
  10. Cluster capacity planning — ежемесячный review квот, планирование масштабирования кластера

🎯 Шпаргалка для интервью

Обязательно знать:

  • Namespace — логическая (не физическая!) группировка ресурсов в K8s кластере
  • DNS между namespace’ами: service.namespace.svc.cluster.local
  • ResourceQuota ограничивает CPU/RAM/Pod’ы на namespace; LimitRange — дефолты для контейнеров
  • RBAC: Role (namespace-scoped) vs ClusterRole (весь кластер)
  • Namespace ≠ Security Boundary — Pod из A может общаться с B без NetworkPolicy
  • Default namespace — не для продакшена; всегда создавайте отдельные namespace’ы
  • Cluster-scoped ресурсы: Node, PV, StorageClass, ClusterRole (не принадлежат namespace’у)

Частые уточняющие вопросы:

  • «Namespace изолирует сеть?» — Нет, только логически; для сетевой изоляции нужен NetworkPolicy
  • «Namespace зависает в Terminating — почему?» — Ресурс с finalizer не может завершиться (например, external-provisioner)
  • «Максимум namespace’ов?» — Формально не ограничен; практически ~10000 (упирается в etcd)
  • «Secrets шарятся между namespace’ами?» — Нет, каждый Secret виден только в своём namespace

Красные флаги (НЕ говорить):

  • «Namespace = полная изоляция» (нужны NetworkPolicy + RBAC)
  • «Использую default namespace для продакшена» (плохая практика)
  • «Namespace заменяет отдельный кластер» (нет failure domain isolation)
  • «PV принадлежит namespace’у» (PV — cluster-scoped ресурс)

Связанные темы:

  • [[Что такое Kubernetes и зачем он нужен]] — объекты K8s
  • [[В чём разница между ConfigMap и Secret]] — Secrets в namespace
  • [[Как мониторить приложения в Kubernetes]] — мониторинг по namespace’ам