Namespace — механизм виртуального разделения кластера на изолированные сегменты. Позволяет нескольким командам или проектам использовать один кластер без конфликтов имён ресурсов. Имена объектов уникальны внутри одного namespace, но могут повторяться в разных.
source: kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
Встроенные namespace
Kubernetes создаёт четыре namespace при инициализации кластера:
| Namespace | Назначение |
|---|---|
default | Пространство по умолчанию для объектов без явного namespace |
kube-system | Системные компоненты: API Server, CoreDNS, kube-proxy, kube-scheduler |
kube-public | Данные, читаемые без аутентификации (в том числе cluster-info) |
kube-node-lease | Объекты Lease для heartbeat узлов — механизм определения доступности node |
Не трогай kube-system без понимания последствий — это системное пространство кластера.
Cluster-scoped ресурсы
Не все ресурсы привязаны к namespace. Cluster-scoped ресурсы: Node, PersistentVolume, Namespace, ClusterRole, ClusterRoleBinding, StorageClass, IngressClass.
# Посмотреть, какие ресурсы привязаны к namespace
kubectl api-resources --namespaced=true
# Какие нет (cluster-scoped)
kubectl api-resources --namespaced=false
Создание Namespace
Через YAML (рекомендуется)
apiVersion: v1
kind: Namespace
metadata:
name: dev
labels:
environment: development
team: backend
kubectl apply -f namespace.yaml
Императивно
kubectl create namespace dev
kubectl create namespace staging
kubectl create namespace production
Работа с namespace через kubectl
# Список namespace
kubectl get namespaces
kubectl get ns
# Ресурсы в конкретном namespace
kubectl get pods --namespace=dev
kubectl get pods -n dev
# Все ресурсы в namespace
kubectl get all -n dev
# Ресурсы во всех namespace
kubectl get pods --all-namespaces
kubectl get pods -A
# Удалить namespace (удалит ВСЕ объекты внутри)
kubectl delete namespace dev
Переключение контекста по умолчанию
Чтобы не указывать -n при каждой команде, устанавливают namespace для текущего контекста:
# Посмотреть текущий контекст
kubectl config current-context
# Установить namespace по умолчанию
kubectl config set-context --current --namespace=dev
# Проверить
kubectl config view --minify | grep namespace
# Вернуться в default
kubectl config set-context --current --namespace=default
Инструменты вроде kubens (из пакета kubectx) упрощают переключение до одной команды:
kubens dev # переключиться в namespace dev
kubens - # вернуться к предыдущему
ResourceQuota
ResourceQuota ограничивает суммарное потребление ресурсов в namespace. Хорошая практика — устанавливать квоты для каждой команды или окружения.
source: kubernetes.io/docs/concepts/policy/resource-quotas/
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-quota
namespace: dev
spec:
hard:
# Вычислительные ресурсы
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
# Количество объектов
pods: "20"
services: "10"
persistentvolumeclaims: "5"
secrets: "20"
configmaps: "20"
# Просмотр квот
kubectl get resourcequota -n dev
kubectl describe resourcequota dev-quota -n dev
Важно: при активной ResourceQuota с requests.cpu или requests.memory каждый Pod в namespace обязан указать соответствующие requests. Иначе API Server отклонит создание Pod. Поэтому ResourceQuota всегда используют вместе с LimitRange — который задаёт requests/limits по умолчанию (подробно в главе 13).
DNS и межнеймспейсная коммуникация
Каждый Service получает DNS-запись:
<service-name>.<namespace>.svc.cluster.local
source: kubernetes.io/docs/concepts/services-networking/dns-pod-service/
Внутри одного namespace — достаточно имени Service:
curl http://my-service
curl http://my-service:8080
Между namespace — нужен FQDN или краткая форма с namespace:
# Из namespace "frontend" к Service в namespace "backend"
curl http://api-service.backend.svc.cluster.local
# Или краткая форма (также работает)
curl http://api-service.backend
Пример: многокомандная структура
# Создать namespace для команд
kubectl create namespace team-alpha
kubectl create namespace team-beta
kubectl create namespace shared-services
# Команда разворачивает приложение в своём namespace
kubectl apply -f app.yaml -n team-alpha
# Применить квоты для команды
kubectl apply -f quota-alpha.yaml -n team-alpha
# Проверить потребление
kubectl describe resourcequota -n team-alpha
# Приложение из team-alpha обращается к shared-сервису
# через FQDN: redis.shared-services.svc.cluster.local
apiVersion: v1
kind: Pod
metadata:
name: app
namespace: team-alpha
spec:
containers:
- name: app
image: myapp:1.0
env:
- name: REDIS_HOST
value: "redis.shared-services.svc.cluster.local"
Namespace как граница мультитенантности
Namespace — базовая единица soft multi-tenancy: несколько команд делят один кластер с некоторым уровнем доверия. Официальная документация прямо предупреждает: namespace сам по себе НЕ является жёсткой (hard) границей безопасности. Изоляция достигается только конфигурацией нескольких других механизмов поверх namespace.
source: kubernetes.io/docs/concepts/security/multi-tenancy/
Документация различает изоляцию control plane и data plane:
| Уровень | Механизм | Что изолирует |
|---|---|---|
| Control plane | RBAC (Role/RoleBinding, namespace-scoped) | доступ к API-объектам чужого namespace |
| Control plane | ResourceQuota / LimitRange | потребление ресурсов, защита от noisy neighbor |
| Control plane | Pod Security Admission | что разрешено запускать (privileged/baseline/restricted) |
| Data plane | NetworkPolicy | сетевой трафик между namespace |
| Data plane | Node isolation (taints, nodeAffinity) | физическое разделение workload по нодам |
| Data plane | Sandboxing (gVisor, Kata) | изоляция ядра между контейнерами |
Критично: если команда может читать/менять API-объекты чужого namespace, она может отключить любые другие политики — поэтому RBAC-изоляция первична.
soft-multitenancy: namespace-per-team
Типичный паттерн — namespace на команду/окружение (не на каждый микросервис). Полный набор границ для одного tenant:
apiVersion: v1
kind: Namespace
metadata:
name: team-alpha
labels:
# Pod Security Admission — enforce restricted, warn/audit baseline
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: v1.36
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/audit: restricted
К нему добавляют: ResourceQuota + LimitRange (границы ресурсов), RBAC RoleBinding на команду (доступ только в свой namespace), default-deny NetworkPolicy (сетевая изоляция, глава 17).
Pod Security Admission (PSA)
Встроенный admission controller (stable с Kubernetes 1.25), enforce'ит Pod Security Standards. Настраивается labels на namespace — без CRD и внешних движков:
pod-security.kubernetes.io/<MODE>: <LEVEL>
pod-security.kubernetes.io/<MODE>-version: <VERSION> # опционально, напр. v1.36 или latest
Три режима (<MODE>) и три уровня (<LEVEL>):
| MODE | Что делает при нарушении |
|---|---|
enforce | Pod отклоняется (применяется только к самим Pod, не к Deployment/Job) |
audit | Pod допускается, нарушение пишется в audit log |
warn | Pod допускается, клиент получает warning (работает и для workload-ресурсов) |
| LEVEL | Суть |
|---|---|
privileged | без ограничений; для системных/инфраструктурных workload |
baseline | запрет известных privilege escalation: hostNetwork/hostPID/hostIPC, privileged, hostPath, host ports |
restricted | baseline + runAsNonRoot: true, allowPrivilegeEscalation: false, capabilities.drop: [ALL] (+ только NET_BIND_SERVICE), seccompProfile.type: RuntimeDefault/Localhost, ограниченный список volume-типов |
source: kubernetes.io/docs/concepts/security/pod-security-admission/ source: kubernetes.io/docs/concepts/security/pod-security-standards/
Когда soft-tenancy недостаточно
Для враждебных tenant (SaaS с недоверенными клиентами) namespace недостаточно — атака идёт через data plane (ядро, узлы). Варианты сильнее:
- Virtual control plane per tenant — отдельный виртуальный API-сервер на tenant (vCluster).
- Кластер на tenant — вплоть до dedicated hardware, если VM не считается достаточной границей.
Типичные ошибки
Удаление namespace с живыми ресурсами. kubectl delete namespace dev удалит ВСЕ объекты в namespace — Pod, Service, Deployment, ConfigMap, Secret, PVC. Операция необратима (namespace переходит в Terminating).
Namespace застрял в Terminating. Причина — финализаторы (finalizers) на объектах внутри, которые не могут завершить очистку. Диагностика: kubectl get namespace dev -o yaml — смотреть поле finalizers. Решение: удалить финализаторы вручную или дождаться завершения очистки контроллером.
Не указывать namespace в CI/CD. Скрипты без -n <namespace> работают с default. При смене контекста kubectl или в другом окружении это приводит к деплою не туда. Всегда явно указывай namespace в автоматизации.
Предполагать изоляцию сети внутри кластера. По умолчанию Pod из разных namespace могут свободно общаться. Изоляция трафика — задача NetworkPolicy (глава 17).
Слишком много namespace. Один namespace на микросервис — антипаттерн. Namespace для изоляции команд/окружений, не для каждого приложения.
Альтернативы
Несколько кластеров — жёсткая изоляция, но дороже в эксплуатации. Актуально для compliance, мультирегиональных деплоев или разделения production/non-production.
Virtual Cluster (vCluster) — полноценный Kubernetes API внутри namespace родительского кластера. Даёт изоляцию на уровне кластера без накладных расходов на отдельные control plane.
Hierarchical Namespaces (HNC) — расширение для создания иерархии namespace с наследованием политик. Всё ещё требует отдельной установки, не встроено в core Kubernetes.