Все правильно, після релізу Hashicorp Consul 1.5.0 на початку травня 2019 року в Consul можна робити авторизацію додатків та служб, запущених у Kubernetes, нативно.
У цьому посібнику ми крок за кроком створимо POC (Перевірка концепції (Proof of concept, PoC — доказ [здійсненності] концепції — прим. перекл.), продемонструвавши цю нову функцію. Від вас очікуються базові знання про Kubernetes та Hashicorp's Consul. І хоча ви можете використовувати будь-яку хмарну платформу чи локальне середовище, у цьому посібнику ми будемо використовувати Google Cloud Platform.
Огляд
Якщо ми перейдемо до документації Consul за його методом авторизації, ми отримаємо короткий огляд його призначення та варіанти використання, а також деякі технічні деталі та загальний огляд логіки. Я настійно рекомендую прочитати її принаймні один раз, перш ніж продовжити, тому що зараз я все це пояснюватиму і розжовуватиму.
Схема 1: Офіційний огляд методу авторизації Consul
Звичайно, там є корисна інформація, але немає посібника про те, як насправді все це використовувати. Тому, як будь-яка розсудлива людина, ви прочісує Інтернет у пошуках керівництва. А потім... Зазнайте поразки. Так буває. Давайте це виправимо.
Перш ніж ми перейдемо до створення нашого POC, повернімося до огляду методів авторизації Consul (Схема 1) і уточнимо його в контексті Kubernetes.
Архітектура
У цьому посібнику ми будемо створювати Consul-сервер на окремій машині, яка буде взаємодіяти з кластером Kubernetes із встановленим клієнтом Consul. Потім ми створимо наш фіктивний додаток у поді та використовуємо наш налаштований метод авторизації для читання з нашого Consul key/value сховища.
Схема нижче детально показує архітектуру, яку ми створюємо в цьому посібнику, а також логіку методу авторизації, яка буде пояснена пізніше.
Схема 2: Огляд методу авторизації в Kubernetes
Невелике зауваження: Consul-серверу не потрібно жити поза межами кластера Kubernetes, щоб це працювало. Але так, він може і так і сяк.
Отже, взявши оглядову схему Consul (Схема 1) і застосувавши Kubernetes до неї, ми отримуємо схему вище (Схема 2), і тут логіка буде наступна:
До кожного поду буде прикріплено службовий обліковий запис, що містить токен JWT, згенерований та відомий Kubernetes. Цей токен також вставляється в під за замовчуванням.
Наша програма або сервіс всередині пода ініціює команду входу в наш Consul-клієнт. У запиті на вхід до системи також буде вказано наш токен та вказано ім'я спеціально створеного методу авторизації (типу Kubernetes). Цей крок № 2 відповідає кроці 1 схеми Consul (Схема 1).
Наш Consul-клієнт потім надішле цей запит на наш Consul-сервер.
МАГІЯ! Саме тут Consul-сервер перевіряє справжність запиту, збирає відомості про ідентичність запиту та порівнює їх із якими-небудь асоційованими визначеними правилами. Нижче буде інша схема, щоби це проілюструвати. Цей крок відповідає крокам 3, 4 та 5 оглядової схеми Consul (Схема 1).
Наш Consul-сервер генерує Consul токен з дозволами відповідно до вказаних нами правил методу авторизації (які ми визначили) щодо особи запитуючого. Потім він відправить цей токен назад. Це відповідає кроці 6 схеми Consul (Схема 1).
Наш Consul-клієнт перенаправляє токен додатку або сервісу, що запитує.
Наша програма або сервіс тепер можуть використовувати цей Consul токен для зв'язку з нашими даними Consul, як було визначено привілеями токена.
Чари розкриті!
Для тих з вас, хто не задоволений лише кроликом з капелюха і хоче знати, як це працює… дозвольте мені «показати вам, наскільки глибока кроляча нора».
Як згадувалося раніше, наш «магічний» крок (Схема 2: Крок 4) полягає в тому, що Consul-сервер перевіряє справжність запиту, збирає відомості про запит та порівнює їх із будь-якими асоційованими визначеними правилами. Цей крок відповідає крокам 3, 4 та 5 оглядової схеми Consul (Схема 1). Нижче наведено схему (Схема 3), мета якої наочно показати, що насправді відбувається під капотом конкретний метод авторизації Kubernetes.
Схема 3: Чари розкриті!
Як відправна точка, наш Consul-клієнт перенаправляє запит на вхід на наш Consul-сервер з токеном облікового запису Kubernetes і конкретним ім'ям інстансу методу авторизації, який був створений раніше. Цей крок відповідає кроці 3 у попередньому поясненні схеми.
Тепер Consul-сервер (або лідер) необхідно перевірити справжність отриманого токена. Тому він проконсультується з кластером Kubernetes (через Consul-клієнт) і, за наявності відповідних дозволів, ми з'ясуємо, чи токен є справжнім, і кому він належить.
Потім перевірений запит повертається до Consul-лідера, і на сервері Consul виконується пошук інстансу методу авторизації із зазначеним ім'ям із запиту на вхід до системи (та типу Kubernetes).
Consul-лідер визначає зазначений інстанс методу авторизації (якщо його знайдено) і читає набір правил прив'язки, які до нього прикріплені. Потім він читає ці правила і порівнює їх із перевіреними атрибутами ідентичності.
Та да! Переходимо до кроку 5 попередньому поясненні схеми.
Запустіть Consul-server на звичайній віртуальній машині
З цього моменту я в основному даватиму інструкції щодо створення цього POC, часто в пунктах, без пояснювальних цілих пропозицій. Також, як зазначалося раніше, я використовуватиму GCP для створення всієї інфраструктури, але ви можете створити таку ж інфраструктуру в будь-якому іншому місці.
Запустіть віртуальну машину (інстанс/сервер).
Створіть правило для firewall (група безпеки в AWS):
Мені подобається присвоювати те саме ім'я машини правилу і мережному тегу, в даному випадку це «skywiz-consul-server-poc».
Знайдіть IP-адресу вашого локального комп'ютера і додайте її до списку вихідних IP-адрес, щоб отримати доступ до інтерфейсу користувача (UI).
Відкрийте порт 8500 для UI. Натисніть Create (Створити). Ми незабаром знову змінимо цей firewall [посилання].
Додайте правило для firewall до інстансу. Поверніться на панель моніторингу VM на сервері Consul і додайте «skywiz-consul-server-poc» у поле мережевих тегів. Натисніть Save (Зберегти).
Встановіть Consul на віртуальну машину, перевірте тут. Пам'ятайте, що вам потрібна версія Consul ≥ 1.5 [посилання]
Створимо single node Consul - наступна конфігурація.
groupadd --system consul
useradd -s /sbin/nologin --system -g consul consul
mkdir -p /var/lib/consul
chown -R consul:consul /var/lib/consul
chmod -R 775 /var/lib/consul
mkdir /etc/consul.d
chown -R consul:consul /etc/consul.d
Докладніше посібник зі встановлення Consul та налаштування кластера з 3 нід див. тут.
Створіть файл /etc/consul.d/agent.json так [посилання]:
consul agent
-server
-ui
-client 0.0.0.0
-data-dir=/var/lib/consul
-bootstrap-expect=1
-config-dir=/etc/consul.d
Ви повинні побачити купу вихідних даних і зрештою “… update blocked by ACLs”.
Знайдіть зовнішню IP-адресу Consul-сервера та відкрийте браузер із цією IP-адресою на порту 8500. Переконайтеся, що відкривається UI.
Спробуйте додати пару ключ/значення. Має бути помилка. Це тому, що ми завантажили сервер Consul за допомогою ACL і заборонили всі правила.
Поверніться до своєї оболонки на Consul-сервері і запустіть процес у фоновому режимі або іншим способом, щоб він працював, і введіть наступне:
consul acl bootstrap
Знайдіть значення "SecretID" і поверніться до UI. На вкладці ACL введіть секретний ідентифікатор токена, який ви тільки що скопіювали. Скопіюйте SecretID ще кудись, він знадобиться нам пізніше.
Тепер додайте пару ключ/значення. Для цього POC додамо таке: ключ: "custom-ns/test_key", значення: "I'm in the custom-ns folder!"
Запуск Kubernetes-кластера для нашої програми з Consul-клієнтом як Daemonset
Створіть кластер K8s (Kubernetes). Ми створимо його в тій же зоні, що й сервер, для більш швидкого доступу, і тому ми можемо використовувати ту саму підмережу для простого підключення з внутрішніми IP-адресами. Ми назвемо його "skywiz-app-with-consul-client-poc".
Як примітка, ось хороший посібник, з яким я зіткнувся при налаштуванні POC Consul-кластера з Consul Connect.
Ми також будемо використовувати Hashicorp helm chart із розширеним файлом значень.
Встановіть та налаштуйте Helm. Кроки конфігурації:
Використовуйте наступний файл значень (зверніть увагу, більшість я відключив):
### poc-helm-consul-values.yaml
global:
enabled: false
image: "consul:latest"
# Expose the Consul UI through this LoadBalancer
ui:
enabled: false
# Allow Consul to inject the Connect proxy into Kubernetes containers
connectInject:
enabled: false
# Configure a Consul client on Kubernetes nodes. GRPC listener is required for Connect.
client:
enabled: true
join: ["<PRIVATE_IP_CONSUL_SERVER>"]
extraConfig: |
{
"acl" : {
"enabled": true,
"default_policy": "deny",
"enable_token_persistence": true
}
}
# Minimal Consul configuration. Not suitable for production.
server:
enabled: false
# Sync Kubernetes and Consul services
syncCatalog:
enabled: false
Застосуйте helm chart:
./helm install -f poc-helm-consul-values.yaml ./consul-helm - name skywiz-app-with-consul-client-poc
При спробі запуску йому знадобляться дозволи для Consul-сервера, так що давайте додамо їх.
Зверніть увагу на «діапазон адрес Pod», розташований на панелі приладів кластера, і поверніться до нашого правила для firewall «skywiz-consul-server-poc».
Додайте діапазон адрес для подавання до списку IP-адрес та відкрийте порти 8301 та 8300.
Перейдіть до Consul UI, і за кілька хвилин ви побачите, що наш кластер з'явиться на вкладці нод.
Налаштування методу авторизації шляхом інтеграції Consul з Kubernetes
Поверніться в оболонку Consul-сервера та експортуйте токен, який ви зберегли раніше:
export CONSUL_HTTP_TOKEN=<SecretID>
Нам знадобиться інформація з нашого Kubernetes-кластера, щоб створити інстанс методу auth:
kubernetes-host
kubectl get endpoints | grep kubernetes
kubernetes-service-account-jwt
kubectl get sa <helm_deployment_name>-consul-client -o yaml | grep "- name:"
kubectl get secret <secret_name_from_prev_command> -o yaml | grep token:
Токен закодований в base64, тому розшифруйте його за допомогою вашого улюбленого інструменту [посилання]
kubernetes-ca-cert
kubectl get secret <secret_name_from_prev_command> -o yaml | grep ca.crt:
Візьміть сертифікат ca.crt (після декодування з base64) і впишіть його у файл ca.crt.
Тепер створіть інстанс методу auth, замінивши місцеholders на значення, які ви тільки що отримали.
consul acl auth-method create
-type "kubernetes"
-name "auth-method-skywiz-consul-poc"
-description "This is an auth method using kubernetes for the cluster skywiz-app-with-consul-client-poc"
-kubernetes-host "<k8s_endpoint_retrieved earlier>"
[email protected]
-kubernetes-service-account-
jwt="<decoded_token_retrieved_earlier>"
Далі ми маємо створити правило та прикріпити його до нової ролі. Для цієї частини можна використовувати Consul UI, але ми будемо використовувати командний рядок.
Потім застосуйте наступну вбудовану команду для створення configmap [посилання]. Зверніть увагу, що ми посилаємось на назву нашого сервісу, замініть його за потреби.
Створіть ще кілька ключових папок із тим самим ключем верхнього рівня (тобто. /sample_key) і значенням на ваш вибір. Створіть відповідні політики та ролі для нових ключових шляхів. Ми зробимо прив'язки пізніше.
Користувальницький тест простору імен:
Створимо наш власний простір імен:
kubectl create namespace custom-ns
Створимо під нашому новому просторі імен. Напишіть конфігурацію для подавання.
Ви можете декодувати "Value" base64 і побачити, що воно відповідає значенню в custom-ns/test_key в UI. Якщо ви використовували те саме значення, наведене вище в цьому посібнику, ваше кодоване значення буде IkknbSBpbiB0aGUgY3VzdG9tLW5zIGZvbGRlciEi.
Тест облікового запису користувальницької служби:
Створіть користувальницький ServiceAccount за допомогою наступної команди [посилання].
Ви також можете переконатися, що цей токен не надає доступу kv у «custom-ns/». Просто повторіть наведену вище команду після заміни custom-sa на префікс custom-ns.
У дозволі відмовлено.
Приклад свердління:
Всі порівняння rule-binding будуть додані в токен з цими правами.
Наш контейнер «poc-ubuntu-custom-sa» знаходиться в просторі стандартних імен — так що давайте використовувати його для іншої rule-binding.
Повторіть попередні кроки:
а) Створіть ідентичну Політику префіксу ключа «default/».
б) Створіть Role, назвіть її "default-ns-role"
в) Прикріпіть Політику до Role.
Створіть Rule-Binding (можливо тільки з cli/api)
consul acl binding-rule create
-method=auth-method-skywiz-consul-poc
-bind-type=role
-bind-name='default-ns-role'
-selector='serviceaccount.namespace=="default"'
Поверніться до нашого контейнера «poc-ubuntu-custom-sa» і спробуйте отримати доступ до «default/» kv.
У дозволі відмовлено.
Ви можете переглянути облікові дані для кожного токена в UI в розділі ACL > Tokens. Як бачите, до нашого поточного токену прикріплена лише одна «custom-sa-role». Токен, який ми використовуємо в даний час, був згенерований, коли ми увійшли в систему, і тоді була тільки одна rule-binding, яка тоді відповідала. Нам потрібно знову увійти до системи та використовувати новий токен.
Переконайтеся, що ви можете читати як зі шляхів «custom-sa/», так і «default/» kv.
Успіх!
Це пов'язано з тим, що наш «poc-ubuntu-custom-sa» відповідає прив'язкам правил «custom-sa» та «default-ns».
Висновок
TTL token mgmt?
На момент написання цієї статті немає інтегрованого способу визначення TTL для токенів, згенерованих цим методом авторизації. Це була б фантастична можливість забезпечити безпечну автоматизацію авторизації Consul.