Деталі реалізації

СТАН ФУНКЦІОНАЛУ: 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 для адміністратора кластера і kubeadm
    • super-admin.conf для супер-адміністратора кластера, який може обходити RBAC
  • Імена сертифікатів і ключових файлів:

    • ca.crt, ca.key для центру авторизації Kubernetes
    • apiserver.crt, apiserver.key для сертифіката API-сервера
    • apiserver-kubelet-client.crt, apiserver-kubelet-client.key для клієнтського сертифіката, що використовується API-сервером для безпечного підключення до kubelet-ів
    • sa.pub, sa.key для ключа, який використовується менеджером контролерів при підписанні ServiceAccount
    • front-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
  • [Помилка], якщо точка доступу 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 генерує пари сертифікатів і приватних ключів для різних цілей:

  • Самопідписаний центр сертифікації для кластера 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
    • Додаткові альтернативні імена, вказані користувачем
  • Клієнтський сертифікат для 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.

Зверніть увагу на наступне:

  1. Якщо дані пари сертифікат-приватний ключ вже існують і їх зміст відповідає вищезазначеним вимогам, вони будуть використані, і фаза генерації для даного сертифіката буде пропущена. Це означає, що користувач може, наприклад, скопіювати поточний CA в /etc/kubernetes/pki/ca.{crt,key}, і після цього kubeadm використовуватиме ці файли для підпису інших сертифікатів. Див. також використання власних сертифікатів
  2. Для CA можливо надати файл ca.crt, але не надавати файл ca.key. Якщо всі інші сертифікати і файли kubeconfig вже на місці, kubeadm визнає цю умову і активує ExternalCA, що також означає, що контролер csrsigner в контролері-менеджері не буде запущений
  3. Якщо kubeadm працює в режимі зовнішньої CA; всі сертифікати повинні бути надані користувачем, оскільки kubeadm не може їх генерувати самостійно
  4. У випадку запуску kubeadm у режимі --dry-run, файли сертифікатів записуються в тимчасову теку
  5. Генерацію сертифікатів можна викликати окремо за допомогою команди 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; у цьому файлі вбудований клієнтський сертифікат з ідентичністю контролера-менеджера. Цей клієнтський сертифікат повинен мати CN system:kube-controller-manager, як визначено стандартними RBAC ролями ядра компонентів

  • Файл kubeconfig для планувальника, /etc/kubernetes/scheduler.conf; у цьому файлі вбудований клієнтський сертифікат з ідентичністю планувальника. Цей клієнтський сертифікат повинен мати CN system: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 та групи.

Зверніть увагу на наступне:

  1. Всі kubeconfig файли включають в себе сертифікат ca.crt.
  2. Якщо вказаний kubeconfig файл вже існує і його зміст відповідає вищезазначеним вимогам, то буде використано існуючий файл, і фаза генерації для даного kubeconfig буде пропущена.
  3. Якщо kubeadm працює в режимі ExternalCA mode, всі необхідні kubeconfig файли також повинні бути надані користувачем, оскільки kubeadm не може згенерувати їх самостійно.
  4. У випадку виконання kubeadm в режимі --dry-run, файли kubeconfig записуються в тимчасову теку.
  5. Генерацію 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
  • Включено обрання лідера як для контролер-менеджера, так і для планувальника

  • Контролер-менеджер та планувальник будуть посилатися на файли kubeconfig з їхніми відповідними, унікальними ідентифікаторами

  • Всі статичні Podʼи отримують будь-які додаткові прапорці, вказані користувачем, як описано в передача користувацьких аргументів компонентам панелі управління

  • Всі статичні Podʼи отримують будь-які додаткові томи, вказані користувачем (Шлях хоста)

Зверніть увагу, що:

  1. Усі образи типово будуть витягуватися з registry.k8s.io. Для налаштування репозиторію образів див. використання власних образів
  2. У разі виконання kubeadm у режимі --dry-run файли статичних Podʼів записуються у тимчасову теку
  3. Генерацію маніфестів статичних Podʼів для компонентів панелі управління можна запустити окремо за допомогою команди kubeadm init phase control-plane all

