На рабочую станцию ставят RSAT — компоненты по требованию Rsat.* через Add-WindowsCapability, — и модули, оснастки и утилиты оттуда ходят на серверы разными путями. ActiveDirectory обращается к ADWS на 9389, модули из CDXML вроде DnsServer с -CimSession — к CIM поверх WinRM, а их -ComputerName, Get-WinEvent и оснастки MMC — по RPC, для которого часть правил файрвола на сервере по умолчанию выключена. Недостающий модуль импортируют с сервера неявным remoting — тем же механизмом PowerShell 7 загружает модули, несовместимые с ним.
StatefulSet закрепляет за каждым подом номер: имя web-1, DNS-имя через headless-сервис и свою заявку на том из volumeClaimTemplates, которая после пересоздания возвращается к тому же номеру; поды создаются и обновляются по одному, и под с данным именем существует не больше одного. DaemonSet держит ровно по одному поду на каждом подходящем узле: привязывает под к узлу через node affinity и сам добавляет tolerations на taints узла. Репликацию и выбор лидера ни тот ни другой не делают — это дело приложения или оператора.
WinRM — реализация стандарта WS-Management: клиент шлёт SOAP-запросы POST /wsman на порт 5985 или 5986, а PowerShell Remoting — ресурс, внутри которого ездит протокол PSRP с сериализованными объектами. В домене аутентификация идёт по Kerberos, и тело шифруется ключом сеанса даже по HTTP; без Kerberos клиент требует HTTPS или TrustedHosts. Объекты из сеанса приходят десериализованными, без методов, а на сервере каждый сеанс живёт в своём wsmprovhost.exe.
ReplicaSet следит, чтобы подов по его шаблону было ровно replicas: недостающие создаёт, лишние удаляет. Deployment отвечает за версии: каждое изменение шаблона пода — новый ReplicaSet с меткой pod-template-hash, и контроллер переносит реплики со старого на новый в рамках maxSurge и maxUnavailable, делая следующий шаг только когда новые поды стали доступными по readiness probe и minReadySeconds. Старые ReplicaSet-ы с нулём реплик остаются историей, по которой работает kubectl rollout undo.
Модуль ActiveDirectory говорит с контроллером не по LDAP, а через службу ADWS на порту 9389, которая сама выполняет обычный LDAP-поиск. Один объект находят по -Identity (sAMAccountName, DN, GUID или SID), несколько — по -Filter, который модуль переводит в LDAP-фильтр и выполняет на сервере. Атрибуты перечисляют в -Properties, а не берут *, и пишущие скрипты фиксируют один контроллер через -Server.
Pod — минимальная единица, которую Kubernetes планирует и запускает: не один контейнер, а группа контейнеров с общим IP-адресом, общими томами и общей судьбой на одном узле. Общие namespaces держит служебный контейнер pause, поэтому перезапуск любого контейнера не меняет адрес пода. kubelet запускает init-контейнеры по одному, затем sidecar-ы (init с restartPolicy: Always) и основные контейнеры, следит за ними через probes, а при удалении даёт terminationGracePeriodSeconds на завершение по SIGTERM.
Время в домене идёт по иерархии: члены домена берут его у контроллеров, контроллеры — у PDC-эмулятора, и только PDC-эмулятор корневого домена леса синхронизируется с внешним источником, который ему назначает администратор (w32tm /config /manualpeerlist). Ответы контроллеров подписаны по MS-SNTP паролем учётной записи компьютера, поэтому член домена не возьмёт время у постороннего NTP-сервера. Расхождение часов больше пяти минут ломает Kerberos и репликацию.
Образ — дерево JSON-документов и слоёв, которые ссылаются друг на друга по дайджесту, поэтому тег можно перезаписать, а дайджест — нет. Приложение hello на Go собираем многоэтапным Dockerfile через docker buildx build под amd64 и arm64 на базе distroless, без shell и не от root, и отправляем с --push в частный GitHub Container Registry. Узлам даём токен только на чтение через Secret типа kubernetes.io/dockerconfigjson, привязанный к ServiceAccount через imagePullSecrets, а в манифестах пишем теги версий или дайджесты, но не latest.
RODC — контроллер для филиала: он выдаёт билеты Kerberos, отвечает на LDAP и работает DNS-сервером, но записи отсылает на записываемый контроллер и сам ничего не реплицирует. Хешей паролей он по умолчанию не хранит: кешируются только учётные записи из разрешённого списка политики репликации паролей (PRP), остальных проверяет контроллер в офисе. TGT он шифрует ключом собственной учётной записи krbtgt_, поэтому украденный RODC не открывает ни других сайтов, ни чужих привилегий.
На трёх машинах Ubuntu 26.04 выключаем swap, включаем net.ipv4.ip_forward, ставим containerd с SystemdCgroup = true и пакеты kubeadm, kubelet и kubectl версии 1.36. На мастере kubeadm init --config kubeadm-config.yaml за минуту выпускает сертификаты, пишет kubeconfig и манифесты статических подов, затем ставим Calico через оператор Tigera, а рабочие узлы подключаем kubeadm join. Самое важное решение — отдельное имя API k8s-api.example.com в controlPlaneEndpoint: без него кластер потом не превратить в отказоустойчивый.