Учимся разворачивать микросервисы. Часть 2. Kubernetes / Хабр

Начало и конец

Учимся разворачивать микросервисы. Часть 2. Kubernetes / Хабр

Добрый день всем читающим!Много статей было об этом, много блогов, но статья HowTo, без напильника, найдена не была, и это крайне печально.Для небольших развертываний эта вещь, из коробки просто незаменима.

Для тех кто не знает: WDS (центр развертывания) это специальное средство, которое есть в серверной ОС Microsoft, с помощью него можно установить систему на большое количество компьютер одновременно, с помощью сети, используя PXE.Также тут будет информация о препарировании wim, и немножко о DHCP.Итак начнем под катом.

1 Включение WDS

Установка WDS в картинках. Все просто.

Дальше начинается то, что потребует чуть больше, чем просто Nextnextnext)/

3 Образы

На установочном диске с любой системой, начиная с Vista, есть папка source, там лежат два файла boot.wim и install.wim

Boot.wim — это образ для запуска, предзагрузочный.

install.wim — это образ самой системы.

Если boot.wim ещё надо будет подготовить, для работы, то install.wim сразу готов для установки.

В диспетчере сервера boot — образы загрузки, install — образы установки.

1 Утилиты

По умолчанию в 2021 сервере, после установки WDS, утилита dism может работать с образами wim в полной мере.

Для 2008/R2 или 7 вам понадобится

и у вас появится инструмент dism.

Создаем структуру папок: c:driversmount — папка монтирования WIM образа; c:driverslan_drivers — папка с драйверами для сетевой карты.Копируем boot.wim от ОС в папку c:driversПредостерегаю! Чем больше драйверов, тем больше универсальности, но и размер образа сильно увеличивается, это необходимо учитывать. Образ целиком заливается в RAM.

2 Препарирование


Для 20087 запускаем Deployment Tools Command Prompt из меню пуск с правами администратора.

Для 2021 — запускаем командную строку с правами администратора.

Смотрим содержимое загрузочного образа boot.wim:

dism /get-wiminfo /wimfile:c:driversboot.wim

По идее там должно быть так:

Как видно из скриншота boot.wim содержит два образа — Windows PE (Индекс 1) и Windows Setup (Индекс 2). Драйвера для сетевой карты надо добавлять в Windows Setup, поэтому будем работать с образом 2 (Индекс 2).

Но не так всё просто. Компания добра Microsoft заблокировала для изменения этот образ, для его редактирования его надо «перезалить».Выполняем:

Dism /Export-Image /SourceImageFile:c:driversboot.wim /SourceIndex:1 /DestinationImageFile:c:driversboot1.wim
Dism /Export-Image /SourceImageFile:c:driversboot.wim /SourceIndex:2 /DestinationImageFile:c:driversboot1.wim


Соответственно, мы перезалили образы Windows PESetup в новый файл.

Сначала скопировали первый, потом второй индекс.

Удаляем boot.wim, переименовываем boot1.wim в boot.wim

dism /get-wiminfo /wimfile:c:driversboot.wim

Должна выдать те же два раздела, с index 1 & 2.

3 Добавление драйверов


Монтируем образ с индексом 2 из файла boot.wim в папку «c:driversmount» командой:

dism /Mount-Wim /WimFile:c:driversboot.wim /index:2 /MountDir:c:driversmountimage

Добавляем драйвера в образ. Драйвера можно добавлять по одному, либо сразу все из определенной директории.Для добавления драйвера указываем полный путь к файлу .INF:

dism /image:c:driversmount /add-driver /driver:«C:driverslan_driversE1C5232.INF»

Если драйверов много, то указываем каталог в качестве источника для поиска и добавления драйверов:

dism /image:c:driversmount /add-driver /driver:«C:driverslan_drivers» /recurse /forceunsigned

параметр /recurse используется, чтобы установить драйвера из вложенных каталогов, а /ForceUnsigned для установки неподписанных драйверов.


После добавления всех драйверов загрузочный образ нужно закрыть (отмонтировать).

dism /unmount-wim /mountdir:c:driversmount /commit

параметр /commit указывает, что нужно сохранять все изменения в образе, без него все изменения будут потеряны.

4 Образ в хранилище

Теперь перекопируем его в любую директорию, где у вас будут хранится образы.

И установим на сервер WDS.

Теперь необходимо указать имя. Имя образа — это то, что будете видеть вы, при выборе загрузчиков, если у вас их несколько.

5 Безопастность

