Источник Предположим, мы создали кластер Kubernetes. И кто-то из команды разработчиков хочет развернуть и протестировать на нем новое приложение. Как нам предоставить ему доступ в кластер?  Команда Kubernetes aaS Mail.ru Cloud Solutions перевела простое руководство по предоставлению доступа к новому кластеру Kubernetes, включая настройку аутентификации и привязку ролей. Автор показывает процесс, используя клиентский сертификат x509. Для управления кластером Kubernetes и запущенными в нем приложениями обычно используют утилиту kubectl или веб-интерфейс. Под капотом эти инструменты вызывают API Server: HTTP Rest API, открывающий конечные точки управления кластером. Этот HTTP API хорошо документирован — посмотрите сами.  После отправки запроса на сервер API он проходит сначала аутентификацию, а затем авторизацию. Аутентификация позволяет убедиться, что запрашивающий известен системе, авторизация — что отправителю запроса разрешено выполнить конкретное действие. Аутентификацию выполняют с помощью плагинов, есть плагины с разными механизмами: сертификаты клиентов — о них в этой статье; Bearer tokens (персональные токены); аутентифицирующий прокси; базовая аутентификация HTTP. В зависимости от механизма аутентификации плагин ищет информацию о пользователе в определенных местах. Например, для аутентификации по сертификату клиента идентификацию пользователя (идентификатор, имя, адрес электронной почты и так далее) указывают в поле Common Name (CN) сертификата. Информацию о группе, если она есть, добавляют в поле Organisation (O). Внутри кластера Kubernetes нет ни ресурсов пользователей, ни ресурсов групп. Их обрабатывают вне кластера и предоставляют с каждым запросом, который направляют на сервер API — я проиллюстрирую это ниже. Кластер используют несколько команд или клиентов (подход с несколькими пользователями), так что нужно изолировать рабочую нагрузку для каждого клиента. Мы создадим пространство имен для команды разработчиков, в которую входит разработчик, которому надо дать доступ (пусть его зовут Дейв). Это пространство имен мы назовем development. Дейву предстоит развернуть стандартные ресурсы Kubernetes. Затем он получит право создавать, просматривать, обновлять, получать список и удалять ресурсы Deployment и Service. Дополнительные права можно предоставить при необходимости, но они ограничены пространством имен development. Скорее всего, членам команды Дейва потребуется такой же уровень доступа. Мы заведем группу dev и предоставим права на уровне группы. Дейву потребуется kubectl, а также openssl — он сгенерирует закрытый ключ и запрос на вход с сертификатом. Сначала Дейв генерирует закрытый ключ RSA и CSR. Закрытый ключ можно создать с помощью команды: С CSR немного сложнее, поскольку Дейву нужно убедиться, что он: использует свое имя в поле Common Name (CN) — оно требуется для идентификации на сервере API; использует имя группы в поле Organisation (O) — это имя нужно для идентификации группы на сервере API. Ниже файл конфигурации, который Дейв использует для создания CSR: Примечание: запись clientAuth в поле extendedKeyUsage нужна, поскольку сертификат будут использовать для идентификации клиента. С помощью указанного файла конфигурации, сохраненного в csr.cnf, CSR можно создать одной командой: Создав файл .csr, Дейв отправляет его администраторам, чтобы они подписали его с помощью центра сертификации кластера. После подписания файла .csr выпускается сертификат. Он будет использоваться для аутентификации запросов, который Дейв отправит на сервер API.  Начнем с создания ресурса Kubernetes Certificate Signing Request. Примечание мы могли создать управляемый кластер (например, в DigitalOcean, Google GKE, Microsoft Azure, Mail.ru Cloud Solutions или другой платформе) или собственный (допустим, kubeadm или kubespray). Процесс подписи везде устроен одинаково. Мы используем следующую спецификацию и сохраняем ее в csr.yaml: Значение ключа request — содержимое переменной окружения BASE64_CSR. Первый шаг — получить кодированный в base64 файл .csr, созданный Дейвом. Затем использовать envsubst, чтобы заменить значения этой переменной перед созданием ресурса. Проверяем статус созданного CSR — мы видим, что он находится в состоянии ожидания: Подтверждаем CSR с помощью команды: Еще раз проверяем статус CSR — теперь он одобрен: Сертификат создан, теперь извлечем его из ресурса CSR, сохраним в файле с именем dave.crt и проверим, что внутри: Следующая команда openssl показывает: сертификат подписан центром сертификации кластера DigitalOcean (часть Issuer). Subject содержит dave в полях CN (CommonName) и O (Organisation), как указал Дейв при создании файла .csr: Примечание в примере используем управляемый кластер Kubernetes, созданный в DigitalOcean — мы видим это в Issuer кластера. На другой платформе будет похоже. Начинаем с создания пространства имен development — благодаря этому ресурсы, которые развернут Дейв и его команда, будут изолированы от остальной рабочей нагрузки кластера.  Его можно создать с помощью простой команды: или с помощью файла dev-ns.yaml: Применяем dev-ns.yaml с помощью команды: Примечание рекомендую создать ресурс ResourceQuota и связать его с пространством имен. Это позволит ограничить объем CPU и ОЗУ, которые можно использовать в пространстве имен. С помощью сертификата Дейв может пройти аутентификацию на сервере API. Но пока у него нет прав, так что он не может делать многие вещи. Давайте дадим ему права создавать, получать список, обновлять, просматривать и удалять ресурсы Deployment и Service в пространстве имен dev. Коротко: роль (то же самое справедливо и для ClusterRole) содержит список правил. Каждое правило определяет действия, которые могут быть выполнены (например: list, get, watch) со списком ресурсов (например: Pod, Service, Secret) в apiGroups (например: core, apps/v1). Роль определяет права для конкретного пространства имен, область ClusterRole — весь кластер. Создадим ресурс Role со следующей спецификацией: Ресурсы подов и служб принадлежат основной группе API (значение ключа apiGroups — пустая строка), а ресурсы развертывания — группе API приложений. Для этих двух групп apiGroup мы определили список ресурсов и действия, которые нужно авторизовать на этих ресурсах. Строки сохраняем в файл role.yaml, для создания роли используем команду: Назначение RoleBinding — связать роль, то есть список разрешенных действий, с пользователем или группой. Чтобы у Дейва были права, указанные в созданной выше роли, мы привязываем его к этой роли. Для этого используем ресурс RoleBinding: Эта RoleBinding связывает: субъект — пользователь Дейв; роль: с именем dev, которая позволяет создавать, просматривать, обновлять, получать список, удалять ресурсы Deployment и Service. Примечание: поскольку Дейв входит в группу разработчиков, то можно использовать следующую привязку RoleBinding для связи роли с группой, а не отдельным пользователем. Помните: информация о группе указывается в поле Organisation (O) сертификата, его отправляют с каждым запросом. Мы сохранили спецификацию ресурса RoleBinding в файле role-binding.yaml и создаем его с помощью команды: Все настроено. Теперь отправляем Дейву информацию, которая необходима для настройки его локального клиента kubectl для связи с нашим кластером. Сначала создаем файл kubeconfig.tpl со следующим содержанием, его мы будем использовать в качестве шаблона: Чтобы создать kubeconfig из этого шаблона, нужно сначала установить переменные среды: Подставляем их, используя удобную утилиту envsubst: Отправляем Дейву файл kubeconfig. Чтобы взаимодействовать с кластером, ему достаточно добавить в файл свой закрытый ключ. Чтобы использовать kubeconfig, Дейв устанавливает переменную среды KUBECONFIG, указав путь к файлу. Примечание: есть разные способы использовать конфигурации Kubernetes. Можно установить переменную среду KUBECONFIG, добавить новую запись в файл $ HOME/.kube/config по умолчанию или использовать флаг --kubeconfig для каждой команды kubectl. Чтобы добавить закрытый ключ dave.key, Дейв использует команду: Команда создает ключ client-key-data в записи пользователя файла kubeconfig и устанавливает dave.key в кодировку base64 в качестве значения. Если все успешно, Дейв может проверить версию сервера (и клиента) с помощью команды: Теперь проверим, позволяет ли связанная с Дейвом текущая роль отображать узлы кластера: Конечно, нет! Но Дейв может что-то развертывать в кластере — по крайней мере, в пространстве имен development. Давайте проверим это с помощью YAML-файла, который определяет Deployment на основе образа nginx и Service для его предоставления: Из результата следующей команды видно, что Дейв может создавать эти ресурсы в кластере: Дейв ограничен пространством имен development. Если он попытается получить список всех подов в пространстве имен по умолчанию, то получит сообщение об ошибке: Еще он не может создавать другие ресурсы, кроме тех, к которым ему предоставили доступ. Например, мы можем попробовать следующую спецификацию ресурса типа Secret: Давайте посмотрим, как Дейв попытается его создать: Мы показали, как использовать сертификат клиента для авторизации пользователей в кластере Kubernetes. Можно настраивать аутентификацию другим способом, но этот довольно прост. После настройки аутентификации мы использовали роль, чтобы определить некоторые права, ограниченные пространством имен, и привязать их к пользователю с помощью RoleBinding. Если нам нужно будет предоставить права для всего кластера, мы сможем использовать ресурсы ClusterRole и ClusterRoleBinding. Что еще почитать: 90+ инструментов, без которых не обойтись при использовании Kubernetes. Основы безопасности внутри Kubernetes: 10 простых советов. Как устроен Kubernetes as a Service на платформе Mail.ru Cloud Solutions. Эмпатичный маркетолог