Питання 21 · Розділ 14

Що таке Namespace в Kubernetes?

Namespace — це як квартири в багатоквартирному будинку. Усі квартири в одному будинку (кластері), але у кожної свій номер (ім'я). В квартирі 1 і квартирі 2 може бути свій телеві...

Мовні версії: 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’ами. Якщо усі сервіси використовують один конфіг, доведеться копіювати в кожен 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’ам