Учимся разворачивать микросервисы. Часть 2. Kubernetes / Хабр

Security — Чтобы добавить разрешения для учетной записи пользователя на группу образов, щелкните правой кнопкой мыши группу оразов и нажмите security. Добавьте учетную запись пользователя из AD и настройте полный контроль. Если вы используете учетную запись администратора домена во время установки WDS, то это можно не делать.

1 Создание образа и его копирование на сетевой ресурс с помощью Windows PE и программы ImageX

Теперь запишем образ компьютера, с помощью среды Windows PE и программы ImageX и сохраним на сетевом ресурсе.


Для этого необходимо загрузиться с диска Windows PE.

Для того чтобы иметь доступ на запись к сетевому ресурсу, необходимо к нему подключиться, введя следующую команду:

1.1 Ручное развертывание

Если необходимо руками образ развернуть (без WDS) но по сети

Битность системы должна быть той же, что и у системы, которую мы распаковываем.

После создания образа, можно развернуть его на новое оборудование с помощью программы ImageX и среды Windows PE.

Форматируем диск, для распаковки на него WMI.

Для этого надо ввести следующие команды:

diskpart
select disk 0
clean
create partition primary size=100
select partition 1
format fs=ntfs label=«system»
assign letter=c
active
create partition primary
select partition 2
format fs=ntfs QUICK
assign letter=e
exit

Можно создать сценарий для данной процедуры, сохранив приведенную информацию в текстовый файл в папке с образом. Чтобы выполнить сценарий из командной строки среды Windows PE, необходимо ввести команду: diskpart /s .txt

Форматирование следует проводить ТОЛЬКО в среде Windows PE. Если отформатировать жёсткий диск на другом компьютере средствами Windows, а затем вставить этот жёсткий диск в конечный компьютер, то образ с вероятностью 80% НЕ РАЗВЕРНЁТСЯ.

Подключаемся к сетевому ресурсу для развёртывания образа, введя следующую команду:

NET USE y: \nmpoem<имя папки> /USER:AD *
Вводим пароль.
! надо понять какой диск является каким, для этого с помощью команды DIR C: (D,E,F & etc), перебираем диски, если их несколько
Разворачиваем образ на жесткий диск с помощью программы ImageX, с сетевого ресурса, введя следующую команду:
d:imagex.exe /apply y:<имя>.wim 1 e: /verify
После этого пойдёт процесс развёртывания образа на указанный жёсткий диск с сетевого ресурса.

Далее, с помощью средства BCDboot необходимо инициализировать хранилище данных конфигурации загрузки (BCD) и скопировать файлы среды загрузки в системный раздел, введя в командной строке следующую команду:

e:windowssystem32bcdboot e:windows
По завершении создания образа и его копирования на сетевой ресурс необходимо ввести команду exit и приложение закроется и компьютер начнёт перегружаться.
Настроенный образ развернут на конечный компьютер.

2 Сервер

Настроим сервер, для работы с образами.

Добавим наш готовый образ в «Образы установки»:

Как в случае с загрузочным образом указываем мастеру путь к файлу wim, который мы создали:

В оригинальном файле install.wim может содержаться несколько редакций:

Но в созданном должна быть только одна.

1 CNP

Учимся разворачивать микросервисы. Часть 2. Kubernetes / Хабр

2 Cisco DHCP MODE

Тут не так страшно как кажется:
BU# ip dhcp pool DATA
BU# option 66 ascii «1.2.3.4»
BU# option 67 ascii «bootfile.pxe»

Configmap

Объект, предоставляющий свойства для подов. В нашем случае шлюзу для связи с подами бекенда необходимо знать URL-адрес их сервиса. Наш ConfigMap будет содержать адреса внутренних сервисов нашего кластера, и его можно будет заинжектить во все заинтересованные микросервисы (в нашей системе это только шлюз).

Deployments

У нас будет два деплоймента — для бекенда и шлюза.

Деплоймент шлюза:

Gke configuration

Как я уже говорил, далее мы обсудим, как можно изменить конфигурацию, чтобы задеплоить систему в Google Kubernetes Engine.

Horizontalpodautoscalers

HorizontalPodAutoscaler будет автоматически масштабировать деплоймент в зависимости от нагрузки на его поды. Мне не удалось заставить работать этот компонент на Minikube (какие-то странные неполадки с сервером метрик), но в GKE он работает из коробки.

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: backend
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: backend
  minReplicas: 1
  maxReplicas: 3
  targetCPUUtilizationPercentage: 50

