ADG Оставить заявку
Блог DevOps 4 мин чтения

Kubernetes 1.14: Windows Node в production - запустили .NET-легаси без изменения кода

Kubernetes 1.14 GA стабилизировал поддержку Windows-нод. Добавили Windows-ноду в гибридный кластер и запустили .NET-легаси в Windows-контейнере - сеть пришлось настраивать отдельно.

Контекст момента

Kubernetes 1.14 GA - стабильная поддержка Windows-нод и улучшения в области persistent volumes

Kubernetes 1.14 вышел 25 марта и принёс несколько заметных вещей. Но нас в этом релизе больше всего интересовала одна: поддержка Windows-нод переехала из beta в GA. Официально стабильная. Можно в production.

У нас как раз был повод проверить.

Контекст: .NET-легаси в гибридном кластере

В одном из managed-проектов есть старый .NET-сервис. Не .NET Core - именно .NET Framework 4.7, Windows-only, переписывать его в обозримой перспективе никто не собирался. Остальная инфраструктура проекта уже в Kubernetes на Linux-нодах. Сам сервис жил на отдельной Windows VM и доставлялся туда по старинке - скриптами, руками, иногда молитвами.

Хотелось унифицировать. Раз уж Kubernetes 1.14 объявил Windows GA - время попробовать добавить Windows-ноду в кластер и загнать этот сервис в контейнер.

Спойлер: запустили. Но путь был не совсем прямым.

Что изменилось в 1.14 для Windows

До 1.14 поддержка Windows-нод была в beta с кучей оговорок. В 1.14 её подняли до GA - это означает стабильный API и гарантию совместимости в рамках жизненного цикла версии. Конкретные улучшения:

  • Runcontainerimage и связанные операции kubelet теперь работают стабильно на Windows без экспериментальных флагов.
  • Улучшена поддержка persistent volumes - в частности, флаги монтирования, которые раньше работали по-разному на Windows и Linux, выровняли поведение.
  • Storage plugin subPath стал корректно работать с Windows-путями.

Плюс в этом же релизе подтянули kubectl - kubectl diff наконец стал первоклассным инструментом, а не экспериментальным флагом. Мелочь, но приятная.

Как добавляли Windows-ноду

Кластер у нас на kubeadm. Добавление Windows-ноды - это не kubeadm join по умолчанию, там есть своя процедура. Грубо:

  • Windows Server 2019 - минимальное требование для Windows-контейнеров в Kubernetes. Мы подняли ноду на WS2019 Core, благо у нас уже был опыт с этим.
  • kubelet и kube-proxy для Windows - скачиваются отдельно, устанавливаются как Windows-сервисы через скрипт PrepareNode.ps1 из официальных материалов SIG Windows.
  • CNI-плагин для Windows - и вот здесь начинается самое интересное.

Сеть: отдельная история

Сетевой оверлей на Windows работает иначе, чем на Linux. Flannel с VXLAN-бэкендом, который стоит у нас на Linux-нодах, на Windows не поддерживается. Вместо этого Windows использует host-gw режим или WinOverlay - VXLAN-реализацию через специфичный для Windows HNS (Host Networking Service).

Мы пошли по пути host-gw для Windows-нод и потратили на это заметную часть времени. Нюансы:

  • Flannel на Windows нужен отдельный DaemonSet с образом под Windows. Образ отдельный - flannel:v0.11.0-windowsamd64.
  • HNS-сеть при первом запуске создаётся с задержкой и может выглядеть как зависший контейнер. Первые несколько минут нервные.
  • Маршруты между Linux- и Windows-нодами в host-gw режиме требуют что все ноды находились в одной L2-сети. В нашем случае - да, но это надо учитывать при планировании топологии.

DNS внутри Pod-ов на Windows-ноде работает через kube-dns/CoreDNS так же, как на Linux - здесь без сюрпризов.

Сервис в контейнере

Сам .NET-сервис мы завернули в Windows-контейнер на базе mcr.microsoft.com/windows/servercore:ltsc2019. Dockerfile простой: скопировать собранные DLL-ки, прописать entrypoint. Код не трогали вообще - сервис написан как console app, слушает порт, читает конфиг из переменных окружения. Это и спасло.

nodeSelector в манифесте Deployment:

nodeSelector:
  kubernetes.io/os: windows

Без этого Kubernetes попытается разместить Pod на Linux-ноде и получит ошибку несовместимости образа.

Pod поднялся, сервис ответил на первый запрос. Момент, честно говоря, неожиданно приятный - когда что-то такое большое просто берёт и работает.

Что не идеально

Образы большие. Windows Server Core - это несколько гигабайт базового образа. Pull на новой ноде занимает время, которое на Linux измеряется секундами, а тут - минутами. Нано-сервер был бы меньше, но наш сервис требует полного Server Core.

Мониторинг. cAdvisor на Linux-нодах работает с containerd. На Windows-ноде ситуация другая - метрики контейнеров идут через другие механизмы, стандартный cAdvisor там работает не полноценно. Пришлось смотреть в сторону кастомных метрик.

Обновление. Rolling update работает, но медленнее - из-за времени pull образа. Нужно учитывать в minReadySeconds и timeout.

Итого

Гибридный кластер с Linux- и Windows-нодами работает. .NET-легаси в контейнере запускается и отвечает на запросы без каких-либо изменений в коде самого сервиса. Сетевой оверлей потребовал отдельной настройки и разбора того, как HNS работает с Flannel - но это решаемо.

Для нас это значит: Windows-зависимые компоненты можно постепенно включать в общую операционную модель кластера, а не держать их на отдельных VM с ручным управлением. Не всё одинаково гладко по сравнению с Linux, но разрыв уже не катастрофический.

Эксплуатируем дальше, смотрим как будет вести себя под реальной нагрузкой.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.