Что такое Namespace в Kubernetes?
Namespace — это как квартиры в многоквартирном доме. Все квартиры в одном здании (кластере), но у каждой свой номер (имя). В квартире 1 и квартире 2 может быть свой телевизор (P...
🟢 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’ами. Если все сервисы используют один 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’ов:
- 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’ам