Pinniped как способ логина в Kubernetes через Active Directory

от автора

Многие пользователи Яндекс облака применяют сервис Managed Service for Kubernetes. При этом учетные записи сотрудников организаций хранятся на контроллерах домена Windows. Удобно и правильно логиниться в Kubernetes учетными записями из Windows-домена, оптимизируя ресурсы DevOps и сисадминов. Но без специального инструмента сделать это нельзя. 

Меня зовут Дмитрий Глушков, я системный инженер эксплуатации в Lamoda Tech. Мои поиски удобного решения задачи привели к программе Pinniped. Она поможет использовать учетные записи Windows AD для предоставления и контроля доступа сотрудников в Kubernetes. Разберемся, как ее установить и использовать.

Что такое Pinniped 

Pinniped (Пиннипед) – это программа, которая позволяет логиниться в Kubernetes-кластеры, в которых у вас нет доступа к их мастер-нодам (пользуясь программой kubectl и специальным файлом-шаблоном кубконфига). Вы можете использовать учетки от разных провайдеров учетных записей (identity providers), например, MS Windows Active Directory. Это подходящее решение, например, в Яндекс облаке для их управляемых куб-кластеров.

Pinniped состоит из двух частей – супервизора и консьержа. Супервизор нужен, чтобы можно было залогиниться с учеткой из Active Directory, а консьерж принимает все запросы в куб-апи и проверяет, что они корректно авторизованы супервизором, и если да, то проксирует их в куб-апи. Обе части – это просто поды в кубе.

Источник: pinniped.dev

Источник: pinniped.dev

Чтобы получить работающую систему, необходимо:

  • подготовить необходимые ресурсы;

  • установить и настроить Pinniped;

  • настроить права в куб-кластере;

  • создать файл шаблона кубконфига;

  • научить пользователей работать с Pinniped. 

Звучить объемно, но выполнимо. Поехали!

1. Подготовка к установке

Предполагается, что у вас есть следующие ресурсы, и вы можете ими управлять:

  • аккаунт в Яндекс облаке, в котором есть работающий managed куберкластер;

  • контроллер домена Windows, к которому есть сетевой доступ из Яндекс облака;

  • tls-certificate, который вы можете создать;

  • DNS-запись, которую вы можете создать, и которая будет работать у вас в сети и показывать на IP-адрес в Яндекс облаке.

2. Установка

Просто создаем в нашем куб-кластере объекты из ямл-файлов от создателей Pinniped:

kubectl apply -f https://get.pinniped.dev/v0.32.0/install-pinniped-supervisor.yaml

kubectl apply -f https://get.pinniped.dev/v0.32.0/install-pinniped-concierge-crds.yaml

kubectl apply -f https://get.pinniped.dev/v0.32.0/install-pinniped-concierge-resources.yaml

2.1 Load balancer для консьержа

После выполнения этих трех команд в куб-кластере в неймспейсе pinniped-concierge появится сервис с именем pinniped-concierge-impersonation-proxy-load-balancer. Мы будем использовать этот сервис как лоад-балансер, который будет принимать запросы для Pinniped-консьержа. Чтобы этот сервис стал работать как лоад-балансер в Яндекс облаке, надо в его конфиге добавить две аннотации:

yandex.cloud/load-balancer-type: internal

yandex.cloud/subnet-id: id-подсети

Тут internal – это тип лоад-балансера NLB в ЯО, такой как в документации Яндекс облака, а id-подсети – это подсетка в Яндекс облаке, в которой будет создан лоад-балансер, как только мы добавим эти две аннотации и сохраним конфиг. Покажу только важную для нас сейчас часть конфигурации, неважные строки пропущены. Вот что должно получиться в итоге:

apiVersion: v1 kind: Service metadata:  annotations:    . . .    yandex.cloud/load-balancer-type: internal    yandex.cloud/subnet-id: id-подсети  labels:    app: pinniped-concierge  name: pinniped-concierge-impersonation-proxy-load-balancer  namespace: pinniped-concierge  . . . spec:  . . .