В spec.scaleTargetRef мы указываем, что мы собираемся автомасштабировать деплоймент под именем backend. Далее сообщаем, что собираемся содержать от 1 до 3 реплик и планируем держать поды загруженными на 50%. Отмечу, чтобы задавать планируемую загрузку в процентах (можно указывать и в абсолютных величинах), то надо обязательно указать requests.cpu у управляемых контейнеров.

Конфигурация HorizontalPodAutoscaler’а шлюза аналогична.

Namespace:

Создадим неймспейс:

kubectl create namespace msvc-ns

Установим его как текущий:

kubectl config set-context --current --namespace=msvc-ns

Далее все объекты будут создаваться в неймспейсе ‘msvc-ns’. Если этот шаг пропустить, то будет использоваться неймспейс ‘default’.

Обычно конфигурация для Kubernetes представляет собой обычный yaml-файл с описанием объектов, но также есть возможность создавать эти объекты и через CLI. В дальнейшем все объекты будут описываться в yaml-формате.

Quotas

Квоты позволяют настроить максимальное потребление ресурсов всем кластером. Это обычно нужно, если несколько команд используют один кластер (multitenant environment). Давайте ограничим ресурсы, доступные объектам нашего неймспейса:

apiVersion: v1  
kind: ResourceQuota  
metadata:  
  name: msvc-quota  
spec:  
  hard:
    limits.cpu: "2"  
    limits.memory: 4Gi

Если мы проставляем жесткие ограничения квот по какому-либо параметру, то для каждого из создаваемых подов этот параметр становится обязательным. Это может вызывать неудобства, например, при создании контейнеров из CLI (см. kubectl run), поэтому установим дефолтные параметры с помощью объекта LimitRange:

apiVersion: v1  
kind: LimitRange  
metadata:  
  name: msvc-default-resources  
spec:  
  limits: 
    - default:
        memory: "512Mi"  
        cpu: "250m"  
      defaultRequest:  
        memory: "256Mi"  
        cpu: "50m"  
      type: Container

Так как конфигурация квот напрямую не относится к нашему приложению, то лучше оформить ее в отдельный файл.

Secret

apiVersion: v1
kind: Secret
metadata:
  name: msvc-secret
type: Opaque
stringData:
  secret: secret

Тип Opaque подразумевает, то что секрет задается парами ключ-значение. Для особых секретов, например, паролей реестров Docker-образов, существуют отдельные типы. В данном конфиге мы указываем пароль в открытом виде в блоке stringData. Так как секреты хранятся в кодировке base64, то наши данные будут закодированы автоматически. Секрет можно указать в уже закодированном виде:

data:
  secret: c2VjcmV0 

Services

Сервис бекенда:

apiVersion: v1
kind: Service
metadata:
  labels:
    tier: backend
  name: backend
spec:
  ports:
    - port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    tier: backend

Запуск

Применяем конфигурацию:

kubectl apply -f deploy.yaml

Подождем пока все объекты Kubernetes запустятся и получим URL нашего приложения:

minikube service gateway --url -n msvc-ns

Далее сгенерируем трафик:

Объекты kubernetes

При работе с Kubernetes инженер описывает желаемое состояние системы через определение объектов и связей между ними. А конкретные действия для достижения нужного состояния оркестратор волен выбирать сам. То есть можно сказать, что настройка носит декларативный характер.

