Що таке Namespace в Kubernetes?
Namespace — це як квартири в багатоквартирному будинку. Усі квартири в одному будинку (кластері), але у кожної свій номер (ім'я). В квартирі 1 і квартирі 2 може бути свій телеві...
🟢 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.
Два типи ресурсів:
- Namespace-scoped — належать namespace’у: Pod, Service, Deployment, ConfigMap, Secret, PVC
- 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’ів:
- Termination: При
kubectl delete namespace X, контроллер ставитьstatus.phase: Terminatingі починає видаляти усі ресурси в namespace’і - Finalizer: Namespace має finalizer
kubernetes. Він блокує видалення, поки усі ресурси не видалені - 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’ів.
Що сталося:
- 50 Pod’ів запросили 5000 CPU, але кластер мав тільки 2000 CPU
- Pod’и зависли в
Pending, kube-scheduler не міг розмістити - API Server почав гальмувати через велику кількість
FailedSchedulingevents - kube-controller-manager почав backlog reconciliation, latency API Server зросла до 5 секунд
- Усі 50 команд почали відчувати проблеми з деплоями та health checks
- 4-годинний outage, поки адміністратори не видалили rogue Deployment
Post-mortem та fix:
- Впроваджені ResourceQuota на кожен namespace (max CPU, memory, pods)
- Заборонено деплой без LimitRange через ValidatingAdmissionWebhook
- Namespace-per-env стратегія замість namespace-per-team:
team-payments-dev,team-payments-prod - Моніторинг
kube_resourcequotaз alert’ами при наближенні до лімітів - RBAC: команди можуть деплоїти тільки в свої namespace’и
- Введено “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 панелі:
- ResourceQuota usage heatmap (по namespace’ам) — червоний при > 80%
- Pod count та status distribution — Pending/Running/Failed
- API Server latency p99 — alert при > 1 секунди
- Namespace lifecycle events — creation/deletion rate
- Cross-namespace network traffic — через NetworkPolicy metrics
- etcd storage usage — namespace ключі займають ~5-10% від etcd
Highload Best Practices
- Використовуйте namespace-per-env стратегію —
team-a-dev,team-a-prodзамість одного namespace для всіх env - ResourceQuota на кожен namespace — без квот один namespace може захопити увесь кластер
- LimitRange за замовчуванням — щоб Pod’и без requests/limits не стартували без дефолтних значень
- NetworkPolicy deny-by-default — забороніть між-namespace трафік, дозволяйте тільки потрібне
- Pod Security Admission
restrictedдля production namespace’ів - ValidatingAdmissionWebhook — забороніть деплой в
defaultnamespace, вимагайте labels - Monitor ResourceQuota usage — alert при 80% utilisation
- Уникайте >100 namespace’ів в одному кластері — API Server та etcd починають гальмувати при великій кількості namespace’ів
- Використовуйте kubectl contexts —
kubectl config use-context team-a-prodдля уникнення помилок деплою “не туди” - 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’ам