Деталі реалізації
Kubernetes v1.10 [stable]
kubeadm init
та kubeadm join
разом забезпечують гарну послідовність дій користувача для створення базового кластера Kubernetes з нуля, відповідно до найкращих практик. Однак може бути не очевидно, як kubeadm це робить.
Цей документ надає додаткову інформацію про те, що відбувається за лаштунками, з метою поширення знань про найкращі практики для кластера Kubernetes.
Основні принципи дизайну
Кластер, який налаштовується за допомогою kubeadm init
та kubeadm join
, має бути:
- Захищеним: Він повинен дотримуватися останніх найкращих практик, таких як:
- забезпечення RBAC
- використання Node Authorizer
- використання захищеного зв’язку між компонентами панелі управління
- використання захищеного зв’язку між API-сервером і kubelet-ами
- обмеження доступу до API kubelet-а
- обмеження доступу до API для системних компонентів, таких як kube-proxy та CoreDNS
- обмеження доступу до того, що може отримати Bootstrap Token
- Зручним для користувачів: Користувачеві не повинно знадобитися виконувати більше, ніж кілька команд:
kubeadm init
export KUBECONFIG=/etc/kubernetes/admin.conf
kubectl apply -f <network-of-choice.yaml>
kubeadm join --token <token> <endpoint>:<port>
- Розширюваним:
- Він не повинен віддавати перевагу жодному конкретному мережевому провайдеру. Налаштування мережі кластерів не входить до сфери компетенції
- Він повинен надавати можливість використовувати конфігураційний файл для налаштування різних параметрів
Константи та добре відомі значення та шляхи
Щоб зменшити складність і спростити розробку вищого рівня інструментів, що будуються на основі kubeadm, він використовує обмежений набір констант для добре відомих шляхів та імен файлів.
Тека Kubernetes /etc/kubernetes
є константою в застосунку, оскільки вона є очевидним шляхом у більшості випадків і найінтуїтивнішим розташуванням; інші константні шляхи та імена файлів є такими:
/etc/kubernetes/manifests
як шлях, де kubelet повинен шукати маніфести статичних Podʼів. Імена маніфестів статичних Podʼів:etcd.yaml
kube-apiserver.yaml
kube-controller-manager.yaml
kube-scheduler.yaml
/etc/kubernetes/
як шлях, де зберігаються файли kubeconfig з ідентифікаторами для компонентів панелі управління. Імена файлів kubeconfig:kubelet.conf
(bootstrap-kubelet.conf
під час TLS bootstrap)controller-manager.conf
scheduler.conf
admin.conf
для адміністратора кластера і kubeadmsuper-admin.conf
для супер-адміністратора кластера, який може обходити RBAC
Імена сертифікатів і ключових файлів:
ca.crt
,ca.key
для центру авторизації Kubernetesapiserver.crt
,apiserver.key
для сертифіката API-сервераapiserver-kubelet-client.crt
,apiserver-kubelet-client.key
для клієнтського сертифіката, що використовується API-сервером для безпечного підключення до kubelet-івsa.pub
,sa.key
для ключа, який використовується менеджером контролерів при підписанні ServiceAccountfront-proxy-ca.crt
,front-proxy-ca.key
для центру авторизації front-проксіfront-proxy-client.crt
,front-proxy-client.key
для клієнта front-проксі
Внутрішній дизайн робочого процесу kubeadm init
Команда kubeadm init
складається з послідовності атомарних завдань для виконання, як описано в внутрішньому робочому процесі kubeadm init
.
Команда kubeadm init phase
дозволяє користувачам викликати кожне завдання окремо, і в кінцевому підсумку пропонує багаторазовий і компонований API/інструментарій, який може бути використаний іншими інструментами початкового завантаження Kubernetes, будь-яким інструментом автоматизації ІТ або досвідченим користувачем для створення власних кластерів.
Перевірка перед установкою (Preflight checks)
Kubeadm виконує набір перевірок перед початком ініціалізації з метою перевірки передумов і уникнення типових проблем під час запуску кластера.
Користувач може пропустити певні перевірки перед установкою або всі за допомогою опції --ignore-preflight-errors
.
- [Попередження], якщо версія Kubernetes, яку слід використовувати (вказана за допомогою прапорця
--kubernetes-version
), є хоча б на одну мінорну версію вищою за версію kubeadm CLI. - Вимоги до системи Kubernetes:
- якщо використовується Linux:
- [Помилка], якщо версія ядра старіша за мінімально необхідну версію
- [Помилка], якщо не налаштовані необхідні підсистеми cgroups
- якщо використовується Linux:
- [Помилка], якщо точка доступу CRI не відповідає
- [Помилка], якщо користувач не є root
- [Помилка], якщо імʼя машини не є дійсним DNS-піддоменом
- [Попередження], якщо імʼя хосту неможливо знайти через мережевий пошук
- [Помилка], якщо версія kubelet нижча за мінімальну підтримувану версію kubelet, підтримувану kubeadm (поточна мінорна версія -1)
- [Помилка], якщо версія kubelet хоча б на одну мінорну версію вища за необхідну версію панелі управління (непідтримуване відхилення версій)
- [Попередження], якщо служба kubelet не існує або вона вимкнена
- [Попередження], якщо активний firewalld
- [Помилка], якщо використовується порт привʼязки API-сервера або порти 10250/10251/10252
- [Помилка], якщо тека
/etc/kubernetes/manifests
вже існує і не є порожньою - [Помилка], якщо включений swap
- [Помилка], якщо команди
conntrack
,ip
,iptables
,mount
,nsenter
відсутні в шляху до команд - [Попередження], якщо команди
ebtables
,ethtool
,socat
,tc
,touch
,crictl
відсутні в шляху до команд - [Попередження], якщо додаткові аргументи для API-сервера, менеджера контролерів, планувальника містять недійсні параметри
- [Попередження], якщо зʼєднання з https://API.AdvertiseAddress:API.BindPort пройде через проксі
- [Попередження], якщо зʼєднання з підмережею сервісів пройде через проксі (перевіряється лише перша адреса)
- [Попередження], якщо зʼєднання з підмережею Podʼів пройде через проксі (перевіряється лише перша адреса)
- Якщо використовується зовнішній etcd:
- [Помилка], якщо версія etcd старіша за мінімально необхідну версію
- [Помилка], якщо сертифікати або ключі etcd вказані, але не надані
- Якщо використовується внутрішній etcd (і, таким чином, буде встановлений локальний etcd):
- [Помилка], якщо використовується порт 2379
- [Помилка], якщо тека Etcd.DataDir вже існує і не є порожньою
- Якщо режим авторизації — ABAC:
- [Помилка], якщо abac_policy.json не існує
- Якщо режим авторизації — WebHook:
- [Помилка], якщо webhook_authz.conf не існує
Примітка:
Перевірки перед установкою можна викликати індивідуально за допомогою командиkubeadm init phase preflight
.Генерація необхідних сертифікатів
Kubeadm генерує пари сертифікатів і приватних ключів для різних цілей:
Самопідписаний центр сертифікації для кластера Kubernetes, збережений у файлі
ca.crt
і приватний ключ у файліca.key
Сертифікат обслуговування для API-сервера, згенерований за допомогою
ca.crt
як CA, збережений у файліapiserver.crt
разом із приватним ключемapiserver.key
. Цей сертифікат повинен містити наступні альтернативні імена:- Внутрішній clusterIP сервісу Kubernetes (перша адреса в CIDR служб, наприклад,
10.96.0.1
, якщо підмережа сервісів —10.96.0.0/12
) - DNS-імена Kubernetes, наприклад
kubernetes.default.svc.cluster.local
, якщо значення прапорця--service-dns-domain
єcluster.local
, а також типові DNS-іменаkubernetes.default.svc
,kubernetes.default
,kubernetes
- Імʼя вузла (node-name)
--apiserver-advertise-address
- Додаткові альтернативні імена, вказані користувачем
- Внутрішній clusterIP сервісу Kubernetes (перша адреса в CIDR служб, наприклад,
Клієнтський сертифікат для API-сервера для безпечного підключення до kubelet-ів, згенерований за допомогою
ca.crt
як CA і збережений у файліapiserver-kubelet-client.crt
разом із його приватним ключемapiserver-kubelet-client.key
. Цей сертифікат повинен бути в організаціїsystem:masters
Приватний ключ для підпису токенів ServiceAccount, збережений у файлі
sa.key
разом із його публічним ключемsa.pub
Центр сертифікації для front proxy, збережений у файлі
front-proxy-ca.crt
разом із його ключемfront-proxy-ca.key
Клієнтський сертифікат для клієнта front proxy, згенерований за допомогою
front-proxy-ca.crt
як CA і збережений у файліfront-proxy-client.crt
разом із його приватним ключемfront-proxy-client.key
Сертифікати зберігаються типово у /etc/kubernetes/pki
, але цю теку можна налаштувати за допомогою прапорця --cert-dir
.
Зверніть увагу на наступне:
- Якщо дані пари сертифікат-приватний ключ вже існують і їх зміст відповідає вищезазначеним вимогам, вони будуть використані, і фаза генерації для даного сертифіката буде пропущена. Це означає, що користувач може, наприклад, скопіювати поточний CA в
/etc/kubernetes/pki/ca.{crt,key}
, і після цього kubeadm використовуватиме ці файли для підпису інших сертифікатів. Див. також використання власних сертифікатів - Для CA можливо надати файл
ca.crt
, але не надавати файлca.key
. Якщо всі інші сертифікати і файли kubeconfig вже на місці, kubeadm визнає цю умову і активує ExternalCA, що також означає, що контролерcsrsigner
в контролері-менеджері не буде запущений - Якщо kubeadm працює в режимі зовнішньої CA; всі сертифікати повинні бути надані користувачем, оскільки kubeadm не може їх генерувати самостійно
- У випадку запуску kubeadm у режимі
--dry-run
, файли сертифікатів записуються в тимчасову теку - Генерацію сертифікатів можна викликати окремо за допомогою команди
kubeadm init phase certs all
It seems like you're referring to documentation or a detailed guide on how kubeadm
handles various aspects of Kubernetes initialization and configuration. If you need a translation of this content into Ukrainian, I can provide that. Here's the translation:
Генерація kubeconfig файлів для компонентів панелі управління
Kubeadm генерує kubeconfig файли з ідентичностями для компонентів панелі управління:
Файл kubeconfig для kubelet, який використовується під час ініціалізації TLS —
/etc/kubernetes/bootstrap-kubelet.conf
. У цьому файлі є bootstrap-token або вбудовані клієнтські сертифікати для автентифікації цього вузла у кластері.Цей клієнтський сертифікат повинен:
- Бути в організації
system:nodes
, як вимагається модулем Node Authorization - Мати Загальне Імʼя (CN)
system:node:<hostname-lowercased>
- Бути в організації
Файл kubeconfig для контролера-менеджера,
/etc/kubernetes/controller-manager.conf
; у цьому файлі вбудований клієнтський сертифікат з ідентичністю контролера-менеджера. Цей клієнтський сертифікат повинен мати CNsystem:kube-controller-manager
, як визначено стандартними RBAC ролями ядра компонентівФайл kubeconfig для планувальника,
/etc/kubernetes/scheduler.conf
; у цьому файлі вбудований клієнтський сертифікат з ідентичністю планувальника. Цей клієнтський сертифікат повинен мати CNsystem:kube-scheduler
, як визначено стандартними RBAC ролями ядра компонентів
Додатково, kubeconfig файл для kubeadm як адміністративної сутності генерується і зберігається у /etc/kubernetes/admin.conf
. Цей файл включає сертифікат з Subject: O = kubeadm:cluster-admins, CN = kubernetes-admin
. kubeadm:cluster-admins
— це група, керована kubeadm. Вона повʼязана з cluster-admin
ClusterRole під час kubeadm init
, за допомогою super-admin.conf
файлу, який не потребує RBAC. Файл admin.conf
повинен залишатися на вузлах панелі управління і не повинен бути переданий іншим користувачам.
Під час kubeadm init
генерується інший kubeconfig файл і зберігається у /etc/kubernetes/super-admin.conf
. Цей файл включає сертифікат з Subject: O = system:masters, CN = kubernetes-super-admin
. system:masters
— це суперкористувачі, які обходять RBAC і роблять super-admin.conf
корисним у випадку надзвичайної ситуації, коли кластер заблокований через неправильну конфігурацію RBAC. Файл super-admin.conf
повинен зберігатися в безпечному місці і не повинен передаватися іншим користувачам.
Дивіться RBAC user facing role bindings для додаткової інформації про RBAC і вбудовані ClusterRoles та групи.
Зверніть увагу на наступне:
- Всі kubeconfig файли включають в себе сертифікат
ca.crt
. - Якщо вказаний kubeconfig файл вже існує і його зміст відповідає вищезазначеним вимогам, то буде використано існуючий файл, і фаза генерації для даного kubeconfig буде пропущена.
- Якщо kubeadm працює в режимі ExternalCA mode, всі необхідні kubeconfig файли також повинні бути надані користувачем, оскільки kubeadm не може згенерувати їх самостійно.
- У випадку виконання kubeadm в режимі
--dry-run
, файли kubeconfig записуються в тимчасову теку. - Генерацію kubeconfig файлів можна викликати окремо за допомогою команди
kubeadm init phase kubeconfig all
Генерація маніфестів статичних Pod для компонентів панелі управління
Kubeadm записує файли маніфестів статичних Pod для компонентів панелі управління до /etc/kubernetes/manifests
. kubelet спостерігає за цією текою для створення Podʼів при запуску.
Маніфести статичних Podʼів мають спільний набір властивостей:
Всі статичні Podʼи розгорнуті в просторі імен
kube-system
Всі статичні Podʼи мають мітки
tier:control-plane
таcomponent:{імʼя-компоненти}
Всі статичні Podʼи використовують клас пріоритету
system-node-critical
На всіх статичних Podʼах встановлено
hostNetwork: true
, щоб дозволити запуск панелі управління до налаштування мережі; в результаті:- Адреса, яку використовує контролер-менеджер та планувальник для посилання на API-сервер, є
127.0.0.1
- Якщо сервер etcd налаштовано локально, адреса
etcd-server
буде встановлена як127.0.0.1:2379
- Адреса, яку використовує контролер-менеджер та планувальник для посилання на API-сервер, є
Включено обрання лідера як для контролер-менеджера, так і для планувальника
Контролер-менеджер та планувальник будуть посилатися на файли kubeconfig з їхніми відповідними, унікальними ідентифікаторами
Всі статичні Podʼи отримують будь-які додаткові прапорці, вказані користувачем, як описано в передача користувацьких аргументів компонентам панелі управління
Всі статичні Podʼи отримують будь-які додаткові томи, вказані користувачем (Шлях хоста)
Зверніть увагу, що:
- Усі образи типово будуть витягуватися з registry.k8s.io. Для налаштування репозиторію образів див. використання власних образів
- У разі виконання kubeadm у режимі
--dry-run
файли статичних Podʼів записуються у тимчасову теку - Генерацію маніфестів статичних Podʼів для компонентів панелі управління можна запустити окремо за допомогою команди
kubeadm init phase control-plane all
Сервер API
Маніфест статичних Podʼів для сервера API обробляється наступними параметрами, наданими користувачами:
apiserver-advertise-address
таapiserver-bind-port
для звʼязку; якщо вони не вказані, стандартне значення буде IP-адреса основного мережевого інтерфейсу на машині та порт 6443service-cluster-ip-range
для використання сервісів- Якщо вказаний зовнішній сервер etcd, то
etcd-servers
та повʼязані налаштування TLS (etcd-cafile
,etcd-certfile
,etcd-keyfile
); якщо зовнішній сервер etcd не вказано, буде використовуватися локальний etcd (через мережу хосту) - Якщо вказаний провайдер хмарних послуг, то налаштовується відповідний параметр
--cloud-provider
разом зі шляхом--cloud-config
, якщо такий файл існує (експериментально, альфа версія, буде вилучено в майбутній версії)
Інші прапорці сервера API, що встановлені безумовно, включають:
--insecure-port=0
для уникнення небезпечних зʼєднань з сервером API--enable-bootstrap-token-auth=true
для активації модуля автентифікаціїBootstrapTokenAuthenticator
. Див. TLS Bootstrapping для деталей--allow-privileged
доtrue
(необхідно, наприклад, для kube-proxy)--requestheader-client-ca-file
доfront-proxy-ca.crt
--enable-admission-plugins
до:NamespaceLifecycle
наприклад, для уникнення видалення системних зарезервованих просторів іменLimitRanger
таResourceQuota
для встановлення обмежень на простори іменServiceAccount
для автоматизації службових облікових записівPersistentVolumeLabel
приєднує мітки регіону або зони до PersistentVolumes, як визначено провайдером хмарних послуг (Цей контролер допуску є застарілим і буде вилучений у майбутній версії. Він типово не розгорнутий kubeadm починаючи з v1.9, якщо явно не вибрано використанняgce
абоaws
як провайдерів хмарних послуг)DefaultStorageClass
для встановлення типового класу зберігання на обʼєктахPersistentVolumeClaim
DefaultTolerationSeconds
NodeRestriction
для обмеження того, що kubelet може змінювати (наприклад, тільки Podʼи на цьому вузлі)
--kubelet-preferred-address-types
доInternalIP,ExternalIP,Hostname;
це робитьkubectl logs
та іншу комунікацію API server-kubelet працюючою в середовищах, де імена хостів вузлів не розвʼязуютьсяПрапорці для використання сертифікатів, згенерованих на попередніх етапах:
--client-ca-file
доca.crt
--tls-cert-file
доapiserver.crt
--tls-private-key-file
доapiserver.key
--kubelet-client-certificate
доapiserver-kubelet-client.crt
--kubelet-client-key
доapiserver-kubelet-client.key
--service-account-key-file
доsa.pub
--requestheader-client-ca-file
доfront-proxy-ca.crt
--proxy-client-cert-file
доfront-proxy-client.crt
--proxy-client-key-file
доfront-proxy-client.key
Інші прапорці для забезпечення безпеки front proxy (Агрегація API) комунікацій:
--requestheader-username-headers=X-Remote-User
--requestheader-group-headers=X-Remote-Group
--requestheader-extra-headers-prefix=X-Remote-Extra-
--requestheader-allowed-names=front-proxy-client
Менеджер контролерів
Маніфест статичного Podʼа для менеджера контролерів обробляється наступними параметрами, наданими користувачами:
Якщо kubeadm запускається з вказанням
--pod-network-cidr
, активується функція менеджера підмережі, необхідна для деяких мережевих втулків CNI, встановлюючи:--allocate-node-cidrs=true
- Прапорці
--cluster-cidr
та--node-cidr-mask-size
відповідно до заданого CIDR
Якщо вказаний провайдер хмарних послуг, то відповідно налаштовується
--cloud-provider
, разом зі шляхом--cloud-config
, якщо такий файл конфігурації існує (експериментально, альфа версія, буде вилучено в майбутній версії)
Інші прапорці, які встановлюються безумовно, включають:
--controllers
, що активує всі стандартні контролери плюс контролериBootstrapSigner
таTokenCleaner
для TLS-запуску. Див. TLS Bootstrapping для деталей.--use-service-account-credentials
доtrue
Прапорці для використання сертифікатів, згенерованих на попередніх етапах:
--root-ca-file
доca.crt
--cluster-signing-cert-file
доca.crt
, якщо відключений зовнішній режим CA, в іншому випадку до""
--cluster-signing-key-file
доca.key
, якщо відключений зовнішній режим CA, в іншому випадку до""
--service-account-private-key-file
доsa.key
.
Планувальник
Маніфест статичного Podʼа для планувальника обробляється наступними параметрами, наданими користувачами.
Генерація маніфесту статичного Pod для локального etcd
Якщо ви вказали зовнішній etcd, цей крок буде пропущено. В іншому випадку kubeadm генерує маніфест статичного Pod для створення локального екземпляра etcd, що працює в Pod з наступними характеристиками:
- слухати на
localhost:2379
і використовуватиHostNetwork=true
- зробити монтування
hostPath
зdataDir
до файлової системи хосту - Будь-які додаткові прапорці, вказані користувачем
Зверніть увагу, що:
- Образ контейнера etcd буде типово витягнутий з
registry.gcr.io
. Для налаштування власного репозиторію образів див. використання власних образів. - Якщо ви запускаєте kubeadm у режимі
--dry-run
, маніфест статичного Pod для etcd записується у тимчасову теку. - Ви можете безпосередньо викликати генерацію маніфесту статичного Pod для локального etcd за допомогою команди
kubeadm init phase etcd local
.
Очікування запуску панелі управління
kubeadm очікує (до 4 хвилин) на відповідь ok
від localhost:6443/healthz
(життєздатність kube-apiserver). Однак, для виявлення умов блокування, kubeadm швидко видає помилку, якщо localhost:10255/healthz
(життєздатність kubelet) або localhost:10255/healthz/syncloop
(готовність kubelet) не повертають ok
в межах відповідно 40 та 60 секунд.
kubeadm покладається на kubelet для завантаження образів панелі управління і їх коректного запуску як статичних Podʼів. Після того як панель управління буде запущена, kubeadm завершує виконання завдань, описаних у наступних розділах.
Збереження конфігурації кластера kubeadm у ConfigMap для подальшого посилання
kubeadm зберігає конфігурацію, передану в kubeadm init
, у ConfigMap з назвою kubeadm-config
в просторі імен kube-system
.
Це забезпечить можливість kubeadm у майбутньому (наприклад, під час оновлення kubeadm upgrade
) визначати фактичний поточний стан кластера і приймати нові рішення на основі цих даних.
Зверніть увагу, що:
- Перед збереженням конфігурації кластера чутлива інформація, така як токен, видаляється з конфігурації.
- Завантаження конфігурації вузла панелі управління може бути викликане окремо за допомогою команди
kubeadm init phase upload-config
.
Позначення вузла як вузла панелі управління
Як тільки панель управління буде доступна, kubeadm виконує наступні дії:
- Позначає вузол як вузол панелі управління з міткою
node-role.kubernetes.io/control-plane=""
- Додає на вузол taint
node-role.kubernetes.io/control-plane:NoSchedule
Зверніть увагу, що фазу позначення вузла як вузла панелі управління можна викликати окремо за допомогою команди kubeadm init phase mark-control-plane
.
Налаштування TLS-Bootstrapping для приєднання вузлів
Kubeadm використовує Автентифікацію за допомогою Запускових Токенів для приєднання нових вузлів до існуючого кластера; для отримання більш детальної інформації дивіться також пропозицію дизайну.
kubeadm init
забезпечує належну конфігурацію всього процесу, включаючи наступні кроки, а також налаштування прапорців API-сервера та контролера, як вже було описано у попередніх розділах.
Примітка:
TLS-запуск для вузлів можна налаштувати за допомогою командиkubeadm init phase bootstrap-token
, виконуючи всі кроки налаштування, описані в наступних розділаї; альтернативно, кожен крок може бути викликаний окремо.Створення bootstrap токена
kubeadm init
створює перший bootstrap токен, що генерується автоматично або надається користувачем за допомогою прапорця --token
. Згідно з документацією щодо специфікації bootstrap токена, токен слід зберегти як секрет з іменем bootstrap-token-<token-id>
у просторі імен kube-system
.
Зверніть увагу, що:
- bootstrap токен, типово створений
kubeadm init
, використовуватиметься для перевірки тимчасових користувачів під час процесу TLS-запуску; ці користувачі будуть членами групиsystem:bootstrappers:kubeadm:default-node-token
. - Токен має обмежену чинність, стандартно 24 години (цей інтервал можна змінити за допомогою прапорця
--token-ttl
). - Додаткові токени можна створити за допомогою команди
kubeadm token
, яка також надає інші корисні функції для управління токенами.
Дозвіл на виклик API CSR вузлами, які приєднуються
Kubeadm забезпечує можливість користувачам у групі system:bootstrappers:kubeadm:default-node-token
доступ до API підпису сертифікатів.
Це реалізується створенням ClusterRoleBinding з назвою kubeadm:kubelet-bootstrap
між вищезазначеною групою та рольовим доступом RBAC стандартно system:node-bootstrapper
.
Налаштування автоматичного схвалення нових bootstrap токенів
Kubeadm забезпечує автоматичне схвалення запитів на підпис сертифікату Bootstrap Token за допомогою контролера csrapprover.
Це реалізується створенням ClusterRoleBinding з назвою kubeadm:node-autoapprove-bootstrap
між групою system:bootstrappers:kubeadm:default-node-token
та стандартним рольовим доступом system:certificates.k8s.io:certificatesigningrequests:nodeclient
.
Роль system:certificates.k8s.io:certificatesigningrequests:nodeclient
також має бути створена, надаючи дозвіл POST на шлях /apis/certificates.k8s.io/certificatesigningrequests/nodeclient
.
Налаштування ротації сертифікатів вузлів з автоматичним схваленням
Kubeadm забезпечує активацію ротації сертифікатів для вузлів і автоматичне схвалення запитів на підпис сертифікатів для вузлів за допомогою контролера csrapprover.
Це реалізується створенням ClusterRoleBinding з назвою kubeadm:node-autoapprove-certificate-rotation
між групою system:nodes
та стандартним рольовим доступом system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
.
Створення публічного ConfigMap cluster-info
У цій фазі створюється ConfigMap cluster-info
у просторі імен kube-public
.
Додатково створюється Role та RoleBinding, які надають доступ до ConfigMap неавтентифікованим користувачам (тобто користувачам у RBAC групі system:unauthenticated
).
Примітка:
Доступ до ConfigMapcluster-info
не обмежується за швидкістю. Це може бути проблемою, якщо ваш API-сервер кластера відкритий для інтернету; у найгіршому випадку може виникнути атака типу DoS, коли атакуючий використовує всі вхідні запити, які може обробити kube-apiserver, щоб обслуговувати ConfigMap cluster-info
.Встановлення надбудов
Kubeadm встановлює внутрішній DNS-сервер і компоненти надбудов kube-proxy через API-сервер.
Примітка:
Цю фазу можна викликати окремо за допомогою командиkubeadm init phase addon all
.proxy
Для kube-proxy
створюється обліковий запис ServiceAccount у просторі імен kube-system
, після чого kube-proxy
розгортається як DaemonSet:
- Облікові дані (
ca.crt
таtoken
) до панелі управління отримуються з облікового запису ServiceAccount. - Місцезнаходження (URL) API-сервера отримується з ConfigMap.
- Обліковий запис ServiceAccount
kube-proxy
повʼязується з правами у рольовому доступі ClusterRolesystem:node-proxier
.
DNS
Сервіс CoreDNS називається
kube-dns
. Це зроблено для запобігання будь-яких перерв у роботі, коли користувач переключає DNS кластера з kube-dns на CoreDNS за допомогою методу--config
, описаного тут.У просторі імен
kube-system
створюється обліковий запис ServiceAccount для CoreDNS.Обліковий запис
coredns
привʼязаний до привілеїв у ClusterRolesystem:coredns
.
У версії Kubernetes 1.21 була видалена підтримка використання kube-dns
з kubeadm. Ви можете використовувати CoreDNS з kubeadm, навіть якщо повʼязаний сервіс називається kube-dns
.
Внутрішній дизайн фаз kubeadm join
Подібно до kubeadm init
, внутрішній робочий процес kubeadm join
також складається з послідовності атомарних завдань, що виконуються.
Вони поділені на дві частини: виявлення (щоб вузол довіряв Kubernetes Master) та початкове завантаження TLS (щоб Kubernetes Master довіряв вузлу).
Дивіться Автентифікація за допомогою Bootstrap Tokens або відповідну пропозицію дизайну.
Попередні перевірки
kubeadm
виконує набір попередніх перевірок перед початком приєднання, з метою перевірити попередні умови та уникнути поширених проблем запуску кластера.
Зверніть увагу на наступне:
- Попередні перевірки
kubeadm join
є, по суті, підмножиною попередніх перевірокkubeadm init
. - Починаючи з версії 1.24, kubeadm використовує crictl для спілкування з усіма відомими CRI точками доступу.
- Починаючи з версії 1.9, kubeadm забезпечує підтримку приєднання вузлів, що працюють на Windows; у такому разі пропускаються специфічні для Linux перевірки.
- У будь-якому випадку користувач може пропустити певні попередні перевірки (або, врешті-решт, усі попередні перевірки) за допомогою опції
--ignore-preflight-errors
.
Виявлення інформації про кластер
Є дві основні схеми для виявлення. Перша полягає у використанні спільного токена разом з IP-адресою сервера API. Друга — наданні файлу (який є підмножиною стандартного файлу kubeconfig).
Виявлення спільного токена
Якщо kubeadm join
викликається з параметром --discovery-token
, використовується виявлення за допомогою токена; у цьому випадку вузол основному отримує сертифікати CA кластера з ConfigMap cluster-info
у просторі імен kube-public
.
Щоб запобігти атакам типу "особа посередині", вживаються кілька заходів:
Спочатку сертифікат CA отримується через небезпечне зʼєднання (це можливо, тому що
kubeadm init
надає доступ користувачамcluster-info
дляsystem:unauthenticated
)Потім сертифікат CA проходить наступні кроки перевірки:
- Базова перевірка: використовуючи ID токена через підпис JWT
- Перевірка публічного ключа: використовуючи наданий
--discovery-token-ca-cert-hash
. Це значення доступне у виводіkubeadm init
або може бути обчислене за допомогою стандартних інструментів (хеш обчислюється над байтами обʼєкта Subject Public Key Info (SPKI) відповідно до RFC7469). Прапор--discovery-token-ca-cert-hash
може бути повторений кілька разів, щоб дозволити більше одного публічного ключа. - Як додаткова перевірка, сертифікат CA отримується через безпечне зʼєднання і порівнюється з сертифікатом CA, отриманим спочатку
Примітка:
Перевірку публічного ключа можна пропустити, передавши прапор--discovery-token-unsafe-skip-ca-verification
; Це послаблює модель безпеки kubeadm, оскільки інші можуть потенційно видавати себе за Kubernetes Master.Виявлення файлу/HTTPS
Якщо kubeadm join
викликається з параметром --discovery-file
, використовується виявлення за допомогою файлу; цей файл може бути локальним файлом або завантаженим через HTTPS URL; у випадку HTTPS, використовується встановлений на хості пакет сертифікатів CA для перевірки зʼєднання.
При виявленні файлу сертифікат CA кластера надається у самому файлі; фактично, файл для виявлення є файлом kubeconfig з встановленими тільки атрибутами server
і certificate-authority-data
, як описано у референс-документації kubeadm join
; коли зʼєднання з кластером встановлено, kubeadm намагається отримати доступ до ConfigMap cluster-info
, і якщо він доступний, використовує його.
TLS Bootstrap
Після того, як інформація про кластер відома, записується файл bootstrap-kubelet.conf
, що дозволяє kubelet виконати початкове завантаження TLS.
Механізм початкового завантаження TLS використовує спільний токен для тимчасової автентифікації з сервером API Kubernetes для подання запиту на підписання сертифіката (CSR) для локально створеної пари ключів.
Запит автоматично затверджується, і операція завершується збереженням файлів ca.crt
і kubelet.conf
, які використовуються kubelet для приєднання до кластера, тоді як bootstrap-kubelet.conf
видаляється.
Примітка:
- Тимчасова автентифікація перевіряється через токен, збережений під час процесу
kubeadm init
(або за допомогою додаткових токенів, створених командоюkubeadm token
) - Тимчасова автентифікація відноситься до користувача, який є членом групи
system:bootstrappers:kubeadm:default-node-token
, якій було надано доступ до API CSR під час процесуkubeadm init
- Автоматичне затвердження CSR управляється контролером csrapprover відповідно до конфігурації, присутньої в процесі
kubeadm init