Рассмотрим некоторые объекты Kubernetes:

  • Namespace — пространство имен. Объекты могут взаимодействовать, только если находятся в одном неймспейсе. С помощью неймспейсов возможно развернуть несколько виртуальных кластеров на одном физическом.

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

  • ReplicaSet — контроллер, позволяющий создать набор одинаковых подов и работать с ними, как с единой сущностью. Поддерживает нужное количество реплик, при необходимости создавая новые поды или убивая старые. На самом деле в большинстве случаев вы не будете работать с ReplicaSet напрямую — для этого есть Deployment.

  • Deployment — контроллер развертывания, являющийся абстракцией более высокого уровня над ReplicaSet’ом. Добавляет возможность обновления управляемых подов.

  • Service — отвечает за сетевое взаимодействие группы подов. В системе обычно существует несколько экземляров одного микросервиса, соответственно каждый из них имеет свой IP-адрес. Количество подов может изменяться, следовательно набор адресов также не постоянен. Другим частям системы для доступа к рассматриваемым подам нужен какой-то статичный адрес, который Service и предоставляет.

    Во избежание путаницы здесь и в дальнейшем под словом «сервис» я буду подразумевать именно объект Kubernetes, а не экземпляр приложения.

    Существует несколько видов сервисов. Перечисленные ниже типы для простоты понимания можно рассматривать, как матрешку. Каждый последующий оборачивает предыдущий и добавляет некоторые правила маршрутизации. Создавая сервис более высокого уровня, автоматически создаются сервисы нижележащего типа. Типы сервисов:

    • ClusterIP — дефолтный тип сервиса. Единая точка доступа к подам по постоянному IP-адресу, доступному только изнутри кластера.
    • NodePort — общий IP-адрес подов (полученный из ClusterIP) соединяется с определенным портом всех нод, на которых развернуты обслуживаемые поды. Поды становятся доступны по адресу <NodeIP>:<NodePort>.
    • LoadBalancer — выходной порт NodePort присоединяется к внешнему балансировщику нагрузки, предоставляемому облачным провайдером. Таким образом мы получаем статический внешний IP-адрес для нашего приложения.

    Также Kubernetes из коробки предоставляет поддержку DNS внутри кластера, позволяя обращаться к сервису по его имени. Более подробно про сервисы можно почитать тут.

  • ConfigMap — объект с произвольными конфигурациями, которые могут, например, быть переданы в контейнеры через переменные среды.

  • Secret — объект с некой конфиденциальной информацией. Секреты могут быть файлами (№ SSL-сертификатами), которые монтируются к контейнеру, либо же base64-закодированными строками, передающимися через те же переменные среды. В статье будут рассмотрены только строковые секреты.

  • HorizontalPodAutoscaler — объект, предназначенный для автоматического изменения количества подов в зависимости от их загруженности.

Среда kubernetes

Minikube — это удобный инструмент для экспериментов с Kubernetes на локальной машине. Изначально мы создадим конфигурацию для работы именно в этой среде. Далее мы поговорим, какие корректировки нужно внести, чтобы задеплоить систему в GKE. Google Cloud Platform был выбран из-за бесплатных 300$ на эксперименты в первый год. Для приведенной в статье конфигурации стоит использовать кластер из 2 стандартных машин (n1-standard-1).

Ссылки по настройке среды:

Управление кластером

Здесь я перечислю несколько полезных команд для управления кластером.

Извлечение информации

kubectl get <object-type> — вывести список объектов определенного типа. В качестве типов может выступать ‘pod’, ‘service’, ‘deployment’ и другие. Чтобы посмотреть все объекты в неймспейсе подставьте ‘all’.kubectl get <object-type> <object-name> -o yaml — выведет полную конфигурацию объекта в yaml-формате.kubectl describe <object-type> <object-name> — подробная информация об объекте.kubectl cluster-info — информация о кластере.kubectl top pod/node — потребляемые ресурсы подами/нодами.

Изменение конфигурации кластера

kubectl apply -f <file/directory> — применить конфигурационный файл или же все файлы из директории.kubectl delete <object-type> <object-name> — удалить объект.kubectl scale deployment <deployment-name> —replicas=n — отмасштабировать деплоймент.

Если выполнить подряд две команды: с n = 0, а затем с другим n, то пересоздаст все поды в деплойменте.kubectl edit <object-type> <object-name> — редактировать конфигурацию объекта в редакторе.kubectl rollout undo deployment <deployment-name> — откатить изменения деплоймента до прошлой версии.

Дебаг

kubectl logs <pod-name> — отобразить логи контейнера. Параметр -f позволит следить за логами в реальном времени.kubectl port-forward <pod-name> <host-port>:<container-port> — пробросить порт хоста на порт контейнера.

Используется для отправки запросов подам вручную.kubectl exec -it <pod-name> — /bin/sh — открыть терминал в контейнере пода.kubectl run curl —image=radial/busyboxplus:curl -i —tty — создать отдельный под. В данном примере создается легкий контейнер с curl, с помощью которого можно будет, например, проверить доступность сервисов.kubectl get events —sort-by=’.metadata.

Часть 1. установка

Эту часть можно пропустить тем, кто хоть раз делал установку службкомпонентов в Server 2021R2. Из этого блока нужен только пункт 1.3.

Идеалом для WDS является, если DHCP сервером является эта же машина. Тогда он может корректно передать информацию о PXE Boot.

Часть 2. препарирование boot.wim


Очень часто возникает одна большая пролема:

image