Как только облако создаст лоад-балансер, у него появится IP-адрес, и можно проверить, что он работает. Вот ожидаемый ответ:

% curl -k https://ip-addr-of-load-balancer-of-concierge {   "kind": "Status",   "apiVersion": "v1",   "metadata": {},   "status": "Failure",   "message": "forbidden: User \"system:anonymous\" cannot get path \"/\": decision made by impersonation-proxy.concierge.pinniped.dev",   "reason": "Forbidden",   "details": {},   "code": 403 }

2.2 Load balancer для супервизора

Делаем сервис+NLB  для супервизора в той же подсетке, что и у консьержа:

apiVersion: v1 kind: Service metadata:   annotations:     yandex.cloud/load-balancer-type: internal     yandex.cloud/subnet-id: id-подсети-из-пункта-2.1   name: pinniped-supervisor-loadbalancer   namespace: pinniped-supervisor spec:   ports:   - targetPort: 8443     port: 443     protocol: TCP   selector:     app: pinniped-supervisor   type: LoadBalancer

Как только облако создаст лоад-балансер для супервизора, у него появится IP-адрес. Надо сделать DNS-запись, указывающую на этот IP-адрес:

pinniped-supervisor.ваш_домен.да  → ip-адрес лоад-балансера супервизора.

2.3 Куб-секрет с TLS-сертификатом супервизора

Супервизор обязательно требует использовать TLS-защищенное подключение к нему, поэтому создадим куб-секрет, и положим туда сертификат и приватный ключ. TL-сертификат надо создать, он должен удостоверять url pinniped-supervisor.ваш_домен.да.

apiVersion: v1 data:   tls.crt: LS0tLS1CRUdJTiBDRVJUS...   tls.key: LS0tLS1CRUdJTiBQUkl... kind: Secret metadata:   name: supervisor-lb-tls-cert   namespace: pinniped-supervisor type: kubernetes.io/tls

2.4 FederationDomain

Создаем объект, который нужен для указания url, на котором будет работать Cупервизор, и тут же указываем секрет с TLS-сертификатом для этого url.

apiVersion: config.supervisor.pinniped.dev/v1alpha1 kind: FederationDomain metadata:   name: my-fd   namespace: pinniped-supervisor spec:   issuer: https://pinniped-supervisor.ваш_домен.да   tls:     secretName: supervisor-lb-tls-cert

После этого шага выполнение запроса типа:

% curl https://pinniped-supervisor.ваш_домен.да должно показывать, что TLS-сертификат правильный.

2.5 Секрет для подключения в домену Active Directory

Создаем секрет для подключения в домену AD. Пароль обязательно должен быть в кавычках. В домене Windows надо создать учетку, которая может читать учетные записи и группы, и использовать её.

apiVersion: v1 kind: Secret metadata:   name: active-directory-bind-credentials   namespace: pinniped-supervisor type: kubernetes.io/basic-auth stringData:   # The dn (distinguished name) of your Active Directory bind account.   username: CN=s-pinniped,OU=Service Accounts,DC=office,DC=ru   # The password of your Active Directory bind account.   password: "ТУТПАРОЛЬОТУЧЁТКИ..."

2.6 ActiveDirectoryIdentityProvider

Продолжаем: делаем ActiveDirectoryIdentityProvider. В этом, например, LDAP-фильтр проверяет, что учетка юзера есть в AD группе admins и/или в AD группе developers. В поле certificateAuthorityData надо записать сертификат контроллера домена, только открытую часть. Используйте подсказку по фильтрам LDAP.