Сервер API

Маніфест статичних Podʼів для сервера API обробляється наступними параметрами, наданими користувачами:

  • apiserver-advertise-address та apiserver-bind-port для звʼязку; якщо вони не вказані, стандартне значення буде IP-адреса основного мережевого інтерфейсу на машині та порт 6443
  • service-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 до файлової системи хосту
  • Будь-які додаткові прапорці, вказані користувачем

Зверніть увагу, що:

  1. Образ контейнера etcd буде типово витягнутий з registry.gcr.io. Для налаштування власного репозиторію образів див. використання власних образів.
  2. Якщо ви запускаєте kubeadm у режимі --dry-run, маніфест статичного Pod для etcd записується у тимчасову теку.
  3. Ви можете безпосередньо викликати генерацію маніфесту статичного 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) визначати фактичний поточний стан кластера і приймати нові рішення на основі цих даних.

Зверніть увагу, що:

  1. Перед збереженням конфігурації кластера чутлива інформація, така як токен, видаляється з конфігурації.
  2. Завантаження конфігурації вузла панелі управління може бути викликане окремо за допомогою команди 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-сервера та контролера, як вже було описано у попередніх розділах.

Створення bootstrap токена

kubeadm init створює перший bootstrap токен, що генерується автоматично або надається користувачем за допомогою прапорця --token. Згідно з документацією щодо специфікації bootstrap токена, токен слід зберегти як секрет з іменем bootstrap-token-<token-id> у просторі імен kube-system.

Зверніть увагу, що:

  1. bootstrap токен, типово створений kubeadm init, використовуватиметься для перевірки тимчасових користувачів під час процесу TLS-запуску; ці користувачі будуть членами групи system:bootstrappers:kubeadm:default-node-token.
  2. Токен має обмежену чинність, стандартно 24 години (цей інтервал можна змінити за допомогою прапорця --token-ttl).
  3. Додаткові токени можна створити за допомогою команди 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).

Встановлення надбудов

Kubeadm встановлює внутрішній DNS-сервер і компоненти надбудов kube-proxy через API-сервер.

proxy

Для kube-proxy створюється обліковий запис ServiceAccount у просторі імен kube-system, після чого kube-proxy розгортається як DaemonSet:

  • Облікові дані (ca.crt та token) до панелі управління отримуються з облікового запису ServiceAccount.
  • Місцезнаходження (URL) API-сервера отримується з ConfigMap.
  • Обліковий запис ServiceAccount kube-proxy повʼязується з правами у рольовому доступі ClusterRole system:node-proxier.

DNS

  • Сервіс CoreDNS називається kube-dns. Це зроблено для запобігання будь-яких перерв у роботі, коли користувач переключає DNS кластера з kube-dns на CoreDNS за допомогою методу --config, описаного тут.

  • У просторі імен kube-system створюється обліковий запис ServiceAccount для CoreDNS.

  • Обліковий запис coredns привʼязаний до привілеїв у ClusterRole system: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 виконує набір попередніх перевірок перед початком приєднання, з метою перевірити попередні умови та уникнути поширених проблем запуску кластера.

Зверніть увагу на наступне:

  1. Попередні перевірки kubeadm join є, по суті, підмножиною попередніх перевірок kubeadm init.
  2. Починаючи з версії 1.24, kubeadm використовує crictl для спілкування з усіма відомими CRI точками доступу.
  3. Починаючи з версії 1.9, kubeadm забезпечує підтримку приєднання вузлів, що працюють на Windows; у такому разі пропускаються специфічні для Linux перевірки.
  4. У будь-якому випадку користувач може пропустити певні попередні перевірки (або, врешті-решт, усі попередні перевірки) за допомогою опції --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, отриманим спочатку

Виявлення файлу/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 видаляється.

Змінено August 27, 2024 at 9:57 PM PST: Removing the reviewers section from the front matter (81a711722d)