Сразу интегрируем необходимые драйвера в этот образ, дабы избежать этой проблемы.Она возникает, из-за отсутствия в образе драйверов для сетевой карты, которая интегрирована установлена в компьютер, на котором будет происходить установка ОС.

Часть 3. образ системы. кастомный вариант

Для начала устанавливаем ОС. Ставим всё что надо.

Далее препарируем её.

Хорошая статья по IMAGEX WINPE созданию образа там же есть ссылки вначале статьи для создания WIN7 & WIN8. Либо находим на просторах интернета WindowsPE, по вашему желанию)Для дальшейшего нам нужен образ WinPe с утилитой ImageX правильной битности.

Часть 4. великий и ужасный dhcp

1) WDS и DHCP установлены на одном сервере.

WDS и DHCP не могут занимать порт UDP 67 одновременно. Запретив службе WDS прослушивать порт UDP 67, можно предоставить порт для DHCP-трафика и присвоить DHCP-параметру 60 (параметр области или сервера) значение PXEClient, устранив конфликт.Если служба WDS устанавливается на DHCP-сервере, в ходе настройки появляется страница DHCP Option 60.

Установите флажки Do not listen on port 67 и Configure DHCP option 60 to PXEClient. В сообщении, получаемом клиентом от сервера DHCP, содержится IP-адрес, маска подсети и параметр 60. В результате клиенту становится ясно, что сервер DHCP является одновременно и сервером WDS.

2) WDS и DHCP находятся на различных серверах, в одной подсети с клиентами.

Дополнительной настройки не требуется, так как WDS и DHCP расположены на разных серверах. Обе службы могут прослушивать порт UDP 67, а клиенты находятся в одной подсети с серверами WDS и DHCP, поэтому широковещательный трафик доступен для всех.

3) WDS и DHCP устанавливаются на различных серверах, в разных подсетях.

Службы WDS и DHCP, установленные на разных серверах, не мешают друг другу прослушивать порт UDP 67.

Вы должны настроить маршрутизатор на отправку широковещательных пакетов, потому что чаще всего мы видим, что широковещательные пакеты не могут идти в другие подсети. Кроме того, весь трафик на UDP порт 4011 от клиентских компьютеров к серверу служб развертывания Windows должен быть направлен соответствующим образом.

Часть 5. немного послесловия

Собственно всё. Это небольшая статья, и кажется она закончена.

Кто-бы что не говорил, но для небольших сеток это очень нужная вещь.

Для тех, кто захочет расширить функционал, есть просто отличная статья на Geektimes:

На этому спешу откланяться, спасибо всем кто заинтересовался этой статьёй.

Гиктаймс форевер!

Если есть оЧепятки в тексте пиши в личных сообщениях, флудить и троллить не спортивно! Если можете что-то важное добавить, добавлю в статью.

UPD. спасибо darthslider и
navion

Существует MDT (Microsoft Delpoyment Toolkit). С помощью него можно сразу добавить ключ в образ и установить продукты с quiet установкой.Также настроить имя пользователя администратора и его пароль.Требует отдельного компьютера и установленных зависимостей.

darthsliderВ первую очередь MDT — это поддежка Task Seqence, то есть это любые скрипты и настройки на любом этапе установки.Так же это удобный редактор unattend.xmlНу и в придачу установка ПО, постнастройка, ввод в домен и тд, а так же поддержка сценариев обновления ОС (захват по и настроек, установка новой ос, восстановление), миграции пользователя на новый пк (схоже с предыдущим сценарием). Но последние 2 пунтка это довольно сильное шаманство.

(О настройке и поднятии видео ТУТ.)

Заключение

В этой статье мы написали Kubernetes-конфигурацию и успешно задеплоили нашу систему в Google Kubernetes Engine.

Возможно, когда вы читали эту статью, то заметили, что даже для деплоя простенькой системы из двух микросервисов очень многое надо держать в голове. Для установки корректной связи между объектами одну и ту же метку надо не забыть прописать в нескольких местах, при описании сервисов и подов надо не запутаться в их портах… Было бы неплохо подключить какой-нибудь шаблонизатор и получить возможность гибко управлять настройками нашей системы в целом, обособившись от абстракций Kubernetes. Все это (и много больше) позволяет сделать пакетный менеджер Helm.

В третьей части этого цикла статей мы потрогаем Helm 3, создадим helm-чарт для нашей системы и выложим его в репозиторий, созданный на основе GitHub Pages.

Итоговые файлы конфигурации для gke

Поместим все файлы в папку scripts_gke/.

Оставьте комментарий

Войти