Как стать автором
Обновить

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

Уровень сложностиСредний
Время на прочтение7 мин
Количество просмотров2K

Многие пользователи Яндекс облака применяют сервис 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. Тем ценнее навык работы с ним. 

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

Теги:
Хабы:
Всего голосов 13: ↑13 и ↓0+17
Комментарии2

Публикации

Информация

Сайт
tech.lamoda.ru
Дата регистрации
Дата основания
Численность
5 001–10 000 человек
Местоположение
Россия