apiVersion: idp.supervisor.pinniped.dev/v1alpha1 kind: ActiveDirectoryIdentityProvider metadata:   name: ad-idp   namespace: pinniped-supervisor spec:   host: ad-dc1.office.ru   userSearch:     base: "OU=Users,OU=Offices,DC=office,DC=ru"     filter: "&(objectClass=person)(userPrincipalName={})(|(memberOf=CN=admins,OU=Groups,DC=office,DC=ru)(memberOf=CN=developers,OU=Groups,DC=office,DC=ru))"     attributes:         username: "sAMAccountName"   groupSearch:     base: "ou=Groups,DC=office,DC=ru"     filter: "&(objectClass=group)(member={})"   tls:     certificateAuthorityData: LS0t...   bind:     secretName: active-directory-bind-credentials

2.7 JWTAuthenticator

Идем дальше. В issuer пишем url лоад-балансера супервизора. В audience не принципиально, что будет написано, но нужно, чтобы для разных куб-кластеров это значение было разным. В certificateAuthorityData кладем сертификат от супервизора, только открытую часть.

apiVersion: authentication.concierge.pinniped.dev/v1alpha1 kind: JWTAuthenticator metadata:   name: jwt-auth spec:   issuer: https://pinniped-supervisor.ваш_домен.да   audience: from-pinniped   tls:     certificateAuthorityData: LS0t...

Установка закончена.

3. Конфигурация Kubernetes

Допустим, мы хотим, чтобы после успешного логина сотрудник мог в кубере успешно выполнять команды типа k get pods, k logs и подобные им – в некоторых заранее разрешенных неймспейсах.

  1. Для этого создадим в нашем кубе ClusterRole, и будем её назначать (bind) на неймспейсы и группы AD.

apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata:   name: pinniped-view rules: - apiGroups: [""]   resources: ["pods", "configmaps"]   verbs: ["get", "list"] - apiGroups: ["apps"]   resources: ["deployments"]   verbs: ["get", "list"] - apiGroups: [""]   resources: ["pods/log"]   verbs: ["get"]

2. Для каждого неймспейса, доступ в который мы хотим разрешить, делаем RoleBinding, который будет связывать кластер-роль с неймспейсом и с AD-группой, например, для неймспейса, который называется «util» и группы AD developers.

apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata:   name: pinniped-view-util-developers   namespace: util subjects: - kind: Group   name: developers@office.ru   apiGroup: rbac.authorization.k8s.io roleRef:   kind: ClusterRole   name: pinniped-view   apiGroup: rbac.authorization.k8s.io

Чтобы наши пользователи могли логиниться в кубер-кластер, им надо предоставить файл – ‎шаблон кубконфига, который будет направлять логин в Pinniped. 

Чтобы сделать этот файл, на свой комп ставим Pinneped-CLI. Логинимся в целевой куб-кластер как обычно, например:

kubectl config use-context ваш_кластер

Затем выполняем команду:

pinniped get kubeconfig > kubeconfig-template.yml 

Теперь в kubeconfig-template.yml файле у нас есть шаблон для авторизации. Этот файл раздаем коллегам, коллеги устанавливают себе Pinniped и используют этот файл как обычный куб-конфиг файл. В файле нет никакой конфиденциальной информации типа паролей и токенов.

5. Пользуемся логином 

Для работы с кластером коллеги будут выполнять подобную команду:

kubectl -n util get pods --kubeconfig kubeconfig-template.yml 

Появится приглашение на ввод имени пользователя Username – тут надо написать свою почту с доменом.

Дальше появится приглашение на ввод пароля – пишем свой пароль домена Windows.

Если все работает правильно, то должен показаться список подов в неймспейсе util, примерно такой: 

Всё, мы настроили логин в кубернетес с учеткой из домена Windows.

Заключение

Описанный инструмент помогает избавиться от рутинной операции создания новых учеток для использования в Kubernetes. При этом Pinniped оказался не самым популярным – чтобы его найти, пришлось спуститься в самые глубины CNCF Landscape. Тем ценнее навык работы с ним. 

Надеюсь, эта инструкция была для вас полезной. Если вы решали подобную задачу иначе – поделитесь в комментариях.


ссылка на оригинал статьи https://habr.com/ru/articles/846000/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *