Налаштування шару агрегації
Налаштування шару агрегації дозволяє розширити apiserver Kubernetes додатковими API, які не є частиною основних API Kubernetes.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Для перевірки версії введітьkubectl version
.Примітка:
Існує кілька вимог щодо налаштування для роботи шару агрегації у вашому середовищі, щоб підтримувати взаємну автентифікацію TLS між проксі-сервером та apiserverʼом розширення. Kubernetes та kube-apiserver мають декілька ЦС (центрів сертифікації), тому переконайтеся, що проксі підписаний ЦС шару агрегації, а не іншим ЦС, таким як загальний ЦС Kubernetes.Увага:
Повторне використання одного ЦС для різних типів клієнтів може негативно вплинути на здатність кластера функціонувати. Для отримання додаткової інформації див. Повторне використання ЦС та конфлікти.Потоки автентифікації
На відміну від Custom Resource Definitions (CRDs), API агрегації включає ще один сервер, ваш apiserver розширення, крім стандартного apiserver Kubernetes. Kubernetes apiserver повинен взаємодіяти з вашим apiserver розширення, а ваш apiserver розширення повинен взаємодіяти з Kubernetes apiserver. Щоб ця взаємодія була захищеною, Kubernetes apiserver використовує x509 сертифікати для автентифікації себе перед apiserver розширення.
У цьому розділі описано, як працюють потоки автентифікації та авторизації та як їх налаштувати.
Основний потік виглядає наступним чином:
- Kubernetes apiserver: автентифікація користувача, що запитує, та авторизація його прав на запитаний API шлях.
- Kubernetes apiserver: проксіювання запиту до apiserverʼа розширення.
- apiserver розширення: автентифікація запиту від Kubernetes apiserver.
- apiserver розширення: авторизація запиту від початкового користувача.
- apiserver розширення: виконання.
У решті цього розділу описуються ці кроки детально.
Потік можна побачити на наступній діаграмі.
Джерело для вищезазначених потоків можна знайти у вихідному коді цього документа.
Автентифікація та авторизація Kubernetes Apiserver
Запит до API шляху, який обслуговується apiserver розширення, починається так само, як і всі API запити: з комунікації з Kubernetes apiserver. Цей шлях вже був зареєстрований з Kubernetes apiserver apiserver розширення.
Користувач взаємодіє з Kubernetes apiserver, запитуючи доступ до шляху. Kubernetes apiserver використовує стандартну автентифікацію та авторизацію, налаштовану в Kubernetes apiserver, для автентифікації користувача та авторизації доступу до конкретного шляху.
Для загального огляду автентифікації в кластері Kubernetes див. "Автентифікація в кластері". Для загального огляду авторизації доступу до ресурсів кластера Kubernetes див. "Огляд авторизації".
Все до цього моменту було стандартними запитами API Kubernetes, автентифікацією та авторизацією.
Kubernetes apiserver тепер готовий відправити запит до apiserverʼа розширення.
Проксіювання запиту Kubernetes Apiserver
Kubernetes apiserver тепер відправить або проксує запит до apiserverʼа розширення, який зареєстрований для обробки цього запиту. Для цього потрібно знати кілька речей:
- Як Kubernetes apiserver повинен автентифікуватися у apiserver розширення, інформуючи його, що запит, який надходить мережею, надходить від дійсного Kubernetes apiserver?
- Як Kubernetes apiserver повинен інформувати apiserver розширення про імʼя користувача та групу, з якими оригінальний запит був автентифікований?
Щоб забезпечити ці два аспекти, ви повинні налаштувати Kubernetes apiserver, використовуючи кілька прапорців.
Автентифікація клієнта Kubernetes Apiserver
Kubernetes apiserver підключається до apiserverʼа розширення через TLS, автентифікується за допомогою клієнтського сертифіката. Ви повинні надати наступне для Kubernetes apiserver при запуску, використовуючи вказані параметри:
- файл приватного ключа через
--proxy-client-key-file
- підписаний файл клієнтського сертифіката через
--proxy-client-cert-file
- сертифікат CA, який підписав файл клієнтського сертифіката через
--requestheader-client-ca-file
- дійсні значення загального імені (CN) в підписаному клієнтському сертифікаті через
--requestheader-allowed-names
Kubernetes apiserver використовуватиме файли, вказані --proxy-client-*-file
, щоб автентифікуватися у apiserver розширення. Щоб запит був вважався дійсним відповідно до стандартів apiserverʼа розширення, мають виконуватися наступні умови:
- Підключення має бути виконане за допомогою клієнтського сертифіката, який підписаний CA, сертифікат якого знаходиться в
--requestheader-client-ca-file
. - Підключення має бути виконане за допомогою клієнтського сертифіката, CN якого знаходиться в одному з тих, що перелічені в
--requestheader-allowed-names
.
Примітка:
Ви можете встановити цей параметр як порожній рядок:--requestheader-allowed-names=""
. Це позначатиме для apiserverʼа розширення, що будь-яке CN прийнятне.Після запуску з цими параметрами Kubernetes apiserver:
- Використовуватиме їх для автентифікації у apiserver розширення.
- Створить ConfigMap у просторі імен
kube-system
з назвоюextension-apiserver-authentication
, в який він помістить сертифікат CA та дозволені CN. Ці дані можна отримати apiserverʼа розширенняs для перевірки запитів.
Зверніть увагу, що той самий клієнтський сертифікат використовується Kubernetes apiserver для автентифікації для усіх apiserverʼів розширень. Він не створює окремий клієнтський сертифікат для кожного apiserverʼа розширення, а лише один, щоб автентифікуватися як Kubernetes apiserver. Цей самий сертифікат використовується для всіх запитів apiserverʼа розширення.
Імʼя користувача та група оригінального запиту
Коли Kubernetes apiserver проксіює запит до apiserverʼа розширення, він повідомляє apiserver розширення імʼя користувача та групу, з якими успішно був автентифікований початковий запит. Він надає це у http заголовках свого проксі-запиту. Ви повинні повідомити Kubernetes apiserver назви заголовків, які слід використовувати.
- заголовок, в якому зберігати імʼя користувача через
--requestheader-username-headers
- заголовок, в якому зберігати групу через
--requestheader-group-headers
- префікс для всіх додаткових заголовків через
--requestheader-extra-headers-prefix
Ці назви заголовків також поміщаються в ConfigMap extension-apiserver-authentication
, так що їх можна отримати та використати apiserverʼа розширенняs.
Apiserver розширення автентифікує запит
apiserver розширення, отримавши проксі-запит від Kubernetes apiserver, повинен перевірити, що запит дійсно надійшов від дійсного автентифікуючого проксі, роль якого виконує Kubernetes apiserver. apiserver розширення перевіряє його за допомогою:
- Отримання наступного з ConfigMap в
kube-system
, як описано вище:- Сертифікат CA клієнта
- Список дозволених імен (CN)
- Назви заголовків для імені користувача, групи та додаткової інформації
- Перевірте, що TLS-зʼєднання було автентифіковано за допомогою сертифіката клієнта, який:
- Був підписаний CA, чий сертифікат відповідає отриманому сертифікату CA.
- Має CN у списку дозволених CN, якщо список не порожній, в іншому випадку дозволяються всі CN.
- Витягу імені користувача та групи з відповідних заголовків.
Якщо вище зазначене пройшло, тоді запит є дійсним проксійним запитом від законного проксі автентифікації, у цьому випадку — apiserver Kubernetes.
Зверніть увагу, що відповідальність за надання вищезазначеного лежить на реалізації apiserverʼа розширення. Більшість роблять це стандартно, використовуючи пакет k8s.io/apiserver/
. Інші можуть надати опції для зміни цього за допомогою параметрів командного рядка.
Для того, щоб мати дозвіл на отримання конфігураційного файлу, apiserver розширення потребує відповідної ролі. Існує стандартна роль з назвою extension-apiserver-authentication-reader
в просторі імен kube-system
, яка може бути призначена.
Apiserver розширення авторизує запит
Тепер apiserver розширення може перевірити, що користувач/група, отримані з заголовків, мають дозвіл на виконання даного запиту. Він робить це, надсилаючи стандартний запит SubjectAccessReview до apiserver Kubernetes.
Для того, щоб apiserver розширення мав право на надсилання запиту SubjectAccessReview
до apiserver Kubernetes, йому потрібні відповідні дозволи. Kubernetes включає стандартну ClusterRole
з назвою system:auth-delegator
, яка має необхідні дозволи. Її можна надати обліковому запису служби apiserverʼа розширенняа.
Виконання Apiserver розширення
Якщо перевірка SubjectAccessReview
пройде успішно, apiserver розширення виконує запит.
Увімкнення прапорців Apiserver Kubernetes
Увімкніть агрегаційний шар за допомогою наступних прапорців kube-apiserver
. Вони можуть вже бути налаштовані вашим постачальником.
--requestheader-client-ca-file=<шлях до сертифікату CA агрегатора>
--requestheader-allowed-names=front-proxy-client
--requestheader-extra-headers-prefix=X-Remote-Extra-
--requestheader-group-headers=X-Remote-Group
--requestheader-username-headers=X-Remote-User
--proxy-client-cert-file=<шлях до сертифікату проксі-клієнта агрегатора>
--proxy-client-key-file=<шлях до ключа проксі-клієнта агрегатора>
Повторне використання та конфлікти сертифікатів CA
У Kubernetes apiserver є два параметри CA клієнта:
--client-ca-file
--requestheader-client-ca-file
Кожен з цих параметрів працює незалежно і може конфліктувати один з одним, якщо їх не використовувати належним чином.
--client-ca-file
: Коли запит надходить на Kubernetes apiserver, якщо цей параметр увімкнено, Kubernetes apiserver перевіряє сертифікат запиту. Якщо він підписаний одним з сертифікатів CA в файлі, на який вказує--client-ca-file
, то запит вважається законним, а користувач — значенням загального іменіCN=
, а група — організацієюO=
. Див. документацію з автентифікації TLS.--requestheader-client-ca-file
: Коли запит надходить на Kubernetes apiserver, якщо цей параметр увімкнено, Kubernetes apiserver перевіряє сертифікат запиту. Якщо він підписаний одним із сертифікатів CA у файлі, на який вказує--requestheader-client-ca-file
, то запит вважається потенційно законним. Потім Kubernetes apiserver перевіряє, чи є загальне імʼяCN=
одним з імен у списку, наданому параметром--requestheader-allowed-names
. Якщо імʼя дозволене, запит схвалюється; якщо ні, запит відхиляється.
Якщо обидва параметри --client-ca-file
та --requestheader-client-ca-file
надані, то спочатку запит перевіряє CA --requestheader-client-ca-file
, а потім --client-ca-file
. Зазвичай для кожного з цих параметрів використовуються різні сертифікати CA, або кореневі CA, або проміжні CA; звичайні клієнтські запити відповідають --client-ca-file
, тоді як агрегаційні запити відповідають --requestheader-client-ca-file
. Однак, якщо обидва використовують той самий CA, то звичайні клієнтські запити, які зазвичай пройшли б через --client-ca-file
, не пройдуть, оскільки CA буде відповідати CA в --requestheader-client-ca-file
, але загальне імʼя CN=
не буде відповідати одному з припустимих загальних імен в --requestheader-allowed-names
. Це може призвести до того, що kublete та інші компоненти панелі управління, так само як і інші клієнти, не зможуть автентифікуватись на Kubernetes apiserver.
З цієї причини використовуйте різні сертифікати CA для опції --client-ca-file
, щоб авторизувати компоненти панелі управління та кінцевих користувачів, і опції --requestheader-client-ca-file
, щоб авторизувати запити apiserverʼа агрегації.
Попередження:
Не використовуйте знову CA, який використовується в іншому контексті, якщо ви не розумієте ризики та механізми захисту використання CA.Якщо ви не запускаєте kube-proxy на хості, на якому працює API-сервер, вам потрібно впевнитися, що система ввімкнена з наступним прапорцем kube-apiserver
:
--enable-aggregator-routing=true
Реєстрація обʼєктів APIService
Ви можете динамічно налаштувати, які клієнтські запити будуть проксійовані до apiserverʼа розширення. Нижче наведено приклад реєстрації:
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
name: <імʼя обʼєкта реєстрації>
spec:
group: <назва групи API, яку обслуговує цей apiserver розширення>
version: <версія API, яку обслуговує цей apiserver розширення>
groupPriorityMinimum: <пріоритет цього APIService для цієї групи, див. документацію API>
versionPriority: <пріоритет упорядкування цієї версії у межах групи, див. документацію API>
service:
namespace: <простір імен сервісу apiserverʼа розширення>
name: <імʼя сервісу apiserverʼа розширення>
caBundle: <pem-кодований ca-сертифікат, який підписує сертифікат сервера, який використовується вебзапитом>
Імʼя обʼєкта APIService повинно бути дійсним імʼям сегмента шляху.
Звертання до apiserverʼа розширення
Після того, як Kubernetes apiserver вирішив, що запит потрібно надіслати до apiserverʼа розширення, він повинен знати, як з ним звʼязатися.
Блок service
— це посилання на сервіс для apiserverʼа розширення. Простір імен та імʼя сервісу обовʼязкові. Порт є необовʼязковим і типово дорівнює 443.
Ось приклад apiserverʼа розширення, який налаштований для виклику на порті "1234" та перевірки зʼєднання TLS проти ServerName my-service-name.my-service-namespace.svc
, використовуючи власний пакет CA.
apiVersion: apiregistration.k8s.io/v1
kind: APIService
...
spec:
...
service:
namespace: my-service-namespace
name: my-service-name
port: 1234
caBundle: "Ci0tLS0tQk...<base64-кодований PEM пакет>...tLS0K"
...
Що далі
- Налаштуйте apiserver розширення для роботи з шаром агрегації.
- Для загального огляду див. Розширення Kubernetes API за допомогою шару агрегації.
- Дізнайтеся, як Розширити API Kubernetes, використовуючи визначення власних ресурсів.