← Kubernetes: основы
7 мин · просто · Урок 9 из 11

Namespace: изоляция ресурсов

Как кластер делят на области, какие ресурсы в них не попадают и по каким правилам kubectl выбирает namespace.

Что такое namespace

Namespace - это область внутри кластера, которая изолирует ресурсы друг от друга. Внутри одного namespace имена ресурсов уникальны.

Один кластер делят разные команды, среды и проекты. Без namespace их имена пересеклись бы быстро. У команды A свой Service api, у команды B тоже api: без границы это конфликт. Service - объект, который даёт постоянный адрес для группы Pod. Namespace и есть та граница, внутри которой api команды A не мешает api команды B.

К namespace привязывают и другие настройки. RBAC задаёт, кто что может делать внутри него. Можно ограничить суммарный CPU и память команды (ResourceQuota) и разрешённый трафик между Pod (NetworkPolicy), это разбираем в отдельных уроках.

В проде namespace это единица администрирования: своя команда, свои права, свои лимиты.

Что лежит в namespace, а что нет

Не все ресурсы живут внутри namespace.

Внутри namespace (namespaced): Pod, Deployment, Service, ConfigMap, Secret, Role, Job.

Вне namespace, на уровне всего кластера (cluster-scoped): Node, Namespace, PersistentVolume, ClusterRole, StorageClass.

Внутри namespaceНа уровне кластера
Pod, Deployment, ServiceNode, Namespace
ConfigMap, SecretPersistentVolume, StorageClass
Role, JobClusterRole

Проверить принадлежность можно так:

kubectl api-resources --namespaced=true
kubectl api-resources --namespaced=false

Node - это машина кластера, она принадлежит всему кластеру, поэтому вне namespace. Pod живёт на узле, но привязан к namespace.

Стандартные namespaces

Свежий кластер уже содержит несколько namespace.

Как создать namespace

Императивно одной командой:

kubectl create ns team-a

ns - это сокращение от namespace.

Декларативно через манифест:

apiVersion: v1
kind: Namespace
metadata:
  name: team-a

Можно указать namespace прямо в манифесте ресурса:

apiVersion: v1
kind: Pod
metadata:
  name: pinger
  namespace: team-a
spec:
  containers:
    - name: pinger
      image: busybox:1.36

Если namespace ещё не существует, apply упадёт с namespaces "team-a" not found. Поэтому сначала создают namespace, потом кладут в него ресурсы.

Флаг -n

По умолчанию kubectl работает в namespace из текущего контекста (обычно default). Чтобы обратиться к другому namespace, добавляют флаг -n:

kubectl get pod -n team-a
kubectl apply -f pod.yaml -n team-a
kubectl logs pinger -n team-a

Флаг -A (или --all-namespaces) показывает ресурсы сразу из всех namespace:

kubectl get pod -A

Сменить namespace по умолчанию для текущего контекста:

kubectl config set-context --current --namespace=team-a

После этого kubectl get pod без флагов смотрит в team-a.

Обращение между namespace

namespace team-a namespace team-b Pod клиент в team-b api Service api команда B api.team-a.svc.cluster.local Service api команда A
Имя api занято в обоих namespace, снаружи спасает только полный адрес.

Каждый Service получает DNS-имя такого вида:

<service>.<namespace>.svc.cluster.local

Из Pod своего namespace к Service можно обратиться коротко: api. Из чужого namespace нужен полный адрес: api.team-a.svc.cluster.local.

Например, Pod в team-b стучится в Service api команды A:

curl http://api.team-a.svc.cluster.local:8080/health

Какой namespace выберет kubectl

Когда namespace не указан явно, kubectl выбирает его так.

  1. Если в манифесте есть metadata.namespace, берёт его.
  2. Иначе, если задан флаг -n, берёт его.
  3. Иначе берёт namespace из текущего контекста.
  4. Иначе default.

Отдельный случай - конфликт. Если в манифесте вписан namespace: team-a, а команда вызвана как kubectl apply -f pod.yaml -n team-b, kubectl не выберет молча один из них, а вернёт ошибку и ничего не создаст. Правило простое: задавай namespace либо в манифесте, либо флагом, но не в обоих местах сразу.

Удаление namespace

kubectl delete ns team-a удаляет всё, что лежит внутри. Это удобно для очистки учебного кластера и опасно для прода. Удаление асинхронное: namespace переходит в фазу Terminating и ждёт, пока освободятся все ресурсы. Если завис, обычно дело в финализаторе на каком-то ресурсе. Финализатор - метка на объекте, которая блокирует удаление до завершения очистки.

Домашка

Теорию закрепляет задание на своём кластере: 2 шага с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.

./run.sh start k8s-namespace     # развернуть стартовое состояние
./run.sh verify k8s-namespace    # проверить текущий шаг

Коротко

Дрилл · вопросы как на собесе

Проверь себя без подсказок

Сформулируй ответ вслух или письменно, потом раскрой и честно отметь: знал или нет.

01

Что такое namespace?

K8S-003

Прошли материал до конца? Отметьте урок пройденным.