Налаштування шару агрегації дозволяє розширити apiserver Kubernetes додатковими API, які не є частиною основних API Kubernetes.
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Для перевірки версії введіть kubectl version.
На відміну від Custom Resource Definitions (CRDs), API агрегації включає ще один сервер, ваш apiserver розширення, крім стандартного apiserver Kubernetes. Kubernetes apiserver повинен взаємодіяти з вашим apiserver розширення, а ваш apiserver розширення повинен взаємодіяти з Kubernetes apiserver. Щоб ця взаємодія була захищеною, Kubernetes apiserver використовує x509 сертифікати для автентифікації себе перед apiserver розширення.
У цьому розділі описано, як працюють потоки автентифікації та авторизації та як їх налаштувати.
Основний потік виглядає наступним чином:
У решті цього розділу описуються ці кроки детально.
Потік можна побачити на наступній діаграмі.

Джерело для вищезазначених потоків можна знайти у вихідному коді цього документа.
Запит до API шляху, який обслуговується apiserver розширення, починається так само, як і всі API запити: з комунікації з Kubernetes apiserver. Цей шлях вже був зареєстрований з Kubernetes apiserver apiserver розширення.
Користувач взаємодіє з Kubernetes apiserver, запитуючи доступ до шляху. Kubernetes apiserver використовує стандартну автентифікацію та авторизацію, налаштовану в Kubernetes apiserver, для автентифікації користувача та авторизації доступу до конкретного шляху.
Для загального огляду автентифікації в кластері Kubernetes див. "Автентифікація в кластері". Для загального огляду авторизації доступу до ресурсів кластера Kubernetes див. "Огляд авторизації".
Все до цього моменту було стандартними запитами API Kubernetes, автентифікацією та авторизацією.
Kubernetes apiserver тепер готовий відправити запит до apiserverʼа розширення.
Kubernetes apiserver тепер відправить або проксує запит до apiserverʼа розширення, який зареєстрований для обробки цього запиту. Для цього потрібно знати кілька речей:
Щоб забезпечити ці два аспекти, ви повинні налаштувати Kubernetes apiserver, використовуючи кілька прапорців.
Kubernetes apiserver підключається до apiserverʼа розширення через TLS, автентифікується за допомогою клієнтського сертифіката. Ви повинні надати наступне для Kubernetes apiserver при запуску, використовуючи вказані параметри:
--proxy-client-key-file--proxy-client-cert-file--requestheader-client-ca-file--requestheader-allowed-namesKubernetes apiserver використовуватиме файли, вказані --proxy-client-*-file, щоб автентифікуватися у apiserver розширення. Щоб запит був вважався дійсним відповідно до стандартів apiserverʼа розширення, мають виконуватися наступні умови:
--requestheader-client-ca-file.--requestheader-allowed-names.--requestheader-allowed-names="". Це позначатиме для apiserverʼа розширення, що будь-яке CN прийнятне.Після запуску з цими параметрами Kubernetes apiserver:
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 розширення, отримавши проксі-запит від Kubernetes apiserver, повинен перевірити, що запит дійсно надійшов від дійсного автентифікуючого проксі, роль якого виконує Kubernetes apiserver. apiserver розширення перевіряє його за допомогою:
kube-system, як описано вище:
Якщо вище зазначене пройшло, тоді запит є дійсним проксійним запитом від законного проксі автентифікації, у цьому випадку — apiserver Kubernetes.
Зверніть увагу, що відповідальність за надання вищезазначеного лежить на реалізації apiserverʼа розширення. Більшість роблять це стандартно, використовуючи пакет k8s.io/apiserver/. Інші можуть надати опції для зміни цього за допомогою параметрів командного рядка.
Для того, щоб мати дозвіл на отримання конфігураційного файлу, apiserver розширення потребує відповідної ролі. Існує стандартна роль з назвою extension-apiserver-authentication-reader в просторі імен kube-system, яка може бути призначена.
Тепер apiserver розширення може перевірити, що користувач/група, отримані з заголовків, мають дозвіл на виконання даного запиту. Він робить це, надсилаючи стандартний запит SubjectAccessReview до apiserver Kubernetes.
Для того, щоб apiserver розширення мав право на надсилання запиту SubjectAccessReview до apiserver Kubernetes, йому потрібні відповідні дозволи. Kubernetes включає стандартну ClusterRole з назвою system:auth-delegator, яка має необхідні дозволи. Її можна надати службовому обліковому запису apiserverʼа розширенняа.
Якщо перевірка SubjectAccessReview пройде успішно, apiserver розширення виконує запит.
Увімкніть агрегаційний шар за допомогою наступних прапорців 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=<шлях до ключа проксі-клієнта агрегатора>
У 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ʼа агрегації.
Якщо ви не запускаєте kube-proxy на хості, на якому працює API-сервер, вам потрібно впевнитися, що система ввімкнена з наступним прапорцем kube-apiserver:
--enable-aggregator-routing=true
Ви можете динамічно налаштувати, які клієнтські запити будуть проксійовані до 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 повинно бути дійсним імʼям сегмента шляху.
Після того, як 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"
...