Доступ к Kubernetes API из Pod — полное руководство

Быстрые ссылки
- Почему приложения обращаются к Kubernetes API из Pod
- Использование клиентских библиотек
- Ручные вызовы API из Pod (curl)
- Работа с RBAC: роли и биндинги
- Выбор другого сервисного аккаунта
- Отключение автоматической монтировки токена
- Безопасность и рекомендации
- Контрольный список для деплоя
- Плейбук для выдачи прав
- Краткий глоссарий и факты
Введение
Kubernetes API — это основной интерфейс управления кластером. С его помощью вы можете читать состояние ресурсов, изменять объекты, и получать метрики/статус контрольной плоскости. Приложения, работающие внутри кластера, тоже могут обращаться к API: Pod получает сервисный аккаунт и набор файлов/переменных окружения, которые позволяют аутентифицироваться и безопасно соединяться с сервером API.
Ниже описаны практические подходы, примеры и рекомендации по безопасности, а также набор шаблонов и чек-листов для типичных сценариев.
Почему приложения обращаются к Kubernetes API из Pod
Причины обращения к API изнутри кластера:
- Динамическая настройка: приложение может обнаруживать соседние Pod, ConfigMap или Secret и подстраивать поведение.
- Операционные агенты: службы мониторинга, автоскейлеры, или кастомные контроллеры работают как in-cluster компоненты.
- Минимизация поверхности атаки: у внутренних компонентов меньше необходимости открывать внешние секреты или распространять ключи вне кластера.
- Расширение функциональности: организации создают внутренние инструменты, которые выполняют операции только изнутри кластера.
Когда это не подходит:
- Если у вас централизованная система управления за пределами кластера, лучше использовать внешний контроллер.
- Чувствительным Pod может быть безопаснее вообще отключить авто-монтировку токена.
Использование клиентских библиотек (рекомендуемо)
Клиентские библиотеки управляют деталями подключения, чтением токена и CA, обработкой ротации токенов и сериализацией API-объектов. Доступные официальные реализации есть для Go, Python, Java, .NET, JavaScript и других. Если есть официальная библиотека для вашего языка — используйте её.
Краткое определение: In-cluster config — это автоматическая конфигурация клиента, которая читает сервисный аккаунт и CA из стандартных путей в Pod, чтобы настроить соединение с API сервером.
Пример на Python (строго как пример, убедитесь, что установлен пакет kubernetes):
from kubernetes import client, config
# Загружает конфигурацию внутри Pod, читая токен и ca.crt
config.load_incluster_config()
api = client.CoreV1Api()
# Получение списка Pod во всех неймспейсах
pods = api.list_pod_for_all_namespaces()
for p in pods.items:
print(p.metadata.namespace, p.metadata.name)Пример на Go (с использованием официального клиента):
import (
"fmt"
v1 "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/rest"
"k8s.io/client-go/kubernetes"
)
config, err := rest.InClusterConfig()
if err != nil {
panic(err.Error())
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
panic(err.Error())
}
pods, err := clientset.CoreV1().Pods("").List(ctx, metav1.ListOptions{})
fmt.Println(len(pods.Items))Почему библиотека лучше “ручного” способа:
- Обработка сертификатов и токенов.
- Поддержка сериализации/десериализации Kubernetes-объектов.
- Более понятные ошибки и совместимость с версией API.
Ручные вызовы Kubernetes API из Pod
Иногда библиотека недоступна или вы пишете лёгкий скрипт — в таких случаях можно выполнить HTTP-запросы вручную.
Ключевые факты (фиксированные пути и переменные):
- API hostname (internal DNS): kubernetes.default.svc
- IP переменная: KUBERNETES_SERVICE_HOST
- CA-файл: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
- Токен сервисного аккаунта: /var/run/secrets/kubernetes.io/serviceaccount/token
- Текущий namespace: /var/run/secrets/kubernetes.io/serviceaccount/namespace
Пример проверки доступности API с curl (внутри Pod):
curl \
--cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
-H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
https://kubernetes.default.svc/apiОжидаемый формат ответа (сокращённый):
{
"kind": "APIVersions",
"versions": ["v1"],
"serverAddressByClientCIDRs": [{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "192.168.49.2:8443"
}]
}Подстановка namespace:
curl \
--cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
-H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
https://kubernetes.default.svc/api/v1/namespaces/$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)/podsСоветы при ручном использовании API:
- Всегда указывайте CA-файл или отключите проверку TLS только в тестах.
- Не логируйте токен в лог-файлы.
- Ограничьте круг запрашиваемых ресурсов (не используйте wildcard, если можно явно указать namespace).
Работа с RBAC: роли и биндинги
Даже если Pod успешно подключается к API, доступ к ресурсам контролируется RBAC. По умолчанию созданный сервисный аккаунт не имеет прав на чтение/запись многих объектов.
Пример Role (только чтение Pod в namespace default):
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: demo-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]Применение:
kubectl apply -f role.yamlRoleBinding для связывания роли с сервисным аккаунтом:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: default
name: demo-role-binding
subjects:
- kind: ServiceAccount
name: default
namespace: default
roleRef:
kind: Role
name: demo-role
apiGroup: rbac.authorization.k8s.iokubectl apply -f role-binding.yamlПроверка прав — пробный запрос к namespaced endpoint:
curl \
--cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
-H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
https://kubernetes.default.svc/api/v1/namespaces/default/podsКогда использовать ClusterRole/ClusterRoleBinding:
- Когда нужно дать права на ресурсы в нескольких namespace или на ресурсы уровня кластера (Node, PersistentVolumes и т.д.).
- ClusterRole даёт глобальный набор прав, поэтому применяйте минимально необходимые разрешения.
Критерии приёмки для RBAC-конфигурации:
- Под имеет только те права, которые необходимы для выполнения задач.
- Проверены негативные сценарии (запросы вне списка разрешённых возвращают 403).
- Нет прямого привязывания токена к внешним системам.
Выбор другого сервисного аккаунта
По умолчанию Pod получает сервисный аккаунт с именем default в том namespace, где создаётся Pod. Чтобы использовать другой аккаунт, укажите spec.serviceAccountName в манифесте Pod (или Deployment/StatefulSet):
apiVersion: v1
kind: Pod
metadata:
name: demo
spec:
serviceAccountName: demo-saСоздание сервисного аккаунта:
kubectl create serviceaccount demo-sa -n defaultУчтите, что сервисный аккаунт должен находиться в том же namespace, что и Pod. Затем создайте RBAC роли и биндинги для demo-sa.
Отключение автоматической монтировки токена
Автоматическая монтировка сервисного токена увеличивает риск — при компрометации контейнера злоумышленник получает доступ к API. Чтобы отключить монтировку токена для конкретного Pod, укажите:
apiVersion: v1
kind: Pod
metadata:
name: demo
spec:
automountServiceAccountToken: falseЭто также поле поддерживается на уровне объекта ServiceAccount, что запрещает автоматическую монтировку токена в любых Pod, использующих этот аккаунт.
Последствия отключения:
- Pod не сможет аутентифицироваться через встроенный токен, пока вы не предоставите альтернативную схему (например, внешние креденшелы или Vault).
- Подходит для защищённых, минимально привилегированных контейнеров.
Безопасность и жёсткая настройка
Практические рекомендации по безопасности:
- Минимизируйте RBAC-права (principle of least privilege).
- Не используйте ClusterRoleBinding с широкими правами для приложений из пользовательских namespace.
- Отключайте automountServiceAccountToken для Pod, которым не нужен API.
- Ограничьте сетевые политики: разрешайте доступ к API серверам только тем Pod, которым он действительно нужен.
- Разделяйте критичные компоненты в отдельных namespace и применяйте NetworkPolicy.
- Рассмотрите использование short-lived токенов и внешних секретных хранилищ (например, HashiCorp Vault) для критичных сценариев.
Риск-матрица (качественная оценка):
| Риск | Вероятность | Уровень воздействия | Смягчение |
|---|---|---|---|
| Компрометация Pod с широкими RBAC правами | Средняя | Высокое | Минимизировать права, rotate токены, мониторинг |
| Логирование токенов в лог-файлы | Низкая | Среднее | Не логировать секреты, использовать redact |
| Чрезмерное использование ClusterRoleBinding | Низкая | Высокое | Использовать namespace-scoped роли |
Важно: не храните токены в виде переменных окружения или в System logs.
Контрольный список перед деплоем приложения, использующего API
- Выбрана правильная модель аутентификации (встроенный SA или внешняя система).
- Создан ServiceAccount и относятся только необходимые роли.
- Под указан automountServiceAccountToken: false там, где это нужно.
- Проверен доступ с помощью тестового запроса curl или unit-тестов клиента.
- Настроены NetworkPolicy и ограничения на уровне namespace.
- Включён аудит доступа и мониторинг (Audit logs, SIEM).
Плейбук: выдача прав сервисному аккаунту (SOP)
Цель: дать Pod сервисному аккаунту demo-sa права на просмотр Pod в namespace staging.
Шаги:
- Создать ServiceAccount в target namespace:
kubectl create serviceaccount demo-sa -n staging- Создать Role с правом list/get pod и сохранить в role-staging.yaml:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: staging
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]- Применить роль:
kubectl apply -f role-staging.yaml- Создать RoleBinding:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: staging
name: pod-reader-binding
subjects:
- kind: ServiceAccount
name: demo-sa
namespace: staging
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io- Применить binding и проверить доступ из Pod, использующего demo-sa.
Критерии успешности:
- Pod с demo-sa возвращает список Pod в staging.
- Попытки доступа к другим ресурсам возвращают 403.
Инцидентный рукбук: если Pod утёк токен или подозрение на компрометацию
- Немедленно отозвать привилегии: удалить/изменить RoleBinding, привязанный к скомпрометированному Account.
- Отключить automountServiceAccountToken для новых Pod, использующих этот Account.
- Принять корректирующие меры: пересоздать сервисный аккаунт, обновить роли, переконфигурировать приложения.
- Проверить логи и аудит Kubernetes API на предмет подозрительных вызовов.
- Произвести пост-инцидентный анализ и скорректировать RBAC/NetworkPolicy.
Альтернативные подходы
- External controllers: запускать контроллеры вне кластера и использовать kubeconfig с ограниченными правами.
- Sidecar pattern: выделить агент в sidecar-контейнере, который управляет вызовами API и имитирует минимальный интерфейс для основного контейнера.
- Webhooks и Admission Controllers: если задача — валидация/мутирование — используйте admission вебхуки.
Совместимость и миграция
- Клиентские библиотеки обычно поддерживают несколько версий API, но проверяйте совместимость при апгрейде кластера.
- Если вы используете нестандартные CRD, убедитесь, что версия библиотеки поддерживает соответствующие Group/Version.
- При переходе на RBAC из ABAC/NodeAuthorization — протестируйте политики в staging.
Факты и полезные пути
- Встроенные файлы для in-cluster аутентификации:
- /var/run/secrets/kubernetes.io/serviceaccount/token — JWT токен сервисного аккаунта
- /var/run/secrets/kubernetes.io/serviceaccount/ca.crt — CA для проверки TLS
- /var/run/secrets/kubernetes.io/serviceaccount/namespace — имя namespace
- Внутренний DNS для API: kubernetes.default.svc
- Переменные окружения, которые могут быть доступны: KUBERNETES_SERVICE_HOST, KUBERNETES_SERVICE_PORT
Краткий глоссарий (1 строка)
- Pod: минимальная единица развертывания в Kubernetes, содержащая один или несколько контейнеров.
- ServiceAccount: объект Kubernetes, представляющий учетные данные для Pod.
- RBAC: модель контроля доступа через роли и биндинги.
- ClusterRole: роль, действующая на уровне всего кластера.
- Role: роль, ограниченная namespace.
Примеры тестов/кейс-критериев
- Тест 1: Pod с demo-sa должен вернуть код 200 при запросе /api/v1/namespaces/
/pods. - Тест 2: Pod с demo-sa не должен иметь права на создание deployment (ожидается 403).
- Тест 3: Отключённый automountServiceAccountToken не должен иметь файл token в /var/run/secrets.
Резюме
Доступ к Kubernetes API из Pod — мощный инструмент для расширения функциональности приложений и автоматизации. Рекомендуется использовать официальные клиентские библиотеки, минимум привилегий через RBAC и дополнительные меры безопасности (NetworkPolicy, отключение автoмонтировки токенов для чувствительных Pod). Применяйте плейбук и контрольный список перед выдачей прав, а также имейте план действий на случай компрометации.
Important: всегда тестируйте политики в изолированном окружении и документируйте выданные права.
Похожие материалы
Установка и удаление Google Chrome — полное руководство
Экранная блокировка Nintendo Switch: включение и советы
Сумма в Excel: быстрые способы и подсказки
Как распечатать лист Excel на одной странице
Как сохранить письмо из Mail в Notes в PDF