Что такое namespace
Namespace — это квартиры в большом многоквартирном доме:
🟢 Junior Level
30-секундный ответ
Namespace (Пространство имён) — это встроенный механизм Kubernetes для виртуального логического разделения одного физического кластера на изолированные рабочие области для разных команд, проектов или окружений (dev, stage, prod).
- Устранение конфликта имён: внутри одного namespace имена ресурсов должны быть уникальными, но в разных пространствах имён могут одновременно работать поды или сервисы с абсолютно одинаковыми именами (например,
payment-serviceвdevиpayment-serviceвprod). - Разделение прав доступа (RBAC): администратор может дать разработчикам полные права в пространстве
developer-sandbox, но запретить даже чтение логов в пространствеproduction. - Ограничение ресурсов: каждому пространству имён можно задать жесткий лимит по суммарному расходу CPU и оперативной памяти (ResourceQuota).
Наглядная аналогия из жизни
Namespace — это квартиры в большом многоквартирном доме:
- Сам дом — это физический кластер серверов.
- Квартиры 101, 102 и 103 — это пространства имён (
dev,stage,prod). - В каждой квартире на кухне стоит свой холодильник с биркой «Холодильник» (одноименные поды
order-db). Жильцы разных квартир не путают свои холодильники, потому что они находятся в изолированных комнатах.
Базовый манифест и команды
apiVersion: v1
kind: Namespace
metadata:
name: billing-prod
labels:
environment: production
team: billing
# Просмотреть список всех пространств имён в кластере
kubectl get namespaces
# Запустить под в конкретном namespace
kubectl run test-pod --image=nginx -n billing-prod
# Переключить рабочий namespace по умолчанию (чтобы не писать флаг -n)
kubectl config set-context --current --namespace=billing-prod
[!WARNING] Namespace — это НЕ физическая и НЕ сетевая изоляция! По умолчанию в Kubernetes включена плоская сеть: любой под из пространства
devможет свободно отправлять HTTP-запросы в базу данных в пространствеprod. Для реальной сетевой изоляции необходима настройкаNetworkPolicy.
🟡 Middle Level
Разделение ресурсов: Namespace-Scoped vs Cluster-Scoped
[ Kubernetes Кластер ]
│
┌───────────────────────────┴───────────────────────────┐
▼ ▼
[ Namespace-Scoped Ресурсы ] [ Cluster-Scoped Ресурсы ]
Живут строго внутри пространства имён: Глобальны для всего кластера:
- Pod, Deployment, StatefulSet - Node (Физический сервер)
- Service, Ingress, EndpointSlice - PersistentVolume (PV)
- ConfigMap, Secret - StorageClass
- PersistentVolumeClaim (PVC) - ClusterRole, ClusterRoleBinding
- ServiceAccount, Role, RoleBinding - Namespace (Само пространство)
Межсетевое взаимодействие: CoreDNS и FQDN
Поды из разных пространств имён могут легко обращаться друг к другу по сети с использованием полных доменных имён (FQDN):
http://<service-name>.<namespace-name>.svc.cluster.local:<port>
- Внутри одного namespace: достаточно короткого имени:
http://postgres:5432. - Из другого namespace: требуется FQDN:
http://postgres.billing-prod.svc.cluster.local:5432.
Контроль ёмкости: ResourceQuota vs LimitRange
Для защиты кластера от «жадных» арендаторов используются два дополняющих друг друга механизма:
1. ResourceQuota (Суммарный потолок на весь Namespace)
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: dev-team
spec:
hard:
requests.cpu: "20" # Сумма всех requests.cpu не может превысить 20 ядер
requests.memory: 50Gi # Сумма всех requests.memory не более 50 ГБ
limits.cpu: "40"
limits.memory: 100Gi
pods: "30" # Максимум 30 подов в этом namespace
2. LimitRange (Правила для каждого отдельного контейнера)
apiVersion: v1
kind: LimitRange
metadata:
name: container-limits
namespace: dev-team
spec:
limits:
- default: # Лимит по умолчанию, если разработчик забыл указать
cpu: "1"
memory: "1Gi"
defaultRequest: # Реквест по умолчанию
cpu: "200m"
memory: "256Mi"
max: # Запретить контейнеры больше 4 CPU
cpu: "4"
memory: "4Gi"
type: Container
🔴 Senior Level
Иллюзия безопасности: почему Namespace не является границей доверия
На архитектурных собеседованиях Senior-уровня распространен вопрос:
«Безопасно ли размещать в одном кластере в разных Namespace приложения публичного контура и закрытые банковские базы данных?»
Ответ: НЕТ, если не приняты дополнительные меры. Namespace изолирует только видимость через API Server, но:
- Общее ядро Linux (Shared Kernel): поды из
devиprodмогут быть запущены шедулером на одной и той же физической ноде. Уязвимость ядра Linux (например, Dirty Pipe, Dirty COW или баги в подсистеме eBPF) позволяет процессу из ненадежного контейнера получить root-доступ к хосту и захватить соседние контейнерыprod. - Плоская сеть (Flat Network): если в кластере не включен CNI с поддержкой
NetworkPolicy(Cilium или Calico) и не объявлена политика «запретить всё по умолчанию» (Default Deny), контейнеры видят трафик друг друга. - Решение для строгого Multi-Tenancy: физическое разделение на разные кластеры серверов, либо изоляция сред выполнения на базе виртуализации уровня гипервизора (Kata Containers, gVisor).
Зависание Namespace в статусе Terminating (Finalizers Trap)
Классическая аварийная ситуация: администратор выполняет kubectl delete namespace staging, но удаление зависает в статусе Terminating на несколько дней.
Механизм зависания:
- Контроллер
NamespaceLifecycleставит статусTerminatingи запускает каскадное удаление всех вложенных ресурсов. - В секции
spec.finalizersу пространства имён по умолчанию стоит блокировщикkubernetes. - Если хотя бы один вложенный ресурс содержит незавершенный финализатор (например, PVC ожидает ответа от отвалившегося облачного хранилища AWS EBS, или пользовательский CRD от оператора не может завершить graceful-очистку), удаление блокируется навечно.
Алгоритм реанимации:
# 1. Найти ресурс, блокирующий удаление
kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found -n staging
# 2. Очистить финализаторы на проблемном объекте
kubectl patch pvc stuck-pvc -n staging -p '{"metadata":{"finalizers":null}}' --type=merge
# 3. Крайняя хирургическая мера: прямое удаление финализатора через Raw API
kubectl get namespace staging -o json | jq '.spec.finalizers=[]' | kubectl replace --raw "/api/v1/namespaces/staging/finalize" -f -
Pod Security Standards (PSA) на уровне Namespace
В Kubernetes 1.25+ устаревшие PodSecurityPolicy заменены на встроенный Admission Controller Pod Security Admission (PSA), который настраивается простыми лейблами на самом Namespace:
apiVersion: v1
kind: Namespace
metadata:
name: secure-prod
labels:
# Запретить запуск root-контейнеров, hostPath, privileged mode
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: latest
pod-security.kubernetes.io/warn: restricted
API Server автоматически отклонит создание любого пода, нарушающего стандарты безопасности CIS Benchmark!
4 Tricky Questions
1. Что произойдёт при попытке создать Deployment без блока resources.requests, если в данном Namespace активен объект ResourceQuota с ограничением по CPU?
Ответ: API-сервер немедленно отклонит создание пода с ошибкой валидации admission-контроллера:
Error from server (Forbidden): pods "order-app-xxx" is forbidden: failed quota: compute-quota: must specify cpu for: order-app
Если в ResourceQuota задано ограничение на суммарный объём requests.cpu, контроллер квот требует, чтобы абсолютно каждый контейнер в этом namespace имел явно объявленный requests.cpu.
Единственный способ избежать этой ошибки без ручного прописывания ресурсов в каждом манифесте — создать в этом же пространстве имён объект LimitRange с секцией defaultRequest, который будет автоматически подставлять дефолтные значения во все новые контейнеры на этапе мутации манифеста.
2. Почему PersistentVolume (PV) является объектом кластерного уровня (Cluster-Scoped), в то время как PersistentVolumeClaim (PVC) привязан к конкретному Namespace?
Ответ: Это фундаментальное архитектурное разделение зон ответственности:
PersistentVolume(PV) представляет собой физический дисковый ресурс (LUN в СХД, том AWS EBS, локальный NVMe SSD). Им распоряжается администратор инфраструктуры кластера. Этот ресурс глобален и не должен быть привязан к изолированным проектам.PersistentVolumeClaim(PVC) — это пользовательская заявка на ресурс от конкретного приложения разработчика (например: «Мне в проекте billing нужно 50 ГБ SSD»). Она создается разработчиком в рамках своего Namespace.- Kubernetes находит подходящий свободный глобальный PV и монопольно связывает (bind) его с локальным PVC. При удалении Namespace удаляется только заявка (PVC), а судьба физического тома (PV) определяется его глобальной политикой
reclaimPolicy(RetainилиDelete).
3. Каким образом злоумышленник, скомпрометировавший под в Namespace development, может получить доступ к базе данных в Namespace production при стандартной конфигурации Kubernetes?
Ответ: При развертывании кластера «из коробки»:
- Сетевой уровень: сетевая модель Kubernetes CNI по умолчанию является абсолютно плоской и полностью разрешительной (Allow-All). Злоумышленник из шелла пода в
devможет запуститьcurl http://db.production.svc.cluster.local:5432и получить доступ к открытому сокету базы данных. - Уровень DNS: CoreDNS кластера резольвит имена сервисов из любых пространств имён для всех клиентов без ограничений.
Защита: обязательное создание манифеста
NetworkPolicyс типомIngress, разрешающего подключение к БД вproductionтолько от подов, имеющих строго определенныйnamespaceSelector.
4. Можно ли перенести уже работающий Pod или Service из одного Namespace в другой с помощью команды kubectl?
Ответ:
Нет, перенести работающий объект между пространствами имён невозможно.
Поле metadata.namespace является неизменяемым (Immutable) с момента создания объекта.
В базе данных etcd ключ ресурса жестко включает имя namespace: /registry/pods/<namespace>/<pod-name>.
Чтобы переместить сервис, необходимо:
- Выгрузить его манифест:
kubectl get deployment my-app -n old-ns -o yaml > app.yaml. - Изменить в манифесте поле
metadata.namespace: new-ns. - Применить его в новом пространстве:
kubectl apply -f app.yaml. - Удалить старый ресурс в прежнем пространстве имён.
🎯 Шпаргалка для интервью
Главное о Namespace
- Суть: виртуальное логическое разделение кластера; позволяет использовать одинаковые имена ресурсов в разных окружениях.
- Главный миф: Namespace НЕ обеспечивает физическую и сетевую изоляцию по умолчанию.
- Межсетевой DNS:
service-name.namespace-name.svc.cluster.local. - ResourceQuota: суммарный лимит CPU/RAM/Pods на всё пространство имён.
- LimitRange: дефолтные и граничные значения CPU/RAM на один контейнер.
- Зависание в Terminating: вызвано блокировкой финализаторами (
spec.finalizers) на дочерних ресурсах (PVC, CRD). - Безопасность: Pod Security Admission (
restricted) настраивается через лейблы на Namespace.
Типы ресурсов по области видимости
| Область видимости | Примеры ресурсов |
| :— | :— |
| Namespaced | Pod, Service, Deployment, PVC, ConfigMap, Secret, ServiceAccount, Role |
| Cluster-wide | Node, PersistentVolume, StorageClass, ClusterRole, Namespace |
Красные флаги на собеседовании (Чего говорить нельзя)
- ❌ «Namespace изолирует сеть, поэтому поды из dev не могут подключиться к сервисам в prod» — сеть плоская, для изоляции обязательно нужен NetworkPolicy.
- ❌ «Мы храним dev, stage и production в одном namespace default» — антипаттерн, приводящий к хаосу и риску случайного удаления данных.
- ❌ «Чтобы перенести Pod в другой namespace, достаточно поменять его через kubectl edit pod» — поле namespace неизменяемо в etcd.