Небольшая инструкция о том, как используя Keycloak можно связать Kubernetes с вашим LDAP-сервером и настроить импорт пользователей и групп. Это позволит настраивать RBAC для ваших пользователей и использовать auth-proxy чтобы защитить Kubernetes Dashboard и другие приложения, которые не умеют производить авторизацию самостоятельно.
Установка Keycloak
Предположим что у вас уже есть LDAP-сервер. Это может быть Active Directory, FreeIPA, OpenLDAP или что-либо еще. Если LDAP-сервера у вас нет, то в принципе вы можете создавать пользователей прямо в интерфейсе Keycloak, либо использовать публичные oidc-провайдеры (Google, Github, Gitlab), результат получится почти такой же.
Первым делом установим сам Keycloak, установка может выполняться отдельно, так и сразу в Kubernetes-кластер, как правило если у вас имеется несколько Kubernetes-кластеров, было бы проще установить его отдельно. С другой стороны вы всегда можете использовать
Для хранения данных Keycloak вам понадобится база данных. По умолчанию используется h2
(все данные хранятся локально), но возможно также использовать postgres
, mysql
или mariadb
.
Если вы все же надумали установить Keycloak отдельно, более подробные инструкции вы найдете в
Настройка федерации
Первым делом создадим новый realm. Realm — это пространство нашего приложения. Каждое приложение может иметь свой realm с разными пользователями и настройками авторизации. Master realm используется самим Keycloak и использовать его для чего-нибудь еще неправильно.
Нажимаем Add realm
Option
Value
Name
kubernetes
Display Name
Kubernetes
HTML Display Name
<img src="https://kubernetes.io/images/nav_logo.svg" width="400" >
Kubernetes по умолчанию проверяет подтвержден у пользователя email или нет. Так как мы используем собственный LDAP-сервер, то тут эта проверка почти всегда будет возвращать false
. Давайте отключим представление этого параметра в Kubernetes:
Client scopes —> Email —> Mappers —> Email verified (Delete)
Теперь настроим федерацию, для этого перейдем в:
User federation —> Add provider… —> ldap
Приведу пример настройки для FreeIPA:
Option
Value
Console Display Name
freeipa.example.org
Vendor
Red Hat Directory Server
UUID LDAP attribute
ipauniqueid
Connection URL
ldaps://freeipa.example.org
Users DN
cn=users,cn=accounts,dc=example,dc=org
Bind DN
uid=keycloak-svc,cn=users,cn=accounts,dc=example,dc=org
Bind Credential
<password>
Allow Kerberos authentication:
on
Kerberos Realm:
EXAMPLE.ORG
Server Principal:
HTTP/[email protected]
KeyTab:
/etc/krb5.keytab
Пользователя keycloak-svc
нужно создать заранее на нашем LDAP-сервере.
В случае с Active Directory, достаточно просто выбрать Vendor: Active Directory и необходимые настройки подставятся в форму автоматически.
Нажимаем Save
Теперь перейдем:
User federation —> freeipa.example.org —> Mappers —> First Name
Option
Value
Ldap attribure
givenName
Теперь включим маппинг групп:
User federation —> freeipa.example.org —> Mappers —> Create
Option
Value
Name
groups
Mapper type
group-ldap-mapper
LDAP Groups DN
cn=groups,cn=accounts,dc=example,dc=org
User Groups Retrieve Strategy
GET_GROUPS_FROM_USER_MEMBEROF_ATTRIBUTE
На этом настройка федерации закончена, перейдем к настройке клиента.
Настройка клиента
Создадим нового клиента (приложение которое будет получать пользователей из Keycloak). Переходим:
Clients —> Create
Option
Value
Client ID
kubernetes
Access Type
confidenrial
Root URL
http://kubernetes.example.org/
Valid Redirect URIs
http://kubernetes.example.org/*
Admin URL
http://kubernetes.example.org/
Так же создадим scope для групп:
Client Scopes —> Create
Option
Value
Template
No template
Name
groups
Full group path
false
И настроим mapper для них:
Client Scopes —> groups —> Mappers —> Create
Option
Value
Name
groups
Mapper Type
Group membership
Token Claim Name
groups
Теперь нам нужно включить маппинг груп в нашем client scope:
Clients —> kubernetes —> Client Scopes —> Default Client Scopes
Выбираем groups в Available Client Scopes, нажимаем Add selected
Теперь настроим аутентификацию нашего приложения, переходим:
Clients —> kubernetes
Option
Value
Authorization Enabled
ON
Нажимем save и на этом настройка клиента завершена, теперь на вкладке
Clients —> kubernetes —> Credentials
вы сможете получить Secret который мы будем использовать в дальнейшем.
Настройка Kubernetes
Настройка Kubernetes для OIDC-авторизации достаточно тривиальна и не является чем-то очень сложным. Все что вам нужно это положить CA-сертификат вашего OIDC-сервера в /etc/kubernetes/pki/oidc-ca.pem
и добавить необходимые опции для kube-apiserver.
Для этого обновите /etc/kubernetes/manifests/kube-apiserver.yaml
на всех ваших мастерах:
...
spec:
containers:
- command:
- kube-apiserver
...
- --oidc-ca-file=/etc/kubernetes/pki/oidc-ca.pem
- --oidc-client-id=kubernetes
- --oidc-groups-claim=groups
- --oidc-issuer-url=https://keycloak.example.org/auth/realms/kubernetes
- --oidc-username-claim=email
...
А так-же обновите kubeadm конфиг в кластере, что бы не потерять эти настройки при обновлении:
kubectl edit -n kube-system configmaps kubeadm-config
...
data:
ClusterConfiguration: |
apiServer:
extraArgs:
oidc-ca-file: /etc/kubernetes/pki/oidc-ca.pem
oidc-client-id: kubernetes
oidc-groups-claim: groups
oidc-issuer-url: https://keycloak.example.org/auth/realms/kubernetes
oidc-username-claim: email
...
На этом настройка Kubernetes завершена. Вы можете повторить данные действия во всех ваших Kubernetes-кластерах.
Начальная авторизация
После данных действий вы уже будете иметь Kubernetes-кластер с настроенной OIDC-авторизацией. Единственный момент, что ваши пользователи пока что не имеют настроенного клиента как и собственного kubeconfig. Что бы эту проблему решить нужно настроить автоматическую выдачу kubeconfig пользователям после успешной авторизации.
Для этого можно использовать специальные web-приложения, которые позволяют провести аутентификацию пользователя а затем скачать готовый kubeconfig. Одно из самых удобных — это
Для настройки Kuberos достаточно описать template для kubeconfig и запустить со следующими параметрами:
kuberos https://keycloak.example.org/auth/realms/kubernetes kubernetes /cfg/secret /cfg/template
Для более детальной информации смотрите
Так же возможно использовать
Полученный kubeconfig можно проверить на сайте users[].user.auth-provider.config.id-token
из вашего kubeconfig в форму на сайте и сразу получите расшифровку.
Настройка RBAC
При настройке RBAC можно ссылаться как на имя пользователя (поле name
в jwt-токене), так и на группу пользователей (поле groups
в jwt-токене). Вот пример настройки прав для группы kubernetes-default-namespace-admins
:
kubernetes-default-namespace-admins.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: default-admins
namespace: default
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubernetes-default-namespace-admins
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: default-admins
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: kubernetes-default-namespace-admins
Больше примеров для RBAC можно найти в
Настройка auth-proxy
Есть замечательный проект
dashboard-proxy.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: kubernetes-dashboard-proxy
spec:
replicas: 1
template:
metadata:
labels:
app: kubernetes-dashboard-proxy
spec:
containers:
- args:
- --listen=0.0.0.0:80
- --discovery-url=https://keycloak.example.org/auth/realms/kubernetes
- --client-id=kubernetes
- --client-secret=<your-client-secret-here>
- --redirection-url=https://kubernetes-dashboard.example.org
- --enable-refresh-tokens=true
- --encryption-key=ooTh6Chei1eefooyovai5ohwienuquoh
- --upstream-url=https://kubernetes-dashboard.kube-system
- --resources=uri=/*
image: keycloak/keycloak-gatekeeper
name: kubernetes-dashboard-proxy
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /oauth/health
port: 80
initialDelaySeconds: 3
timeoutSeconds: 2
readinessProbe:
httpGet:
path: /oauth/health
port: 80
initialDelaySeconds: 3
timeoutSeconds: 2
---
apiVersion: v1
kind: Service
metadata:
name: kubernetes-dashboard-proxy
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: kubernetes-dashboard-proxy
type: ClusterIP
Источник: habr.com