Kubernetes Basics
Основи Kubernetes
Вивчайте та практикуйте взлом AWS:Навчання HackTricks AWS Red Team Expert (ARTE)
Вивчайте та практикуйте взлом GCP:
Навчання HackTricks GCP Red Team Expert (GRTE)
Оригінальний автор цієї сторінки Jorge (читайте його оригінальний пост тут)
Архітектура та Основи
Що робить Kubernetes?
Дозволяє запуск контейнера/ів у контейнерному двигуні.
Розклад дозволяє контейнерам ефективно виконувати місію.
Підтримує життєздатність контейнерів.
Дозволяє комунікацію між контейнерами.
Дозволяє техніки розгортання.
Обробляє обсяги інформації.
Архітектура
![](https://cloud.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2Fsickrov.github.io%2Fmedia%2FScreenshot-68.jpg&width=768&dpr=4&quality=100&sign=4902871c&sv=1)
Вузол (Node): операційна система з підсистемою або підсистемами.
Підсистема (Pod): Обгортка навколо контейнера або кількох контейнерів. Підсистема повинна містити лише одну програму (таким чином, зазвичай підсистема запускає лише 1 контейнер). Підсистема - це спосіб, яким Kubernetes абстрагує технологію контейнерів, що працює.
Служба (Service): Кожна підсистема має 1 внутрішній IP-адресу з внутрішнього діапазону вузла. Однак його також можна використовувати через службу. Служба також має IP-адресу і її мета полягає в підтримці зв'язку між підсистемами, тому якщо одна підсистема вмирає, новий замінник (з іншою внутрішньою IP-адресою) буде доступний через той самий IP служби. Його можна налаштувати як внутрішній або зовнішній. Служба також діє як балансувальник навантаження, коли 2 підсистеми підключені до однієї служби. Коли створюється служба, ви можете знайти кінцеві точки кожної служби, запустивши
kubectl get endpoints
Kubelet: Основний агент вузла. Компонент, який встановлює зв'язок між вузлом та kubectl, і може запускати лише підсистеми (через API-сервер). Kubelet не керує контейнерами, які не були створені Kubernetes.
Kube-proxy: це служба, відповідальна за комунікації (служби) між apiserver та вузлом. Основа - це IPtables для вузлів. Досвідчені користувачі можуть встановлювати інші kube-proxy від інших вендорів.
Бічний контейнер (Sidecar container): Бічні контейнери - це контейнери, які повинні працювати разом з основним контейнером у підсистемі. Цей шаблон бічного контейнера розширює та покращує функціональність поточних контейнерів без їх зміни. На сьогоднішній день ми знаємо, що ми використовуємо технологію контейнерів для упакування всіх залежностей для запуску додатка в будь-якому місці. Контейнер робить лише одну річ і робить це дуже добре.
Майстер-процес:
Сервер API (Api Server): Це спосіб, яким користувачі та підсистеми взаємодіють з майстер-процесом. Повинні допускатися лише аутентифіковані запити.
Планувальник (Scheduler): Планування означає переконання, що Підсистеми відповідають Вузлам, щоб Kubelet міг їх запустити. У нього достатньо інтелекту, щоб вирішити, який вузол має більше доступних ресурсів, і призначити нову підсистему для нього. Зверніть увагу, що планувальник не запускає нові підсистеми, він просто взаємодіє з процесом Kubelet, який працює всередині вузла, який запустить нову підсистему.
Керуючий контролер Kubernetes (Kube Controller manager): Він перевіряє ресурси, такі як набори реплік або розгортання, щоб переконатися, наприклад, що правильна кількість підсистем або вузлів працює. У разі відсутності підсистеми він буде взаємодіяти з планувальником, щоб запустити нову. Він контролює реплікацію, токени та облікові служби для API.
etcd: Зберігання даних, постійне, послідовне та розподілене. Це база даних Kubernetes та сховище ключ-значення, де воно зберігає повний стан кластерів (кожна зміна реєструється тут). Компоненти, такі як Планувальник або Керуючий контролер, залежать від цих даних, щоб знати, які зміни відбулися (доступні ресурси вузлів, кількість запущених підсистем...).
Керуючий контролер хмарних служб (Cloud controller manager): Це конкретний контролер для керування потоками та додатками, наприклад, якщо у вас є кластери в AWS або OpenStack.
Зверніть увагу, що оскільки може бути кілька вузлів (що запускають кілька підсистем), може бути кілька майстер-процесів, доступ до яких до сервера API балансується та їх etcd синхронізований.
Томи (Volumes):
Коли підсистема створює дані, які не повинні бути втрачені при зникненні підсистеми, їх слід зберігати на фізичному томі. Kubernetes дозволяє прикріплювати том до підсистеми для збереження даних. Том може бути на локальній машині або на віддаленому сховищі. Якщо ви запускаєте підсистеми на різних фізичних вузлах, вам слід використовувати віддалене сховище, щоб всі підсистеми могли до нього отримати доступ.
Інші конфігурації:
ConfigMap: Ви можете налаштувати URL-адреси для доступу до служб. Підсистема отримає дані звідси, щоб знати, як спілкуватися з іншими службами (підсистемами). Зверніть увагу, що це не рекомендоване місце для збереження облікових даних!
Секрет (Secret): Це місце для зберігання секретних даних, таких як паролі, ключі API... закодовані в B64. Підсистема зможе отримати доступ до цих даних для використання необхідних облікових даних.
Розгортання (Deployments): Тут вказуються компоненти, які мають бути запущені Kubernetes. Користувач зазвичай не буде працювати безпосередньо з підсистемами, підсистеми абстраговані в Набори реплік (кількість однакових реплік підсистем), які запускаються через розгортання. Зверніть увагу, що розгортання призначені для безстандартних додатків. Мінімальна конфігурація для розгортання - це ім'я та зображення для запуску.
Набір реплік зі станом (StatefulSet): Цей компонент призначений спеціально для додатків, таких як бази даних, які потребують доступу до одного сховища.
Вхід (Ingress): Це конфігурація, яка використовується для викладення додатка публічно за допомогою URL-адреси. Зверніть увагу, що це також можна зробити за допомогою зовнішніх служб, але це правильний спосіб викладення додатка.
Якщо ви реалізуєте вхід, вам потрібно створити Контролери входу (Ingress Controllers). Контролер входу - це підсистема, яка буде кінцевою точкою, яка отримає запити, перевірить їх та розподілить навантаження на служби. контролер входу надсилатиме запити на основі налаштованих правил входу. Зверніть увагу, що правила входу можуть вказувати на різні шляхи або навіть піддомени до різних внутрішніх служб Kubernetes.
Кращою практикою з точки зору безпеки буде використання хмарного балансувальника навантаження або проксі-сервера як точки входу, щоб не мати жодної частини кластера Kubernetes відкритою.
Коли отримано запит, який не відповідає жодному правилу входу, контролер входу направить його до "Стандартного фонового процесу". Ви можете використовувати
describe
, щоб отримати адресу цього параметра.minikube addons enable ingress
Інфраструктура PKI - Центр сертифікації CA:
![](https://cloud.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2Fsickrov.github.io%2Fmedia%2FScreenshot-66.jpg&width=768&dpr=4&quality=100&sign=ddfcd3be&sv=1)
CA є довіреним коренем для всіх сертифікатів всередині кластера.
Дозволяє компонентам перевіряти один одного.
Усі сертифікати кластера підписані CA.
ETCd має власний сертифікат.
Типи:
сертифікат apiserver.
сертифікат kubelet.
сертифікат планувальника.
Основні дії
Minikube
Minikube може бути використаний для проведення швидких тестів на Kubernetes без необхідності розгортання всього середовища Kubernetes. Він буде запускати процеси майстра та вузла на одній машині. Minikube буде використовувати virtualbox для запуску вузла. Див. тут, як його встановити.
Основи Kubectl
Kubectl
- це інструмент командного рядка для кластерів Kubernetes. Він взаємодіє з Api-сервером основного процесу для виконання дій в Kubernetes або для запиту даних.
Інформаційна панель Minikube
Інформаційна панель дозволяє вам легше бачити, що запущено в minikube, ви можете знайти URL для доступу до неї за посиланням:
Приклади файлів конфігурації YAML
Кожен файл конфігурації має 3 частини: метадані, специфікація (що потрібно запустити), стан (бажаний стан). У межах специфікації файлу конфігурації розгортання можна знайти шаблон, визначений новою структурою конфігурації, що визначає зображення для запуску:
Приклад розгортання + Сервіс, визначені в одному файлі конфігурації (з тут)
Оскільки сервіс зазвичай пов'язаний з одним розгортанням, можна визначити обидва в одному файлі конфігурації (сервіс, визначений у цьому конфігураційному файлі, доступний лише в межах системи):
Приклад конфігурації зовнішнього сервісу
Цей сервіс буде доступний зовні (перевірте атрибути nodePort
та type: LoadBlancer
):
Це корисно для тестування, але для продакшну вам слід мати лише внутрішні сервіси та Ingress для викладення додатку.
Приклад файлу конфігурації Ingress
Це дозволить викласти додаток за адресою http://dashboard.com
.
Приклад файлу конфігурації секретів
Зверніть увагу, як паролі закодовані у B64 (що не є безпечним!)
Приклад ConfigMap
ConfigMap - це конфігурація, яка надається капсулам, щоб вони знали, як знаходити та отримувати доступ до інших служб. У цьому випадку кожна капсула буде знати, що ім'я mongodb-service
є адресою капсули, з якою вони можуть спілкуватися (ця капсула буде виконувати mongodb):
Потім, всередині конфігурації розгортання цю адресу можна вказати наступним чином, щоб вона завантажувалася всередині середовища контейнера:
Приклад конфігурації обсягу
Ви можете знайти різні приклади файлів конфігурації зберігання у форматі yaml за посиланням https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes. Зверніть увагу, що обсяги не знаходяться всередині просторів імен
Простори імен
Kubernetes підтримує кілька віртуальних кластерів, що базуються на одному фізичному кластері. Ці віртуальні кластери називаються просторами імен. Вони призначені для використання в середовищах з великою кількістю користувачів, розподілених по різним командам або проектам. Для кластерів з кількома десятками користувачів вам не потрібно створювати або думати про простори імен. Ви повинні почати використовувати простори імен лише для кращого контролю та організації кожної частини додатку, розгорнутого в Kubernetes.
Простори імен надають область для імен. Імена ресурсів повинні бути унікальними всередині простору імен, але не між просторами імен. Простори імен не можуть бути вкладені один в одного, і кожний ресурс Kubernetes може бути лише в одному просторі імен.
За замовчуванням є 4 простори імен, якщо ви використовуєте minikube:
kube-system: Це не призначено для використання користувачами і ви не повинні до нього торкатися. Це для процесів майстра та kubectl.
kube-public: Глобально доступні дані. Містить configmap, який містить інформацію про кластер.
kube-node-lease: Визначає доступність вузла.
default: Простір імен, який користувач використовуватиме для створення ресурсів.
Зверніть увагу, що більшість ресурсів Kubernetes (наприклад, pods, services, replication controllers та інші) знаходяться в деяких просторах імен. Однак інші ресурси, такі як ресурси простору імен та ресурси низького рівня, такі як вузли та постійні обсяги, не знаходяться в просторі імен. Щоб переглянути, які ресурси Kubernetes знаходяться в просторі імен, а які - ні:
Ви можете зберегти простір імен для всіх наступних команд kubectl в цьому контексті.
Helm
Helm - це менеджер пакетів для Kubernetes. Він дозволяє упаковувати файли YAML та розповсюджувати їх у публічних та приватних репозиторіях. Ці пакети називаються Helm Charts.
Kubernetes секрети
Секрет - це об'єкт, який містить конфіденційні дані, такі як пароль, токен або ключ. Таку інформацію можна було б вказати в специфікації Pod або в зображенні. Користувачі можуть створювати секрети, і система також створює секрети. Ім'я об'єкта Secret повинно бути дійсним ім'ям DNS-піддомену. Прочитайте тут офіційну документацію.
Секрети можуть бути такими речами як:
API, SSH ключі.
Токени OAuth.
Облікові дані, паролі (звичайний текст або b64 + шифрування).
Інформація або коментарі.
Код підключення до бази даних, рядки... .
Є різні типи секретів в Kubernetes
Вбудований Тип | Використання |
---|---|
Opaque | довільні дані, визначені користувачем (За замовчуванням) |
kubernetes.io/service-account-token | токен облікового запису служби |
kubernetes.io/dockercfg | серіалізований файл ~/.dockercfg |
kubernetes.io/dockerconfigjson | серіалізований файл ~/.docker/config.json |
kubernetes.io/basic-auth | облікові дані для базової аутентифікації |
kubernetes.io/ssh-auth | облікові дані для SSH аутентифікації |
kubernetes.io/tls | дані для TLS клієнта або сервера |
bootstrap.kubernetes.io/token | дані токена завантаження |
Тип Opaque є типом за замовчуванням, типова пара ключ-значення, визначена користувачем.
Як працюють секрети:
![](https://cloud.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2Fsickrov.github.io%2Fmedia%2FScreenshot-164.jpg&width=768&dpr=4&quality=100&sign=407ce89f&sv=1)
Наступний файл конфігурації визначає секрет з ім'ям mysecret
з 2 парами ключ-значення username: YWRtaW4=
та password: MWYyZDFlMmU2N2Rm
. Також він визначає под з ім'ям secretpod
, який матиме username
та password
, визначені в mysecret
, викладені в змінних середовища SECRET_USERNAME
та SECRET_PASSWOR
. Також він також підключить секрет username
всередині mysecret
за шляхом /etc/foo/my-group/my-username
з дозволами 0640
.
Секрети в etcd
etcd - це послідовний та високодоступний сховище ключ-значення, яке використовується як сховище даних кластера Kubernetes. Давайте отримаємо доступ до секретів, збережених в etcd:
Ви побачите сертифікати, ключі та URL-адреси, які знаходяться в файловій системі. Як тільки ви отримаєте цю інформацію, ви зможете підключитися до etcd.
Після встановлення зв'язку ви зможете отримати секрети:
Додавання шифрування до ETCD
За замовчуванням всі секрети зберігаються у відкритому тексті всередині etcd, якщо ви не застосуєте шар шифрування. Наведений нижче приклад базується на https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
Після цього вам потрібно встановити прапор --encryption-provider-config
на kube-apiserver
, щоб вказати місце розташування створеного файлу конфігурації. Ви можете змінити /etc/kubernetes/manifest/kube-apiserver.yaml
та додати наступні рядки:
Прокрутіть вниз у розділі volumeMounts:
Прокрутіть вниз у volumeMounts до hostPath:
Перевірка шифрування даних
Дані шифруються при записі в etcd. Після перезапуску вашого kube-apiserver
, будь-який новостворений або оновлений секрет повинен бути зашифрованим при зберіганні. Для перевірки ви можете використовувати командний рядок програми etcdctl
, щоб отримати вміст вашого секрету.
Створіть новий секрет під назвою
secret1
в просторі іменdefault
:
Використовуючи командний рядок etcdctl, прочитайте цей секрет з etcd:
ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C
де [...]
повинні бути додаткові аргументи для підключення до сервера etcd. 3. Перевірте, що збережений секрет починається з k8s:enc:aescbc:v1:
, що вказує на те, що провайдер aescbc
зашифрував отримані дані. 4. Перевірте, що секрет правильно розшифровується при отриманні через API:
повинно відповідати mykey: bXlkYXRh
, mydata закодовано, перевірте розкодування секрету, щоб повністю розкодувати секрет.
Оскільки секрети шифруються при записі, виконання оновлення секрету зашифрує вміст:
Останні поради:
Спробуйте не зберігати секрети в файловій системі, отримуйте їх з інших місць.
Перевірте https://www.vaultproject.io/ для додаткового захисту ваших секретів.
Посилання
Вивчайте та практикуйте хакінг AWS:Навчання HackTricks AWS Red Team Expert (ARTE)
Вивчайте та практикуйте хакінг GCP:
Навчання HackTricks GCP Red Team Expert (GRTE)
Last updated