Что такое нода сервера: Кластер (группа компьютеров) — Википедия – Ноды в Криптовалюте. Что такое, Виды, мастерноды Ethereum

Содержание

Кластер (группа компьютеров) — Википедия

У этого термина существуют и другие значения, см. Кластер.

Кластер — группа компьютеров, объединённых высокоскоростными каналами связи, представляющая с точки зрения пользователя единый аппаратный ресурс. Кластер — слабо связанная совокупность нескольких вычислительных систем, работающих совместно для выполнения общих приложений, и представляющихся пользователю единой системой. Один из первых архитекторов кластерной технологии Грегори Пфистер дал кластеру следующее определение: «Кластер — это разновидность параллельной или распределённой системы, которая:

  1. состоит из нескольких связанных между собой компьютеров;
  2. используется как единый, унифицированный компьютерный ресурс».

Обычно различают следующие основные виды кластеров:

  1. отказоустойчивые кластеры (High-availability clusters, HA, кластеры высокой доступности)
  2. кластеры с балансировкой нагрузки (Load balancing clusters)
  3. вычислительные кластеры (High performance computing clusters, HPC)
  4. системы распределенных вычислений

Кластеры высокой доступности[править | править код]

Обозначаются аббревиатурой HA (англ. High Availability — высокая доступность). Создаются для обеспечения высокой доступности сервиса, предоставляемого кластером. Избыточное число узлов, входящих в кластер, гарантирует предоставление сервиса в случае отказа одного или нескольких серверов. Типичное число узлов — два, это минимальное количество, приводящее к повышению доступности. Создано множество программных решений для построения такого рода кластеров.

Отказоустойчивые кластеры и системы разделяются на 3 основных типа:

  • с холодным резервом или активный/пассивный. Активный узел выполняет запросы, а пассивный ждет его отказа и включается в работу, когда таковой произойдет. Пример — резервные сетевые соединения, в частности, Алгоритм связующего дерева. Например, связка DRBD и HeartBeat/Corosync.
  • с горячим резервом или активный/активный. Все узлы выполняют запросы, в случае отказа одного нагрузка перераспределяется между оставшимися. То есть кластер распределения нагрузки с поддержкой перераспределения запросов при отказе. Примеры — практически все кластерные технологии, например, Microsoft Cluster Server. OpenSource проект OpenMosix.
  • с модульной избыточностью.
    Применяется только в случае, когда простой системы совершенно недопустим. Все узлы одновременно выполняют один и тот же запрос (либо части его, но так, что результат достижим и при отказе любого узла), из результатов берется любой. Необходимо гарантировать, что результаты разных узлов всегда будут одинаковы (либо различия гарантированно не повлияют на дальнейшую работу). Примеры — RAID и Triple modular redundancy.

Конкретная технология может сочетать данные принципы в любой комбинации. Например, Linux-HA поддерживает режим обоюдной поглощающей конфигурации (англ. takeover), в котором критические запросы выполняются всеми узлами вместе, прочие же равномерно распределяются между ними.

[1]

Кластеры распределения нагрузки (Network Load Balancing, NLB)[править | править код]

Принцип их действия строится на распределении запросов через один или несколько входных узлов, которые перенаправляют их на обработку в остальные, вычислительные узлы. Первоначальная цель такого кластера — производительность, однако, в них часто используются также и методы, повышающие надёжность. Подобные конструкции называются серверными фермами. Программное обеспечение (ПО) может быть как коммерческим (OpenVMS, MOSIX, Platform LSF HPC, Solaris Cluster, Moab Cluster Suite, Maui Cluster Scheduler), так и бесплатным (OpenMosix, Sun Grid Engine, Linux Virtual Server).

Вычислительные кластеры[править | править код]

Кластеры используются в вычислительных целях, в частности в научных исследованиях. Для вычислительных кластеров существенными показателями являются высокая производительность процессора в операциях над числами с плавающей точкой (flops) и низкая латентность объединяющей сети, и менее существенными — скорость операций ввода-вывода, которая в большей степени важна для баз данных и web-сервисов. Вычислительные кластеры позволяют уменьшить время расчетов, по сравнению с одиночным компьютером, разбивая задание на параллельно выполняющиеся ветки, которые обмениваются данными по связывающей сети. Одна из типичных конфигураций — набор компьютеров, собранных из общедоступных компонентов, с установленной на них операционной системой Linux, и связанных сетью Ethernet, Myrinet, InfiniBand или другими относительно недорогими сетями. Такую систему принято называть кластером Beowulf. Специально выделяют высокопроизводительные кластеры (Обозначаются англ. аббревиатурой

HPC Cluster — High-performance computing cluster). Список самых мощных высокопроизводительных компьютеров (также может обозначаться англ. аббревиатурой HPC) можно найти в мировом рейтинге TOP500. В России ведется рейтинг самых мощных компьютеров СНГ.[2]

Системы распределенных вычислений (grid)[править | править код]

Такие системы не принято считать кластерами, но их принципы в значительной степени сходны с кластерной технологией. Их также называют grid-системами. Главное отличие — низкая доступность каждого узла, то есть невозможность гарантировать его работу в заданный момент времени (узлы подключаются и отключаются в процессе работы), поэтому задача должна быть разбита на ряд независимых друг от друга процессов. Такая система, в отличие от кластеров, не похожа на единый компьютер, а служит упрощённым средством распределения вычислений. Нестабильность конфигурации, в таком случае, компенсируется больши́м числом узлов.

Кластер серверов, организуемых программно[править | править код]

Кластер серверов (в информационных технологиях) — группа серверов, объединённых логически, способных обрабатывать идентичные запросы и использующихся как единый ресурс. Чаще всего серверы группируются посредством локальной сети. Группа серверов обладает большей надежностью и большей производительностью, чем один сервер. Объединение серверов в один ресурс происходит на уровне программных протоколов.

В отличие от аппаратного кластера компьютеров, кластеры организуемые программно, требуют:

  • наличия специального программного модуля (Cluster Manager), основной функцией которого является поддержание взаимодействия между всеми серверами — членами кластера:
    • синхронизации данных между всеми серверами — членами кластера;
    • распределение нагрузки (клиентских запросов) между серверами — членами кластера;
  • от умения клиентского программного обеспечения распознавать сервер, представляющий собой кластер серверов, и соответствующим образом обрабатывать команды от Cluster Manager;
    • если клиентская программа не умеет распознавать кластер, она будет работать только с тем сервером, к которому обратилась изначально, а при попытке Cluster Manager перераспределить запрос на другие серверы, клиентская программа может вообще лишиться доступа к этому серверу (результат зависит от конкретной реализации кластера).
Примеры программных кластерных решений
Применение[править | править код]

В большинстве случаев, кластеры серверов функционируют на раздельных компьютерах. Это позволяет повышать производительность за счёт распределения нагрузки на аппаратные ресурсы и обеспечивает отказоустойчивость на аппаратном уровне.

Однако, принцип организации кластера серверов (на уровне программного протокола) позволяет исполнять по нескольку программных серверов на одном аппаратном. Такое использование может быть востребовано:

  • при разработке и тестировании кластерных решений;
  • при необходимости обеспечить доступность кластера только с учётом частых изменений конфигурации серверов — членов кластера, требующих их перезагрузки (перезагрузка производится поочерёдно) в условиях ограниченных аппаратных ресурсов.
Ambox outdated serious.svg

Информация в этом разделе устарела.

Вы можете помочь проекту, обновив его и убрав после этого данный шаблон.

Дважды в год организацией TOP500 публикуется список пятисот самых производительных вычислительных систем в мире, среди которых в последнее время часто преобладают кластеры. Самым быстрым кластером является IBM Roadrunner (Лос-Аламосская национальная лаборатория, США, созданный в 2008 году), его максимальная производительность (на июль 2008) составляет 1,026 Петафлопс. Самая быстрая система в Европе (на июль 2008) — суперкомпьютер, BlueGene/P находится в Германии, в исследовательском центре города Юлих, земля Северный Рейн-Вестфалия, максимально достигнутая производительность 167,3 Терафлопс.

Кластерные системы занимают достойное место в списке самых быстрых, при этом значительно выигрывая у суперкомпьютеров в цене. На июль 2008 года на 7 месте рейтинга TOP500 находится кластер SGI Altix ICE 8200 (Chippewa Falls, Висконсин, США).

Сравнительно дешёвую альтернативу суперкомпьютерам представляют кластеры, основанные на концепции Beowulf, которые строятся из обыкновенных недорогих компьютеров на основе бесплатного программного обеспечения. Один из практических примеров такой системы — Stone Soupercomputer в Национальной лаборатории Ок-Ридж (Теннесси, США, 1997).

Крупнейший кластер, принадлежащий частному лицу (из 1000 процессоров), был построен Джоном Козой (John Koza).

История создания кластеров неразрывно связана с ранними разработками в области компьютерных сетей. Одной из причин для появления скоростной связи между компьютерами стали надежды на объединение вычислительных ресурсов. В начале 1970-х годов группой разработчиков протокола TCP/IP и лабораторией Xerox PARC были закреплены стандарты сетевого взаимодействия. Появилась и операционная система Hydra для компьютеров PDP-11 производства DEC, созданный на этой основе кластер был назван C.mpp (Питтсбург, штат Пенсильвания, США, 1971 год). Тем не менее, только около 1983 года были созданы механизмы, позволяющие с лёгкостью пользоваться распределением задач и файлов через сеть, по большей части это были разработки в SunOS (операционной системе на основе BSD от компании Sun Microsystems).

Первым коммерческим проектом кластера стал ARCNet, созданный компанией Datapoint в 1977 году. Прибыльным он не стал, и поэтому строительство кластеров не развивалось до 1984 года, когда DEC построила свой VAXcluster на основе операционной системы VAX/VMS. ARCNet и VAXcluster были рассчитаны не только на совместные вычисления, но и совместное использование файловой системы и периферии с учётом сохранения целостности и однозначности данных. VAXCluster (называемый теперь VMSCluster) — является неотъемлемой компонентой операционной системы HP OpenVMS, использующих процессоры DEC Alpha и Itanium.

Два других ранних кластерных продукта, получивших признание, включают Tandem Hymalaya (1994, класс HA) и IBM S/390 Parallel Sysplex (1994).

История создания кластеров из обыкновенных персональных компьютеров во многом обязана проекту Parallel Virtual Machine. В 1989 году это программное обеспечение для объединения компьютеров в виртуальный суперкомпьютер открыло возможность мгновенного создания кластеров. В результате суммарная производительность всех созданных тогда дешёвых кластеров обогнала по производительности сумму мощностей «серьёзных» коммерческих систем.

Создание кластеров на основе дешёвых персональных компьютеров, объединённых сетью передачи данных, продолжилось в 1993 году силами Американского аэрокосмического агентства NASA, затем в 1995 году получили развитие кластеры Beowulf, специально разработанные на основе этого принципа. Успехи таких систем подтолкнули развитие grid-сетей, которые существовали ещё с момента создания UNIX.

Широко распространённым средством для организации межсерверного взаимодействия является библиотека MPI, поддерживающая языки C и Fortran. Она используется, например, в программе моделирования погоды MM5.

Операционная система Solaris предоставляет программное обеспечение Solaris Cluster, которое служит для обеспечения высокой доступности и безотказности серверов, работающих под управлением Solaris. Для OpenSolaris существует реализация с открытым кодом под названием OpenSolaris HA Cluster.

Среди пользователей GNU/Linux популярны несколько программ:

  • distcc, MPICH и др. — специализированные средства для распараллеливания работы программ. distcc допускает параллельную компиляцию в GNU Compiler Collection.
  • Linux Virtual Server, Linux-HA — узловое ПО для распределения запросов между вычислительными серверами.
  • MOSIX, openMosix, Kerrighed, OpenSSI — полнофункциональные кластерные среды, встроенные в ядро, автоматически распределяющие задачи между однородными узлами. OpenSSI, openMosix и Kerrighed создают среду единой операционной системы между узлами.

Кластерные механизмы планируется встроить и в ядро DragonFly BSD, ответвившуюся в 2003 году от FreeBSD 4.8. В дальних планах также превращение её в среду единой операционной системы.

Компанией Microsoft выпускается HA-кластер для операционной системы Windows. Существует мнение, что он создан на основе технологии Digital Equipment Corporation, поддерживает до 16 (с 2010 года) узлов в кластере, а также работу в сети SAN (Storage Area Network). Набор API-интерфейсов служит для поддержки распределяемых приложений, есть заготовки для работы с программами, не предусматривающими работы в кластере.

Windows Compute Cluster Server 2003 (CCS), выпущенный в июне 2006 года разработан для высокотехнологичных приложений, которые требуют кластерных вычислений. Издание разработано для развертывания на множестве компьютеров, которые собираются в кластер для достижения мощностей суперкомпьютера. Каждый кластер на Windows Compute Cluster Server состоит из одного или нескольких управляющих машин, распределяющих задания и нескольких подчиненных машин, выполняющих основную работу. В ноябре 2008 года представлен Windows HPC Server 2008, призванный заменить Windows Compute Cluster Server 2003.

Novell Open Enterprise Server (OES) — сетевая операционная система, «» Novell NetWare и SUSE Linux Enterprise Server; кроме прочего способная создавать смешанные кластеры, в которых ресурсы при сбое могут перемещаться с сервера NetWare на сервер Linux и наоборот.

Кластер Hyper-v из двух нод, без внешнего хранилища или гиперконвергенция на коленке

Давным-давно, в далекой-далекой галактике…, стояла передо мной задача организовать подключение нового филиала к центральному офису. В филиале доступно было два сервера, и я думал, как было бы неплохо организовать из двух серверов отказоустойчивый кластер hyper-v. Однако времена были давние, еще до выхода 2012 сервера. Для организации кластера требуется внешнее хранилище и сделать отказоустойчивость из двух серверов было в принципе невозможно.

Однако недавно я наткнулся на статью Romain Serre в которой эта проблема как раз решалась с помощью Windows Server 2016 и новой функции которая присутствует в нем — Storage Spaces Direct (S2D). Картинку я как раз позаимствовал из этой статьи, поскольку она показалась очень уместной.

Технология Storage Spaces Direct уже неоднократно рассматривалась на Хабре. Но как-то прошла мимо меня, и я не думал, что можно её применять в «народном хозяйстве». Однако это именно та технология, которая позволяет собрать кластер из двух нод, создав при этом единое общее хранилище между серверами. Некий единый рейд из дисков, которые находятся на разных серверах. Причем выход одного из дисков или целого сервера не должны привести к потере данных.

Звучит заманчиво и мне было интересно узнать, как это работает. Однако двух серверов для тестов у меня нет, поэтому я решил сделать кластер в виртуальной среде. Благо и вложенная виртуализация в hyper-v недавно появилась.

Для своих экспериментов я создал 3 виртуальные машины. На первой виртуальной машине я установил Server 2016 с GUI, на котором я поднял контроллер AD и установил средства удаленного администрирования сервера RSAT. На виртуальные машины для нод кластера я установил Server 2016 в режиме ядра. В этом месяце загадочный Project Honolulu, превратился в релиз Windows Admin Center и мне также было интересно посмотреть насколько удобно будет администрировать сервера в режиме ядра. Четвертная виртуальная машина должна будет работать внутри кластера hyper-v на втором уровне виртуализации.

Для работы кластера и службы Storage Spaces Direct необходим Windows Server Datacenter 2016. Отдельно стоит обратить внимание на аппаратные требования для Storage Spaces Direct. Сетевые адаптеры между узлами кластера должны быть >10ГБ с поддержкой удаленного прямого доступа к памяти (RDMA). Количество дисков для объединения в пул – минимум 4 (без учета дисков под операционную систему). Поддерживаются NVMe, SATA, SAS. Работа с дисками через RAID контроллеры не поддерживается. Более подробно о требованиях docs.microsoft.com

Если вы, как и я, никогда не работали со вложенной виртуализацией hyper-v, то в ней есть несколько нюансов. Во-первых, по умолчанию на новых виртуальных машинах она отключена. Если вы захотите в виртуальной машине включить роль hyper-v, то получите ошибку, о том, что оборудование не поддерживает данную роль. Во-вторых, у вложенной виртуальной машины (на втором уровне виртуализации) не будет доступа к сети. Для организации доступа необходимо либо настраивать nat, либо включать спуфинг для сетевого адаптера. Третий нюанс, для создания нод кластера, нельзя использовать динамическую память. Подробнее по ссылке.

Поэтому я создал две виртуальные машины – node1, node2 и сразу отключил динамическую память. Затем необходимо включить поддержку вложенной виртуализации:

Set-VMProcessor -VMName node1,node2 -ExposeVirtualizationExtensions $true

Включаем поддержку спуфинга на сетевых адаптерах ВМ:
Get-VMNetworkAdapter -VMName node1,node2 | Set-VMNetworkAdapter -MacAddressSpoofing On


HDD10 и HDD 20 я использовал как системные разделы на нодах. Остальные диски я добавил для общего хранилища и не размечал их.

Сетевой интерфейс Net1 у меня настроен на работу с внешней сетью и подключению к контроллеру домена. Интерфейс Net2 настроен на работу внутренней сети, только между нодами кластера.

Для сокращения изложения, я опущу действия необходимые для того, чтобы добавить ноды к домену и настройку сетевых интерфейсов. С помощью консольной утилиты sconfig это не составит большого труда. Уточню только, что установил Windows Admin Center с помощью скрипта:

msiexec /i "C:\WindowsAdminCenter1804.msi" /qn /L*v log.txt SME_PORT=6515 SSL_CERTIFICATE_OPTION=generate

По сети из расшаренной папки установка Admin Center не прошла. Поэтому пришлось включать службу File Server Role и копировать инсталлятор на каждый сервер, как в мс собственно и рекомендуют.

Когда подготовительная часть готова и перед тем, как приступать к созданию кластера, рекомендую обновить ноды, поскольку без апрельских обновлений Windows Admin Center не сможет управлять кластером.

Приступим к созданию кластера. Напомню, что все необходимые консоли у меня установлены на контролере домена. Поэтому я подключаюсь к домену и запускаю Powershell ISE под администратором. Затем устанавливаю на ноды необходимые роли для построения кластера с помощью скрипта:

$Servers = "node1","node2"
$ServerRoles = "Data-Center-Bridging","Failover-Clustering","Hyper-V","RSAT-Clustering-PowerShell","Hyper-V-PowerShell","FS-FileServer"

foreach ($server in $servers){
    Install-WindowsFeature –Computername $server –Name $ServerRoles} 

И перегружаю сервера после установки.

Запускаем тест для проверки готовности нод:

Test-Cluster –Node "node1","node2" –Include "Storage Spaces Direct", "Inventory", "Network", "System Configuration

Отчёт в фомате html сформировался в папке C:\Users\Administrator\AppData\Local\Temp. Путь к отчету утилита пишет, только если есть ошибки.

Ну и наконец создаем кластер с именем hpvcl и общим IP адресом 192.168.1.100

New-Cluster –Name hpvcl –Node "node1","node2" –NoStorage -StaticAddress 192.168.1.100 

После чего получаем ошибку, что в нашем кластере нет общего хранилища для отказоустойчивости. Запустим Failover cluster manager и проверим что у нас получилось.

Включаем (S2D)

Enable-ClusterStorageSpacesDirect –CimSession hpvcl 

И получаем оповещение, что не найдены диски для кэша. Поскольку тестовая среда у меня на SSD, а не на HDD, не будем переживать по этому поводу.

Затем подключаемся к одной из нод с помощью консоли powershell и создаем новый том. Нужно обратить внимание, что из 4 дисков по 40GB, для создания зеркального тома доступно порядка 74GB.

New-Volume -FriendlyName "Volume1" -FileSystem CSVFS_ReFS -StoragePoolFriendlyName S2D* -Size 74GB -ResiliencySettingName Mirror 

На каждой из нод, у нас появился общий том C:\ClusterStorage\Volume1.
Кластер с общим диском готов. Теперь создадим виртуальную машину VM на одной из нод и разместим её на общее хранилище.

Для настроек сети виртуальной машины, необходимо будет подключиться консолью hyper-v manager и создать виртуальную сеть с внешним доступом на каждой из нод с одинаковым именем. Затем мне пришлось перезапустить службу кластера на одной из нод, чтобы избавиться от ошибки с сетевым интерфейсом в консоли failover cluster manager.

Пока на виртуальную машину устанавливается система, попробуем подключиться к Windows Admin Center. Добавляем в ней наш гиперконвергентный кластер и получаем грустный смайлик

Подключимся к одной из нод и выполним скрипт:

Add-ClusterResourceType -Name "SDDC Management" -dll "$env:SystemRoot\Cluster\sddcres.dll" -DisplayName "SDDC Management"

Проверяем Admin Center и на этот раз получаем красивые графики

После того, как установил ОС на виртуальную машину VM внутри кластера, первым делом я проверил Live migration, переместив её на вторую ноду. Во время миграции я пинговал машину, чтобы проверить насколько быстро происходит миграция. Связь у меня пропала только на 2 запроса, что можно считать весьма неплохим результатом.

И тут стоит добавить несколько ложек дёгтя в эту гиперконвергентную бочку мёда. В тестовой и виртуальной среде все работает неплохо, но как это будет работать на реальном железе вопрос интересный. Тут стоит вернуться к аппаратным требованиям. Сетевые адаптеры 10GB с RDMA стоят порядка 500$, что в сумме с лицензией на Windows Server Datacenter делает решение не таким уж и дешёвым. Безусловно это дешевле чем выделенное хранилище, но ограничение существенное.

Вторая и основная ложка дёгтя, это новость о том, что функцию (S2D) уберут из следующей сборки server 2016 . Надеюсь, сотрудники Microsoft, читающие Хабр, это прокомментируют.

В заключении хотел бы сказать несколько слов о своих впечатлениях. Знакомство с новыми технологиями это был для меня весьма интересный опыт. Назвать его полезным, пока не могу. Я не уверен, что смогу применить эти навыки на практике. Поэтому у меня вопросы к сообществу: готовы ли вы рассматривать переход на гиперконвергентные решения в будущем? как относитесь к размещению виртуальных контроллеров домена на самих нодах?

Stratus, VMware, VMmanager Cloud / ISPsystem corporate blog / Habr

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

Мы расскажем какие есть способы защиты от сбоев серверов и какие архитектуры используют при внедрении VMmanager Cloud: продукта, который предназначен для создания кластера высокой доступности.


В области защиты от сбоев на кластерах терминология в Интернете различается от сайта к сайту. Для того чтобы избежать путаницы, мы обозначим термины и определения, которые будут использоваться в этой статье.
  • Отказоустойчивость (Fault Tolerance, FT) — способность системы к дальнейшей работе после выхода из строя какого-либо её элемента.
  • Кластер — группа серверов (вычислительных единиц), объединенных каналами связи.
  • Отказоустойчивый кластер (Fault Tolerant Cluster, FTC) — кластер, отказ сервера в котором не приводит к полной неработоспособности всего кластера. Задачи вышедшей из строя машины распределяются между одной или несколькими оставшимися нодами в автоматическом режиме.
  • Непрерывная доступность (Continuous Availability, CA) — пользователь может в любой момент воспользоваться сервисом, перерывов в предоставлении не происходит. Сколько времени прошло с момента отказа узла не имеет значения.
  • Высокая доступность (High Availability, HA) — в случае выхода из строя узла пользователь какое-то время не будет получать услугу, однако восстановление системы произойдёт автоматически; время простоя минимизируется.
  • КНД — кластер непрерывной доступности, CA-кластер.
  • КВД — кластер высокой доступности, HA-кластер.

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

На первый взгляд самый привлекательный вариант для бизнеса тот, когда в случае сбоя обслуживание пользователей не прерывается, то есть кластер непрерывной доступности. Без КНД никак не обойтись как минимум в задачах уже упомянутого биллинга абонентов и при автоматизации непрерывных производственных процессов. Однако наряду с положительными чертами такого подхода есть и “подводные камни”. О них следующий раздел статьи.


Бесперебойное обслуживание клиента возможно только в случае наличия в любой момент времени точной копии сервера (физического или виртуального), на котором запущен сервис. Если создавать копию уже после отказа оборудования, то на это потребуется время, а значит, будет перебой в предоставлении услуги. Кроме этого, после поломки невозможно будет получить содержимое оперативной памяти с проблемной машины, а значит находившаяся там информация будет потеряна.
Для реализации CA существует два способа: аппаратный и программный. Расскажем о каждом из них чуть подробнее.

Аппаратный способ представляет собой “раздвоенный” сервер: все компоненты дублированы, а вычисления выполняются одновременно и независимо. За синхронность отвечает узел, который в числе прочего сверяет результаты с половинок. В случае несоответствия выполняется поиск причины и попытка коррекции ошибки. Если ошибка не корректируется, то неисправный модуль отключается.
На Хабре недавно была статья на тему аппаратных CA-серверов. Описываемый в материале производитель гарантирует, что годовое время простоя не более 32 секунд. Так вот, для того чтобы добиться таких результатов, надо приобрести оборудование. Российский партнёр компании Stratus сообщил, что стоимость CA-сервера с двумя процессорами на каждый синхронизированный модуль составляет порядка $160 000 в зависимости от комплектации. Итого на кластер потребуется $1 600 000.

Программный способ.
На момент написания статьи самый популярный инструмент для развёртывания кластера непрерывной доступности — vSphere от VMware. Технология обеспечения Continuous Availability в этом продукте имеет название “Fault Tolerance”.

В отличие от аппаратного способа данный вариант имеет ограничения в использовании. Перечислим основные:

  • На физическом хосте должен быть процессор:
    • Intel архитектуры Sandy Bridge (или новее). Avoton не поддерживается.
    • AMD Bulldozer (или новее).
  • Машины, на которых используется Fault Tolerance, должны быть объединены в 10-гигабитную сеть с низкими задержками. Компания VMware настоятельно рекомендует выделенную сеть.
  • Не более 4 виртуальных процессоров на ВМ.
  • Не более 8 виртуальных процессоров на физический хост.
  • Не более 4 виртуальных машин на физический хост.
  • Невозможно использовать снэпшоты виртуальных машин.
  • Невозможно использовать Storage vMotion.

Полный список ограничений и несовместимостей есть в официальной документации.
Экспериментально установлено, что технология Fault Tolerance от VMware значительно “тормозит” виртуальную машину. В ходе исследования vmgu.ru после включения FT производительность ВМ при работе с базой данных упала на 47%.

Лицензирование vSphere привязано к физическим процессорам. Цена начинается с $1750 за лицензию + $550 за годовую подписку и техподдержку. Также для автоматизации управления кластером требуется приобрести VMware vCenter Server, который стоит от $8000. Поскольку для обеспечения непрерывной доступности используется схема 2N, для того чтобы работали 10 нод с виртуальными машинами, нужно дополнительно приобрести 10 дублирующих серверов и лицензии к ним. Итого стоимость программной части кластера составит 2*(10+10)*(1750+550)+8000=$100 000.

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

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

Есть Remus на базе Xen, бесплатное решение с открытым исходным кодом. Проект использует технологию микроснэпшотов. К сожалению, документация давно не обновлялась; например, установка описана для Ubuntu 12.10, поддержка которой прекращена в 2014 году. И как ни странно, даже Гугл не нашёл ни одной компании, применившей Remus в своей деятельности.

Предпринимались попытки доработки QEMU с целью добавить возможность создания continuous availability кластера. На момент написания статьи существует два таких проекта.

Первый — Kemari, продукт с открытым исходным кодом, которым руководит Yoshiaki Tamura. Предполагается использовать механизмы живой миграции QEMU. Однако тот факт, что последний коммит был сделан в феврале 2011 года говорит о том, что скорее всего разработка зашла в тупик и не возобновится.

Второй — Micro Checkpointing, основанный Michael Hines, тоже open source. К сожалению, уже год в репозитории нет никакой активности. Похоже, что ситуация сложилась аналогично проекту Kemari.

Таким образом, реализации continuous availability на базе виртуализации KVM в данный момент нет.

Итак, практика показывает, что несмотря на преимущества систем непрерывной доступности, есть немало трудностей при внедрении и эксплуатации таких решений. Однако существуют ситуации, когда отказоустойчивость требуется, но нет жёстких требований к непрерывности сервиса. В таких случаях можно применить кластеры высокой доступности, КВД.


В контексте КВД отказоустойчивость обеспечивается за счёт автоматического определения отказа оборудования и последующего запуска сервиса на исправном узле кластера.

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

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

  • Вычислительный. К нему относятся ноды, на которых непосредственно запущены виртуальные машины
  • Кластер хранилища. Тут находятся диски, которые используются нодами вычислительного подкластера.

На данный момент для реализации КВД с виртуальными машинами на нодах есть следующие инструменты:
  • Heartbeat версии 1.х в связке с DRBD;
  • Pacemaker;
  • VMware vSphere;
  • Proxmox VE;
  • XenServer;
  • Openstack;
  • oVirt;
  • Red Hat Enterprise Virtualization;
  • Windows Server Failover Clustering в связке с серверной ролью “Hyper-V”;
  • VMmanager Cloud.

Познакомим вас с особенностями нашего продукта VMmanager Cloud.
Наше решение VMmanager Cloud использует виртуализацию QEMU-KVM. Мы сделали выбор в пользу этой технологии, поскольку она активно разрабатывается и поддерживается, а также позволяет установить любую операционную систему на виртуальную машину. В качестве инструмента для выявления отказов в кластере используется Corosync. Если выходит из строя один из серверов, VMmanager поочерёдно распределяет работавшие на нём виртуальные машины по оставшимся нодам.

В упрощённой форме алгоритм такой:

  1. Происходит поиск узла кластера с наименьшим количеством виртуальных машин.
  2. Выполняется запрос хватает ли свободной оперативной памяти для размещения текущей ВМ в списке.
  3. Если памяти для распределяемой машины достаточно, то VMmanager отдаёт команду на создание виртуальной машины на этом узле.
  4. Если памяти не хватает, то выполняется поиск на серверах, которые несут на себе большее количество виртуальных машин.

Мы провели тестирование на многих конфигурациях железа, опросили существующих пользователей VMmanager Cloud и на основании полученных данных сделали вывод, что для распределения и возобновления работы всех ВМ с отказавшего узла требуется от 45 до 90 секунд в зависимости от быстродействия оборудования.

Практика показывает, что лучше выделить одну или несколько нод под аварийные ситуации и не развёртывать на них ВМ в период штатной работы. Такой подход исключает ситуацию, когда на “живых” нодах в кластере не хватает ресурсов, чтобы разместить все виртуальные машины с “умершей”. В случае с одним запасным сервером схема резервирования носит название “N+1”.

VMmanager Cloud поддерживает следующие типы хранилищ: файловая система, LVM, Network LVM, iSCSI и Ceph. В контексте КВД используются последние три.

При использовании вечной лицензии стоимость программной части кластера из десяти “боевых” узлов и одного резервного составит €3520 или $3865 на сегодняшний день (лицензия стоит €320 за ноду независимо от количества процессоров на ней). В лицензию входит год бесплатных обновлений, а со второго года они будут предоставляться в рамках пакета обновлений стоимостью €880 в год за весь кластер.

Рассмотрим по каким схемам пользователи VMmanager Cloud реализовывали кластеры высокой доступности.


Компания FirstByte начала предоставлять облачный хостинг в феврале 2016 года. Изначально кластер работал под управлением OpenStack. Однако отсутствие доступных специалистов по этой системе (как по наличию так и по цене) побудило к поиску другого решения. К новому инструменту для управления КВД предъявлялись следующие требования:
  1. Возможность предоставления виртуальных машин на KVM;
  2. Наличие интеграции с Ceph;
  3. Наличие интеграции с биллингом подходящим для предоставления имеющихся услуг;
  4. Доступная стоимость лицензий;
  5. Наличие поддержки производителя.

В итоге лучше всего по требованиям подошел VMmanager Cloud.

Отличительные черты кластера:

  • Передача данных основана на технологии Ethernet и построена на оборудовании Cisco.
  • За маршрутизацию отвечает Cisco ASR9001; в кластере используется порядка 50000 IPv6 адресов.
  • Скорость линка между вычислительными нодами и коммутаторами 10 Гбит/с.
  • Между коммутаторами и нодами хранилища скорость обмена данными 20 Гбит/с, используется агрегирование двух каналов по 10 Гбит/с.
  • Между стойками с нодами хранилища есть отдельный 20-гигабитный линк, используемый для репликации.
  • В узлах хранилища установлены SAS-диски в связке с SSD-накопителями.
  • Тип хранилища — Ceph.

В общем виде система выглядит так:

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


Компания FirstVDS предоставляет услуги отказоустойчивого хостинга, запуск продукта состоялся в сентябре 2015 года.

К использованию VMmanager Cloud компания пришла из следующих соображений:

  1. Большой опыт работы с продуктами ISPsystem.
  2. Наличие интеграции с BILLmanager по умолчанию.
  3. Отличное качество техподдержки продуктов.
  4. Поддержка Ceph.

Кластер имеет следующие особенности:
  • Передача данных основана на сети Infiniband со скоростью соединения 56 Гбит/с;
  • Infiniband-сеть построена на оборудовании Mellanox;
  • В узлах хранилища установлены SSD-носители;
  • Используемый тип хранилища — Ceph.

Общая схема выглядит так:

В случае общего отказа Infiniband-сети связь между хранилищем дисков ВМ и вычислительными серверами выполняется через Ethernet-сеть, которая развёрнута на оборудовании Juniper. “Подхват” происходит автоматически.

Благодаря высокой скорости взаимодействия с хранилищем такой кластер подходит для размещения сайтов со сверхвысокой посещаемостью, видеохостинга с потоковым воспроизведением контента, а также для выполнения операций с большими объёмами данных.


Подведём итог статьи. Если каждая секунда простоя сервиса приносит значительные убытки — не обойтись без кластера непрерывной доступности.

Однако если обстоятельства позволяют подождать 5 минут пока виртуальные машины разворачиваются на резервной ноде, можно взглянуть в сторону КВД. Это даст экономию в стоимости лицензий и оборудования.

Кроме этого не можем не напомнить, что единственное средство повышения отказоустойчивости — избыточность. Обеспечив резервирование серверов, не забудьте зарезервировать линии и оборудование передачи данных, каналы доступа в Интернет, электропитание. Всё что только можно зарезервировать — резервируйте. Такие меры исключают единую точку отказа, тонкое место, из-за неисправности в котором прекращает работать вся система. Приняв все вышеописанные меры, вы получите отказоустойчивый кластер, который действительно трудно вывести из строя.

Если вы решили, что для ваших задач больше подходит схема высокой доступности и выбрали VMmanager Cloud как инструмент для её реализации, к вашим услугам инструкция по установке и документация, которая поможет подробно ознакомиться с системой. Желаем вам бесперебойной работы!

P. S. Если у вас в организации есть аппаратные CA-серверы — напишите, пожалуйста, в комментариях кто вы и для чего вы их используете. Нам действительно интересно услышать для каких проектов использование такого оборудование экономически целесообразно 🙂

Настройка НА-кластера Kubernetes на «голом железе» с kubeadm. Часть 1/3 / Southbridge corporate blog / Habr

Часть 2/3 тут
Часть 3/3 тут

Всем привет! В этой статье я хочу упорядочить информацию и поделиться опытом создания и использования внутреннего кластера Kubernetes.

За последние несколько лет эта технология оркестровки контейнеров сделала большой шаг вперед и стала своего рода корпоративным стандартом для тысяч компаний. Некоторые используют ее в продакшене, другие просто тестируют на проектах, но страсти вокруг нее, как ни крути, пылают нешуточные. Если еще ни разу ее не использовали, самое время начать знакомство.


0. Вступление

Kubernetes — это масштабируемая технология оркестровки, которая может начинаться с установки на одной ноде и достигать размеров огромных НА-кластеров на основе нескольких сотен нод внутри. Большинство популярных облачных провайдеров представляют разные виды реализации Kubernetes — бери и пользуйся. Но ситуации бывают разные, и есть компании, которые облака не используют, а получить все преимущества современных технологий оркестровки хотят. И тут на сцену выходит инсталляция Kubernetes на «голое железо».


1. Введение

В этом примере мы создадим НА-кластер Kubernetes с топологией на несколько мастер-нод (multi masters), с внешним кластером etcd в качестве базового слоя и балансировщиком нагрузки MetalLB внутри. На всех рабочих нодах будем развертывать GlusterFS как простое внутреннее распределенное кластерное хранилище. Также попытаемся развернуть в нем несколько тестовых проектов, используя наш личный реестр Docker.

Вообще, есть несколько способов создать НА-кластер Kubernetes: трудный и углубленный путь, описанный в популярном документе kubernetes-the-hard-way, или более простой способ — с помощью утилиты kubeadm.

Kubeadm — это инструмент, созданный сообществом Kubernetes именно, чтобы упростить установку Kubernetes и облегчить процесс. Ранее Kubeadm рекомендовали только для создания небольших тестовых кластеров с одной мастер-нодой, для начала работы. Но за последний год многое улучшили, и теперь мы можем использовать его для создания HA-кластеров с несколькими мастер-нодами. Если верить новостям сообщества Kubernetes, в будущем Kubeadm будет рекомендоваться в качестве инструмента для установки Kubernetes.

Документация на Kubeadm предлагает два основных способа реализации кластера, со стековой и внешней etcd-топологией. Я выберу второй путь с внешними etcd нодами по причине отказоустойчивости НА-кластера.

Вот схема из документации Kubeadm, описывающая этот путь:

Я немного ее изменю. Во-первых, буду использовать пару серверов HAProxy в качестве балансировщиков нагрузки с пакетом Heartbeat, которые будут делить виртуальный IP-адрес. Heartbeat и HAProxy используют небольшое количество системных ресурсов, поэтому я размещу их на паре etcd нод, чтобы немного уменьшить число серверов для нашего кластера.

Для этой схемы кластера Kubernetes понадобится восемь нод. Три сервера для внешнего кластера etcd (LB-сервисы также будут использовать пару из их числа), два — для нод плоскости управления (мастер-ноды) и три — для рабочих нод. Это может быть как «голое железо», так и VM-сервер. В данном случае это не принципиально. Можно запросто изменить схему, добавив больше мастер-нод и разместив HAProxy с Heartbeat на отдельных нодах, если свободных серверов много. Хотя моего варианта для первой реализации кластера HA хватит за глаза.

А хотите — добавьте небольшой сервер с установленной утилитой kubectl для управления этим кластером или используйте для этого собственный рабочий стол Linux.

Схема для этого примера будет выглядеть примерно так:


2. Требования

Понадобятся две мастер-ноды Kubernetes с минимальными рекомендованными системными требованиями: 2 ЦП и 2 ГБ ОЗУ в соответствии с документацией kubeadm. Для рабочих нод рекомендую использовать более мощные серверы, поскольку на них будем запускать все наши сервисы приложений. А для Etcd + LB мы также можем взять серверы с двумя ЦП и минимум 2 ГБ ОЗУ.

Выберите сеть общего пользования или частную сеть для этого кластера; IP-адреса значения не имеют; важно, чтобы все серверы были доступны друг для друга и, конечно, для вас. Позже внутри кластера Kubernetes мы настроим оверлейную сеть.

Минимальные требования для этого примера:


  • 2 сервера с 2 процессорами и 2 ГБ оперативной памяти для мастер-нод
  • 3 сервера с 4 процессорами и 4-8 ГБ оперативной памяти для рабочих нод
  • 3 сервера с 2 процессорами и 2 ГБ оперативной памяти для Etcd и HAProxy
  • 192.168.0.0/24  — подсеть.

192.168.0.1 — виртуальный IP-адрес HAProxy, 192.168.0.2 — 4 основных IP-адреса нод Etcd и HAProxy, 192.168.0.5 — 6 основных IP-адресов мастер-нод Kubernetes, 192.168.0.7 — 9 основных IP-адресов рабочих нод Kubernetes.

База Debian 9 установлена на всех серверах.


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

3. Настройка HAProxy и Heartbeat.

У нас больше одной мастер-ноды Kubernetes, и поэтому необходимо настроить перед ними балансировщик нагрузки HAProxy — распределять трафик. Это будет пара серверов HAProxy с одним общим виртуальным IP-адресом. Отказоустойчивость обеспечивается при помощи пакета Heartbeat. Для развертывания мы воспользуемся первыми двумя etcd серверами.

Установим и настроим HAProxy с Heartbeat на первом и втором etcd -серверах (192.168.0.2–3 в этом примере):

etcd1# apt-get update && apt-get upgrade && apt-get install -y haproxy 
etcd2# apt-get update && apt-get upgrade && apt-get install -y haproxy

Сохраните исходную конфигурацию и создайте новую:

etcd1# mv /etc/haproxy/haproxy.cfg{,.back}
etcd1# vi /etc/haproxy/haproxy.cfg
etcd2# mv /etc/haproxy/haproxy.cfg{,.back}
etcd2# vi /etc/haproxy/haproxy.cfg

Добавьте эти параметры конфигурации для обоих HAProxy:

global
    user haproxy
    group haproxy
defaults
    mode http
    log global
    retries 2
    timeout connect 3000ms
    timeout server 5000ms
    timeout client 5000ms
frontend kubernetes
    bind 192.168.0.1:6443
    option tcplog
    mode tcp
    default_backend kubernetes-master-nodes
backend kubernetes-master-nodes
    mode tcp
    balance roundrobin
    option tcp-check
    server k8s-master-0 192.168.0.5:6443 check fall 3 rise 2
    server k8s-master-1 192.168.0.6:6443 check fall 3 rise 2

Как видите, обе службы HAProxy делят IP-адрес — 192.168.0.1. Этот виртуальный IP-адрес будет перемещаться между серверами, поэтому чутка схитрим и включим параметр net.ipv4.ip_nonlocal_bind, чтобы разрешить привязку системных служб к нелокальному IP-адресу.

Добавьте эту возможность в файл /etc/sysctl.conf:

etcd1# vi /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind=1
etcd2# vi /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind=1

Запустите на обоих серверах:

sysctl -p

Также запустите HAProxy на обоих серверах:

etcd1# systemctl start haproxy
etcd2# systemctl start haproxy

Убедитесь, что HAProxy запущены и прослушиваются по виртуальному IP-адресу на обоих серверах:

etcd1# netstat -ntlp
tcp 0 0 192.168.0.1:6443 0.0.0.0:* LISTEN 2833/haproxy
etcd2# netstat -ntlp
tcp 0 0 192.168.0.1:6443 0.0.0.0:* LISTEN 2833/haproxy

Гуд! Теперь установим Heartbeat и настроим этот виртуальный IP.

etcd1# apt-get -y install heartbeat && systemctl enable heartbeat
etcd2# apt-get -y install heartbeat && systemctl enable heartbeat

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

Сначала создайте файл /etc/ha.d/authkeys, в этом файле Heartbeat хранит данные для взаимной аутентификации. Файл должен быть одинаковым на обоих серверах:

# echo -n securepass | md5sum
bb77d0d3b3f239fa5db73bdf27b8d29a
etcd1# vi /etc/ha.d/authkeys
auth 1
1 md5 bb77d0d3b3f239fa5db73bdf27b8d29a
etcd2# vi /etc/ha.d/authkeys
auth 1
1 md5 bb77d0d3b3f239fa5db73bdf27b8d29a

Этот файл должен быть доступен только руту:

etcd1# chmod 600 /etc/ha.d/authkeys
etcd2# chmod 600 /etc/ha.d/authkeys

Теперь создадим основной файл конфигурации для Heartbeat на обоих серверах: для каждого сервера он будет немного отличаться.

Создайте /etc/ha.d/ha.cf:

etcd1

etcd1# vi /etc/ha.d/ha.cf
#       keepalive: how many seconds between heartbeats
#
keepalive 2
#
#       deadtime: seconds-to-declare-host-dead
#
deadtime 10
#
#       What UDP port to use for udp or ppp-udp communication?
#
udpport        694
bcast  ens18
mcast ens18 225.0.0.1 694 1 0
ucast ens18 192.168.0.3
#       What interfaces to heartbeat over?
udp     ens18
#
#       Facility to use for syslog()/logger (alternative to log/debugfile)
#
logfacility     local0
#
#       Tell what machines are in the cluster
#       node    nodename ...    -- must match uname -n
node    etcd1_hostname
node    etcd2_hostname

etcd2

etcd2# vi /etc/ha.d/ha.cf
#       keepalive: how many seconds between heartbeats
#
keepalive 2
#
#       deadtime: seconds-to-declare-host-dead
#
deadtime 10
#
#       What UDP port to use for udp or ppp-udp communication?
#
udpport        694
bcast  ens18
mcast ens18 225.0.0.1 694 1 0
ucast ens18 192.168.0.2
#       What interfaces to heartbeat over?
udp     ens18
#
#       Facility to use for syslog()/logger (alternative to vlog/debugfile)
#
logfacility     local0
#
#       Tell what machines are in the cluster
#       node    nodename ...    -- must match uname -n
node    etcd1_hostname
node    etcd2_hostname

Параметры «ноды» для этой конфигурации получите, запустив uname -n на обоих Etcd серверах. Также используйте имя вашей сетевой карты вместо ens18.

Наконец, нужно создать на этих серверах файл /etc/ha.d/haresources. Для обоих серверов файл должен быть одинаковым. В этом файле мы задаем наш общий IP-адрес и определяем, какая нода является главной по умолчанию:

etcd1# vi /etc/ha.d/haresources
etcd1_hostname 192.168.0.1
etcd2# vi /etc/ha.d/haresources
etcd1_hostname 192.168.0.1

Когда все готово, запускаем службы Heartbeat на обоих серверах и проверяем, что на ноде etcd1 мы получили этот заявленный виртуальный IP:

etcd1# systemctl restart heartbeat
etcd2# systemctl restart heartbeat
etcd1# ip a
ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.2/24 brd 192.168.0.255 scope global ens18
       valid_lft forever preferred_lft forever
    inet 192.168.0.1/24 brd 192.168.0.255 scope global secondary

Вы можете проверить, что HAProxy работает нормально, запустив nc по адресу 192.168.0.1 6443. Должно быть, у вас превышено время ожидания, поскольку Kubernetes API пока не прослушивается на серверной части. Но это означает, что HAProxy и Heartbeat настроены правильно.

# nc -v 192.168.0.1 6443 
Connection to 93.158.95.90 6443 port [tcp/*] succeeded!

4. Подготовка нод для Kubernetes

Следующим шагом подготовим все ноды Kubernetes. Нужно установить Docker с некоторыми дополнительными пакетами, добавить репозиторий Kubernetes и установить из него пакеты kubelet, kubeadm, kubectl. Эта настройка одинакова для всех нод Kubernetes (мастер-, рабочих и проч.)


Основное преимущество Kubeadm в том, что дополнительного ПО много не надо. Установили kubeadm на всех хостах — и пользуйтесь; хоть сертификаты CA генерируйте.

Установка Docker на всех нодах:

Update the apt package index
# apt-get update
Install packages to allow apt to use a repository over HTTPS 
# apt-get -y install \
  apt-transport-https \
  ca-certificates \
  curl \
  gnupg2 \
  software-properties-common
Add Docker’s official GPG key
# curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
Add docker apt repository
# apt-add-repository \
  "deb [arch=amd64] https://download.docker.com/linux/debian \
  $(lsb_release -cs) \
  stable"
Install docker-ce.
# apt-get update && apt-get -y install docker-ce
Check docker version
# docker -v
Docker version 18.09.0, build 4d60db4

После этого установите на всех нодах пакеты Kubernetes:


  • kubeadm: команда для загрузки кластера.
  • kubelet: компонент, который запускается на всех компьютерах в кластере и выполняет действия вроде как запуска подов и контейнеров.
  • kubectl: командная строка util для связи с кластером.
  • kubectl — по желанию; я часто устанавливаю его на всех нодах, чтобы запускать кое-какие команды Kubernetes для отладки.
# curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
Add the Google repository
# cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
Update and install packages
# apt-get update && apt-get install -y kubelet kubeadm kubectl
Hold back packages
# apt-mark hold kubelet kubeadm kubectl
Check kubeadm version
# kubeadm version 
kubeadm version: &version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.1", GitCommit:"eec55b9dsfdfgdfgfgdfgdfgdf365bdd920", GitTreeState:"clean", BuildDate:"2018-12-13T10:36:44Z", GoVersion:"go1.11.2", Compiler:"gc", Platform:"linux/amd64"}

Установив kubeadm и остальные пакеты, не забудьте отключить swap.

# swapoff -a
# sed -i '/ swap / s/^/#/' /etc/fstab

Повторите установку на остальных нодах. Пакеты ПО одинаковыми для всех нод кластера, и только следующая конфигурация определит роли, которые они получат позже.


5. Настройка кластера HA Etcd

Итак, завершив приготовления, настроим кластер Kubernetes. Первым кирпичиком будет кластер HA Etcd, который также настраивается с помощью инструмента kubeadm.


Прежде чем начнем, убедитесь, что все etcd ноды сообщаются через порты 2379 и 2380. Кроме того, между ними нужно настроить ssh-доступ — чтобы использовать scp.

Начнем с первой etcd ноды, а затем просто скопируем все необходимые сертификаты и файлы конфигурации на остальные серверы.

На всех etcd нодах нужно добавить новый файл конфигурации systemd для юнита kubelet с более высоким приоритетом:

etcd-nodes# cat << EOF > /etc/systemd/system/kubelet.service.d/20-etcd-service-manager.conf
[Service]
ExecStart=
ExecStart=/usr/bin/kubelet --address=127.0.0.1 --pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true
Restart=always
EOF

etcd-nodes# systemctl daemon-reload
etcd-nodes# systemctl restart kubelet

Затем перейдем по ssh к первой etcd ноде — ее будем использовать для генерации всех необходимых конфигураций kubeadm для каждой etcd ноды, а затем их скопируем.

# Export all our etcd nodes IP's as variables 
etcd1# export HOST0=192.168.0.2
etcd1# export HOST1=192.168.0.3
etcd1# export HOST2=192.168.0.4

# Create temp directories to store files for all nodes
etcd1# mkdir -p /tmp/${HOST0}/ /tmp/${HOST1}/ /tmp/${HOST2}/
etcd1# ETCDHOSTS=(${HOST0} ${HOST1} ${HOST2})
etcd1# NAMES=("infra0" "infra1" "infra2")

etcd1# for i in "${!ETCDHOSTS[@]}"; do
HOST=${ETCDHOSTS[$i]}
NAME=${NAMES[$i]}
cat << EOF > /tmp/${HOST}/kubeadmcfg.yaml
apiVersion: "kubeadm.k8s.io/v1beta1"
kind: ClusterConfiguration
etcd:
    local:
        serverCertSANs:
        - "${HOST}"
        peerCertSANs:
        - "${HOST}"
        extraArgs:
            initial-cluster: ${NAMES[0]}=https://${ETCDHOSTS[0]}:2380,${NAMES[1]}=https://${ETCDHOSTS[1]}:2380,${NAMES[2]}=https://${ETCDHOSTS[2]}:2380
            initial-cluster-state: new
            name: ${NAME}
            listen-peer-urls: https://${HOST}:2380
            listen-client-urls: https://${HOST}:2379
            advertise-client-urls: https://${HOST}:2379
            initial-advertise-peer-urls: https://${HOST}:2380
EOF
done

Теперь создадим основной центр сертификации, используя kubeadm

etcd1# kubeadm init phase certs etcd-ca

Эта команда создаст два файла ca.crt & ca.key в директории /etc/kubernetes/pki/etcd/.

etcd1# ls /etc/kubernetes/pki/etcd/ 
ca.crt  ca.key

Теперь сгенерируем сертификаты для всех etcd нод:

### Create certificates for the etcd3 node 
etcd1# kubeadm init phase certs etcd-server --config=/tmp/${HOST2}/kubeadmcfg.yaml
etcd1# kubeadm init phase certs etcd-peer --config=/tmp/${HOST2}/kubeadmcfg.yaml
etcd1# kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST2}/kubeadmcfg.yaml
etcd1# kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST2}/kubeadmcfg.yaml
etcd1# cp -R /etc/kubernetes/pki /tmp/${HOST2}/
### cleanup non-reusable certificates
etcd1# find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete
### Create certificates for the etcd2 node
etcd1# kubeadm init phase certs etcd-server --config=/tmp/${HOST1}/kubeadmcfg.yaml
etcd1# kubeadm init phase certs etcd-peer --config=/tmp/${HOST1}/kubeadmcfg.yaml
etcd1# kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST1}/kubeadmcfg.yaml
etcd1# kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST1}/kubeadmcfg.yaml
etcd1# cp -R /etc/kubernetes/pki /tmp/${HOST1}/
### cleanup non-reusable certificates again
etcd1# find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete
### Create certificates for the this local node
etcd1# kubeadm init phase certs etcd-server --config=/tmp/${HOST0}/kubeadmcfg.yaml
etcd1 #kubeadm init phase certs etcd-peer --config=/tmp/${HOST0}/kubeadmcfg.yaml
etcd1# kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST0}/kubeadmcfg.yaml
etcd1# kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST0}/kubeadmcfg.yaml
# No need to move the certs because they are for this node
# clean up certs that should not be copied off this host
etcd1# find /tmp/${HOST2} -name ca.key -type f -delete
etcd1# find /tmp/${HOST1} -name ca.key -type f -delete

Затем скопируем сертификаты и конфигурации kubeadm на ноды etcd2 и etcd3.


Сначала сгенерируйте пару ssh-ключей на etcd1 и добавьте открытую часть к нодам etcd2 и 3. В этом примере все команды выполняются от имени пользователя, владеющего всеми правами в системе.
etcd1# scp -r /tmp/${HOST1}/* ${HOST1}:
etcd1# scp -r /tmp/${HOST2}/* ${HOST2}:
### login to the etcd2 or run this command remotely by ssh
etcd2# cd /root
etcd2# mv pki /etc/kubernetes/
### login to the etcd3 or run this command remotely by ssh
etcd3# cd /root
etcd3# mv pki /etc/kubernetes/

Прежде чем запустить кластер etcd, убедитесь, что файлы существуют на всех нодах:

Список необходимых файлов на etcd1:

/tmp/192.168.0.2
└── kubeadmcfg.yaml
---
/etc/kubernetes/pki
├── apiserver-etcd-client.crt
├── apiserver-etcd-client.key
└── etcd
    ├── ca.crt
    ├── ca.key
    ├── healthcheck-client.crt
    ├── healthcheck-client.key
    ├── peer.crt
    ├── peer.key
    ├── server.crt
    └── server.key

Для ноды etcd2 это:

/root
└── kubeadmcfg.yaml
---
/etc/kubernetes/pki
├── apiserver-etcd-client.crt
├── apiserver-etcd-client.key
└── etcd
    ├── ca.crt
    ├── healthcheck-client.crt
    ├── healthcheck-client.key
    ├── peer.crt
    ├── peer.key
    ├── server.crt
    └── server.key

И последняя нода etcd3:

/root
└── kubeadmcfg.yaml
---
/etc/kubernetes/pki
├── apiserver-etcd-client.crt
├── apiserver-etcd-client.key
└── etcd
    ├── ca.crt
    ├── healthcheck-client.crt
    ├── healthcheck-client.key
    ├── peer.crt
    ├── peer.key
    ├── server.crt
    └── server.key

Когда все сертификаты и конфигурации на месте, создаем манифесты. На каждой ноде выполните команду kubeadm — чтобы сгенерировать статический манифест для кластера etcd:

etcd1# kubeadm init phase etcd local --config=/tmp/192.168.0.2/kubeadmcfg.yaml
etcd1# kubeadm init phase etcd local --config=/root/kubeadmcfg.yaml
etcd1# kubeadm init phase etcd local --config=/root/kubeadmcfg.yaml

Теперь кластер etcd — по идее — настроен и исправен. Проверьте, выполнив следующую команду на ноде etcd1:

etcd1# docker run --rm -it \
--net host \
-v /etc/kubernetes:/etc/kubernetes quay.io/coreos/etcd:v3.2.24 etcdctl \
--cert-file /etc/kubernetes/pki/etcd/peer.crt \
--key-file /etc/kubernetes/pki/etcd/peer.key \
--ca-file /etc/kubernetes/pki/etcd/ca.crt \
--endpoints https://192.168.0.2:2379 cluster-health
### status output
member 37245675bd09ddf3 is healthy: got healthy result from https://192.168.0.3:2379 
member 532d748291f0be51 is healthy: got healthy result from https://192.168.0.4:2379 
member 59c53f494c20e8eb is healthy: got healthy result from https://192.168.0.2:2379 
cluster is healthy

Кластер etcd поднялся, так что двигаемся дальше.


6. Настройка мастер- и рабочих нод

Настроим мастер-ноды нашего кластера — скопируйте эти файлы с первой ноды etcd на первую мастер-ноду:

etcd1# scp /etc/kubernetes/pki/etcd/ca.crt 192.168.0.5:
etcd1# scp /etc/kubernetes/pki/apiserver-etcd-client.crt 192.168.0.5:
etcd1# scp /etc/kubernetes/pki/apiserver-etcd-client.key 192.168.0.5:

Затем перейдите по ssh к мастер-ноде master1 и создайте файл kubeadm-config.yaml со следующим содержанием:

master1# cd /root && vi kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration
kubernetesVersion: stable
apiServer:
  certSANs:
  - "192.168.0.1"
controlPlaneEndpoint: "192.168.0.1:6443"
etcd:
    external:
        endpoints:
        - https://192.168.0.2:2379
        - https://192.168.0.3:2379
        - https://192.168.0.4:2379
        caFile: /etc/kubernetes/pki/etcd/ca.crt
        certFile: /etc/kubernetes/pki/apiserver-etcd-client.crt
        keyFile: /etc/kubernetes/pki/apiserver-etcd-client.key

Переместите ранее скопированные сертификаты и ключ в соответствующую директорию на ноде master1, как в описании настройки.

master1# mkdir -p /etc/kubernetes/pki/etcd/ 
master1# cp /root/ca.crt /etc/kubernetes/pki/etcd/
master1# cp /root/apiserver-etcd-client.crt /etc/kubernetes/pki/
master1# cp /root/apiserver-etcd-client.key /etc/kubernetes/pki/

Чтобы создать первую мастер-ноду, выполните:

master1# kubeadm init --config kubeadm-config.yaml

Если все предыдущие шаги выполнены правильно, вы увидите следующее:

You can now join any number of machines by running the following on each node
as root:
kubeadm join 192.168.0.1:6443 --token aasuvd.kw8m18m5fy2ot387 --discovery-token-ca-cert-hash sha256:dcbaeed8d1478291add0294553b6b90b453780e546d06162c71d515b494177a6

Скопируйте этот вывод инициализации kubeadm в любой текстовый файл, мы будем использовать этот токен в будущем, когда присоединим к нашему кластеру вторую мастер- и рабочую ноды.

Я уже говорил, что кластер Kubernetes будет использовать некую оверлейную сеть для подов и других сервисов, поэтому на этом этапе нужно установить какой-либо плагин CNI. Я рекомендую плагин Weave CNI. Опыт показал: он полезней и менее проблемный, — но вы можете выбрать другой, например, Calico.

Установка сетевого плагина Weave на первую мастер-ноду:

master1# kubectl --kubeconfig /etc/kubernetes/admin.conf apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
The connection to the server localhost:8080 was refused - did you specify the right host or port?
serviceaccount/weave-net created
clusterrole.rbac.authorization.k8s.io/weave-net created
clusterrolebinding.rbac.authorization.k8s.io/weave-net created
role.rbac.authorization.k8s.io/weave-net created
rolebinding.rbac.authorization.k8s.io/weave-net created
daemonset.extensions/weave-net created

Немного подождите, а затем введите следующую команду для проверки запуска подов компонентов:

master1# kubectl --kubeconfig /etc/kubernetes/admin.conf get pod -n kube-system -w
NAME                             READY   STATUS   RESTARTS AGE 
coredns-86c58d9df4-d7qfw         1/1     Running  0        6m25s 
coredns-86c58d9df4-xj98p         1/1     Running  0        6m25s 
kube-apiserver-master1           1/1     Running  0        5m22s 
kube-controller-manager-master1  1/1     Running  0        5m41s 
kube-proxy-8ncqw                 1/1     Running  0        6m25s 
kube-scheduler-master1           1/1     Running  0        5m25s 
weave-net-lvwrp                  2/2     Running  0        78s

  • Рекомендуется присоединять новые ноды плоскости управления только после инициализации первой ноды.

Чтобы проверить состояние кластера, выполните:

master1# kubectl --kubeconfig /etc/kubernetes/admin.conf get nodes
NAME      STATUS   ROLES    AGE   VERSION 
master1   Ready    master   11m   v1.13.1

Прекрасно! Первая мастер-нода поднялась. Теперь она готова, и мы закончим создавать кластер Kubernetes — добавим вторую мастер-ноду и рабочие ноды.
Чтобы добавить вторую мастер-ноду, создайте ssh-ключ на ноде master1 и добавьте открытую часть в ноду master2. Выполните тестовый вход в систему, а затем скопируйте кое-какие файлы с первой мастер-ноды на вторую:

master1# scp /etc/kubernetes/pki/ca.crt 192.168.0.6:
master1# scp /etc/kubernetes/pki/ca.key 192.168.0.6:
master1# scp /etc/kubernetes/pki/sa.key 192.168.0.6:
master1# scp /etc/kubernetes/pki/sa.pub 192.168.0.6:
master1# scp /etc/kubernetes/pki/front-proxy-ca.crt @192.168.0.6:
master1# scp /etc/kubernetes/pki/front-proxy-ca.key @192.168.0.6:
master1# scp /etc/kubernetes/pki/apiserver-etcd-client.crt @192.168.0.6:
master1# scp /etc/kubernetes/pki/apiserver-etcd-client.key @192.168.0.6:
master1# scp /etc/kubernetes/pki/etcd/ca.crt 192.168.0.6:etcd-ca.crt
master1# scp /etc/kubernetes/admin.conf 192.168.0.6:
### Check that files was copied well
master2# ls /root
admin.conf  ca.crt  ca.key  etcd-ca.crt  front-proxy-ca.crt  front-proxy-ca.key  sa.key  sa.pub

На второй мастер-ноде переместите ранее скопированные сертификаты и ключи в соответствующие директории:

master2#
mkdir -p /etc/kubernetes/pki/etcd
mv /root/ca.crt /etc/kubernetes/pki/
mv /root/ca.key /etc/kubernetes/pki/
mv /root/sa.pub /etc/kubernetes/pki/
mv /root/sa.key /etc/kubernetes/pki/
mv /root/apiserver-etcd-client.crt /etc/kubernetes/pki/ 
mv /root/apiserver-etcd-client.key /etc/kubernetes/pki/
mv /root/front-proxy-ca.crt /etc/kubernetes/pki/
mv /root/front-proxy-ca.key /etc/kubernetes/pki/
mv /root/etcd-ca.crt /etc/kubernetes/pki/etcd/ca.crt
mv /root/admin.conf /etc/kubernetes/admin.conf

Присоединим вторую мастер-ноду к кластеру. Для этого понадобится вывод команды соединения, который был ранее передан нам kubeadm init на первой ноде.

Запустите мастер-ноду master2:

master2# kubeadm join 192.168.0.1:6443 --token aasuvd.kw8m18m5fy2ot387 --discovery-token-ca-cert-hash sha256:dcbaeed8d1478291add0294553b6b90b453780e546d06162c71d515b494177a6 --experimental-control-plane

  • Нужно добавить флажок --experimental-control-plane. Он автоматизирует присоединение данных мастер-нод к кластеру. Без этого флажка просто добавится обычная рабочая нода.

Подождите немного, пока нода не присоединится к кластеру, и проверьте новое состояние кластера:

master1# kubectl --kubeconfig /etc/kubernetes/admin.conf get nodes
NAME      STATUS   ROLES    AGE   VERSION 
master1   Ready    master   32m   v1.13.1 
master2   Ready    master   46s   v1.13.1

Также убедитесь, что все поды со всех мастер-нод запущены нормально:

master1# kubectl — kubeconfig /etc/kubernetes/admin.conf get pod -n kube-system -w

NAME                            READY  STATUS   RESTARTS  AGE 
coredns-86c58d9df4-d7qfw        1/1    Running  0         46m 
coredns-86c58d9df4-xj98p        1/1    Running  0         46m 
kube-apiserver-master1          1/1    Running  0         45m 
kube-apiserver-master2          1/1    Running  0         15m 
kube-controller-manager-master1 1/1    Running  0         45m 
kube-controller-manager-master2 1/1    Running  0         15m 
kube-proxy-8ncqw                1/1    Running  0         46m 
kube-proxy-px5dt                1/1    Running  0         15m 
kube-scheduler-master1          1/1    Running  0         45m 
kube-scheduler-master2          1/1    Running  0         15m 
weave-net-ksvxz                 2/2    Running  1         15m 
weave-net-lvwrp                 2/2    Running  0         41m

Замечательно! Мы почти закончили конфигурацию кластера Kubernetes. И последнее, что нужно сделать, это добавить три рабочих ноды, которые мы подготовили ранее.

Войдите в рабочие ноды и выполните команду kubeadm join без флажка --experimental-control-plane.

worker1-3# kubeadm join 192.168.0.1:6443 --token aasuvd.kw8m18m5fy2ot387 --discovery-token-ca-cert-hash sha256:dcbaeed8d1478291add0294553b6b90b453780e546d06162c71d515b494177a6

Еще раз проверим состояние кластера:

master1# kubectl --kubeconfig /etc/kubernetes/admin.conf get nodes
NAME           STATUS   ROLES    AGE     VERSION 
master1   Ready    master   1h40m   v1.13.1 
master2   Ready    master   1h59m   v1.13.1 
worker1   Ready    <none>   1h8m    v1.13.1 
worker2   Ready    <none>   1h8m    v1.13.1 
worker3   Ready    <none>   1h7m    v1.13.1

Как видите, у нас есть полностью настроенный HA-кластер Kubernetes с двумя мастер- и тремя рабочими нодами. Он построен на основе кластера HA etcd с отказоустойчивым балансировщиком нагрузки перед мастер-нодами. Как по мне, звучит неплохо.


7. Настройка удаленного управления кластером

Еще одно действие, которое осталось рассмотреть в этой — первой — части статьи, это настройка удаленной утилиты kubectl для управления кластером. Ранее мы запускали все команды с мастер-ноды master1, но это подходит только для первого раза — при настройке кластера. Было бы неплохо настроить внешнюю ноду управления. Для этого можно использовать ноутбук или другой сервер.

Войдите на этот сервер и запустите:

Add the Google repository key
control# curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
Add the Google repository
control# cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
Update and install kubectl
control# apt-get update && apt-get install -y kubectl
In your user home dir create
control# mkdir ~/.kube
Take the Kubernetes admin.conf from the master1 node
control# scp 192.168.0.5:/etc/kubernetes/admin.conf ~/.kube/config
Check that we can send commands to our cluster
control# kubectl get nodes
NAME           STATUS   ROLES    AGE     VERSION 
master1        Ready    master   6h58m   v1.13.1 
master2        Ready    master   6h37m   v1.13.1 
worker1        Ready    <none>   5h46m   v1.13.1 
worker2        Ready    <none>   5h46m   v1.13.1 
worker3        Ready    <none>   5h46m   v1.13.1

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

control# kubectl create deployment nginx --image=nginx 
deployment.apps/nginx created
control# kubectl get pods 
NAME                   READY   STATUS    RESTARTS   AGE 
nginx-5c7588df-6pvgr   1/1     Running   0          52s

Поздравляю! Вы только что задеплоили Kubernetes. И это означает, что ваш новый HA-кластер готов. На самом деле, процесс настройки кластера Kubernetes с использованием kubeadm довольно простой и быстрый.

В следующей части статьи добавим внутреннее хранилище, настроив GlusterFS на всех рабочих нодах, настроим внутренний балансировщик нагрузки для нашего кластера Kubernetes, а также запустим определенные стресс-тесты, отключив кое-какие ноды, и проверим кластер на стабильность.


Послесловие

Да, работая по данному примеру, вы столкнетесь с рядом проблем. Волноваться не надо: чтобы отменить изменения и вернуть ноды в исходное состояние, просто запустите kubeadm reset — изменения, которые kubeadm внес ранее, сбросятся, и можно настраиваться заново. Также не забудьте проверить состояние Docker-контейнеров на нодах кластера — убедитесь, что все они запускаются и работают без ошибок. Для дополнительной информации о поврежденных контейнерах используйте команду docker logs containerid.

На сегодня все. Удачи!

Запускаем полноценный кластер на Kubernetes с нуля на Ubuntu 16.04 / Habr

Уже довольно много написано статей, по установке и запуску Kubernetes, однако, не всё так гладко (я потратил несколько суток на запуск своего кластера).

Данная статья призвана дать исчерпывающую информацию не только по установке k8s, но и объяснить каждый шаг: зачем и почему мы делаем именно так, как написано (это очень важно для успешного запуска).

Что нужно знать


Серверы:
Кластер подразумевает, что у Вас более одного физического сервера, между которыми и будут распределятся ресурсы. Серверы называются нодами (nodes).

Диски:
Обычные харды в k8s не поддерживаются. Работа с дисками происходит по средствам распределенных файловых хранилищ. Это необходимо для того, чтобы k8s мог «перемещать» контейнеры docker на другие ноды в случае необходимости, без потери данных (файлов).

Начинать создание кластера нужно именно с создания своего распределенного файлового хранилища. Если вы уверены, что диски вам никогда не понадобятся, то этот шаг можно пропустить.
Я выбрал Ceph. А еще рекомендую почитать эту замечательную статью.

Минимальное разумное количество серверов для Ceph — 3 (можно построить и на одном, но в этом мало смысла из-за высокой вероятности потерять данные).

Сеть:
Нам понадобится Flannel — он позволяет организовать программно определяемую сеть (Software Defined Network, SDN). Именно SDN позволяет всем нашим контейнерам общаться с друг другом внутри кластера (установка Flannel производится вместе с k8s и описана ниже).

Подготовка серверов


В нашем примере мы используем 3 физических сервера. Установите Ubuntu 16.04 на все сервера. Не создавайте swap партиции (требование k8s).

Предусмотрите в каждом сервере как минимум один диск (или партицию) для Ceph.

Не включайте поддержку SELinux (в Ubuntu 16.04 он выключен по-умолчанию).

Мы назвали сервера так: kub01 kub02 kub03. Партиция sda2 на каждом сервере создана для Ceph (форматировать не обязательно).

Установка и настройка Ceph


Установку Ceph я опишу довольно кратко. В сети много примеров и на самом сайте Ceph довольно хорошая документация.

Все операции производим из под привелигированого пользователя root.

Создадим временную директорию:

mkdir ~/ceph-admin
cd ~/ceph-admin

Установим Ceph:
apt install ceph-deploy ceph-common

Необходимо создать ключ и разложить его по всем серверам. Это нужно для утилиты ceph-deploy:
ssh-keygen
ssh-copy-id kub01
ssh-copy-id kub02
ssh-copy-id kub03

(возможно, вам понадобится поправить конфиг ssh для разрешения логинится под пользователем root).

Проверьте, что kub01 не прописан в вашем /etc/hosts как 127.0.0.1 (если прописан, удалите эту строку).

Создаем дисковый кластер и инициализируем его:

ceph-deploy new kub01 kub02 kub03
ceph-deploy install kub01 kub02 kub03
ceph-deploy mon create-initial
ceph-deploy osd prepare kub01:sda2 kub02:sda2 kub03:sda2
ceph-deploy osd activate kub01:sda2 kub02:sda2 kub03:sda2

Проверяем наш дисковый кластер:
ceph -s
    cluster 363a4cd8-4cb3-4955-96b2-73da72b63cf5
    health HEALTH_OK

Можно взять на вооружение следующие полезные команды:
ceph -s
ceph df
ceph osd tree

Теперь, когда мы убедились, что Ceph работает, мы создадим отдельный пул (pool) для k8s:
ceph osd pool create kube 100 100

(можно посмотреть все существующие пулы командой: ceph df)

Теперь создадим отдельного пользователя для нашего пула kube и сохраним ключи:

ceph auth get-or-create client.kube mon 'allow r' osd 'allow rwx pool=kube'
ceph auth get-key client.admin > /etc/ceph/client.admin
ceph auth get-key client.kube > /etc/ceph/client.kube

(ключи понадобятся для доступа k8s к хранилищу)

Устанавливаем Kubernetes


Добавим репозиторий k8s в нашу систему:
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main  
EOF

Теперь установим основные пакеты:
apt update
apt install -y docker.io kubelet kubeadm kubernetes-cni

Инициализируем и запускаем k8s
kubeadm init --pod-network-cidr=10.244.0.0/16

(именно такая сеть 10.244.0.0/16 необходима для работы flannel — не изменяйте ее)

Сохраните напечатанную скриптом команду для присоединения нод к кластеру.

Для работы с k8s удобно использовать отдельного непривилегированного пользователя. Создадим его и скопируем в него конфигурационный файл k8s:

useradd -s /bin/bash -m kube
mkdir ~kube/.kube
cp /etc/kubernetes/admin.conf ~kube/.kube/config
chown kube: ~kube/.kube/config

Для работы с k8s используется утилита: kubectl. Используем ее только из под нашего пользователя kube. Для перехода под пользователя выполним:
su - kube

Разрешаем запуск контейнеров на мастере:
kubectl taint nodes --all node-role.kubernetes.io/master-

Настраиваем права:
kubectl create clusterrolebinding add-on-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default

Устанавливаем flannel (сетевую подсистему):
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

Как проверить что всё работаетВыполните команду:
kubectl -n kube-system get pods

Вывод должен быть примерно следующим:
NAME                                      READY     STATUS    RESTARTS   AGE
etcd-kub01.domain.com                      1/1       Running   1          4d
kube-apiserver-kub01.domain.com            1/1       Running   1          4d
kube-controller-manager-kub01.domain.com   1/1       Running   0          4d
kube-dns-7c6d8859cb-dmqrn                  3/3       Running   0          1d
kube-flannel-ds-j948h                      1/1       Running   0          1d
kube-proxy-rmbqq                           1/1       Running   0          1d
kube-scheduler-kub01.domain.com            1/1       Running   1          4d


Устанавливаем и настраиваем веб-интерфейс
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml

Создаем пользователя для доступа в веб интерфейс:
cat << EOF > account.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system
EOF

kubectl -n kube-system create -f account.yaml

Запустим kube-proxy, сделать это можно так:
kubectl proxy &

И пробросим порт 8001 с вашей рабочей машины до сервера kub01:
ssh -L 8001:127.0.0.1:8001 -N kub01 &

Теперь мы можем зайти в веб интерфейс со своей рабочей машины по адресу:

http://127.0.0.1:8001/ui
(откроется веб интерфейс, где нужно указать токен)

Получить токен для доступа в веб интерфейс можно так:

kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')

Настраиваем Kubernetes и Ceph


В текущем контроллере kube-controller-manager-amd64:v1.9.2 отсутствует бинарник rbd, необходимый для работы с Ceph, поэтому создадим свой собственный kube-controller-manager:Что такое RBD, зачем он нужен и почему отсутствует?RBD (Rados Block Device) — блочное устройство, которое как раз и используется k8s для создания и монтирования партиций Docker контейнеров. В данном случае, это бинарник, входящий в состав пакета: ceph-common.

k8s не включает этот пакет в свой контроллер видимо потому, что он зависит от дистрибутива операционной системы, которую вы используете. Поэтому, при сборке своего контроллера обязательно указывайте именно Ваш дистрибутив, чтобы RBD был актуальным.


Для создания нашего kube-controller-manager сделайте следующее:
(все команды выполняем из под пользователя root)
mkdir docker
cat << EOF > docker/Dockerfile
FROM ubuntu:16.04

ARG KUBERNETES_VERSION=v1.9.2

ENV DEBIAN_FRONTEND=noninteractive \
   container=docker \
   KUBERNETES_DOWNLOAD_ROOT=https://storage.googleapis.com/kubernetes-release/release/${KUBERNETES_VERSION}/bin/linux/amd64 \
   KUBERNETES_COMPONENT=kube-controller-manager

RUN set -x \
   && apt-get update \
   && apt-get install -y \
       ceph-common \
       curl \
   && curl -L ${KUBERNETES_DOWNLOAD_ROOT}/${KUBERNETES_COMPONENT} -o /usr/bin/${KUBERNETES_COMPONENT} \
   && chmod +x /usr/bin/${KUBERNETES_COMPONENT} \
   && apt-get purge -y --auto-remove \
       curl \
   && rm -rf /var/lib/apt/lists/*
EOF

docker build -t "my-kube-controller-manager:v1.9.2" docker/

(обязательно указывайте актуальные версии k8s и дистрибутива ОС)

Проверяем, что наш контроллер успешно создан:

docker images | grep my-kube-controller-manager

Проверяем, что в нашем образе есть rbd:
docker run my-kube-controller-manager:v1.9.2 whereis rbd

Должны увидеть что-то вида: rbd: /usr/bin/rbd /usr/share/man/man8/rbd.8.gz

Заменяем стандартный контроллер нашим, для этого правим файл:
/etc/kubernetes/manifests/kube-controller-manager.yaml

Заменяем строку:
image: gcr.io/google_containers/kube-controller-manager-amd64:v1.9.2
на:
image: my-kube-controller-manager:v1.9.2
imagePullPolicy: IfNotPresent

(обязательно добавляем директиву imagePullPolicy, чтобы k8s не пытался скачивать этот образ из интернета)

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

kubectl -n kube-system describe pods | grep kube-controller

Должны увидеть, что используется наш образ:
Image: my-kube-controller-manager:v1.9.2

Теперь, когда запустился наш контроллер с поддержкой RBD, мы можем приступить к настройке связки k8s и Ceph.

Настройка связки дисковой подсистемы (k8s + Ceph)

Добавляем ключи в k8s, для доступа к Ceph:
kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" --from-file=/etc/ceph/client.admin --namespace=kube-system
kubectl create secret generic ceph-secret-kube --type="kubernetes.io/rbd" --from-file=/etc/ceph/client.kube --namespace=default

Создаем StorageClass (default):
cat << EOF > ceph_storage.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ceph-rbd
  annotations: {"storageclass.kubernetes.io/is-default-class":"true"}
provisioner: kubernetes.io/rbd
parameters:
  monitors: kub01:6789,kub02:6789,kub03:6789
  pool: kube
  adminId: admin
  adminSecretName: ceph-secret
  adminSecretNamespace: "kube-system"
  userId: kube
  userSecretName: ceph-secret-kube
  fsType: ext4
  imageFormat: "2"
  imageFeatures: "layering"
EOF

kubectl create -f ceph_storage.yaml

Как проверить работу дисковой подсистемы?Проверяем наличие StorageClass:
kube@kub01:~$ kubectl get storageclass
NAME                      PROVISIONER         AGE
ceph-rbd (default)        kubernetes.io/rbd   4d

Создадим тестовый pod с диском:
cat << EOF > test_pod.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: claim1
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: test-pod-with-pvc
spec:
  volumes:
    - name: test-pvc-storage
      persistentVolumeClaim:
        claimName: claim1
  containers:
    - name: test-container
      image: kubernetes/pause
      volumeMounts:
       - name: test-pvc-storage
         mountPath: /var/lib/www/html
EOF

kubectl create -f test_pod.yaml

Проверим, что создался Pod (нужно дождаться создания и запуска):
kube@kub01:~$ kubectl get pods
NAME                READY     STATUS    RESTARTS   AGE
test-pod-with-pvc   1/1       Running   0          15m

Проверим, что создался Claim (запрос на предоставление диска):
kube@kub01:~$ kubectl get pvc
NAME      STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
claim1    Bound     pvc-076df6ee-0ce9-11e8-8b93-901b0e8fc39b   1Gi        RWO            ceph-rbd       12m

Проверим, что создался и сам диск:
kube@kub01:~$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                        STORAGECLASS   REASON    AGE
pvc-076df6ee-0ce9-11e8-8b93-901b0e8fc39b   1Gi        RWO            Delete           Bound     default/claim1               ceph-rbd        

И наконец, проверим, что диск примонтирован в системе:
root@kub01:~$ mount | grep pvc-076df6ee-0ce9-11e8-8b93-901b0e8fc39b
/dev/rbd0 on /var/lib/kubelet/pods/076fff13-0ce9-11e8-8b93-901b0e8fc39b/volumes/kubernetes.io~rbd/pvc-076df6ee-0ce9-11e8-8b93-901b0e8fc39b type ext4 (rw,relatime,stripe=1024,data=ordered)


Добавление новых (дополнительных) нод в кластер k8s


На новом сервере выполните следующие команды:
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main  
EOF

apt update
apt install -y  docker.io kubelet kubeadm kubernetes-cni ceph-common python

Присоединяем ноду к мастеру:
Нам нужен ключ. Его можно получить на мастере, выполнив команду:
kubeadm token list

Либо, создать его:
kubeadm token create --print-join-command

Пример команды для присоединения (выполняем на новой ноде):

kubeadm join --token cb9141.6a912d1dd7f66ff5 8.8.8.8:6443 --discovery-token-ca-cert-hash sha256:f0ec6d8f9699169089c89112e0e6b5905b4e1b42db22815186240777970dc6fd

Установка и настройка Helm


Для быстрой и простой установки приложений в k8s был придуман Helm.

Список доступных приложений можно найти здесь.

Устанавливаем и инициализируем Helm:

curl https://storage.googleapis.com/kubernetes-helm/helm-v2.8.0-linux-amd64.tar.gz | tar -xz
./linux-amd64/helm init

P.S.: на написание этой статьи ушло 6 часов. Не судите строго, если где-то есть опечатки. Задавайте вопросы, с радостью отвечу и помогу.

установка, настройка сети, ZFS, решение распространенных проблем / Habr

За последние несколько лет я очень тесно работаю с кластерами Proxmox: многим клиентам требуется своя собственная инфраструктура, где они могут развивать свой проект. Именно поэтому я могу рассказать про самые распространенные ошибки и проблемы, с которыми также можете столкнуться и вы. Помимо этого мы конечно же настроим кластер из трех нод с нуля.


Proxmox кластер может состоять из двух и более серверов. Максимальное количество нод в кластере равняется 32 штукам. Наш собственный кластер будет состоять из трех нод на мультикасте (в статье я также опишу, как поднять кластер на уникасте — это важно, если вы базируете свою кластерную инфраструктуру на Hetzner или OVH, например). Коротко говоря, мультикаст позволяет осуществлять передачу данных одновременно на несколько нод. При мультикасте мы можем не задумываться о количестве нод в кластере (ориентируясь на ограничения выше).

Сам кластер строится на внутренней сети (важно, чтобы IP адреса были в одной подсети), у тех же Hetzner и OVH есть возможность объединять в кластер ноды в разных датацентрах с помощью технологии Virtual Switch (Hetzner) и vRack (OVH) — о Virtual Switch мы также поговорим в статье. Если ваш хостинг-провайдер не имеет похожие технологии в работе, то вы можете использовать OVS (Open Virtual Switch), которая нативно поддерживается Proxmox, или использовать VPN. Однако, я рекомендую в данном случае использовать именно юникаст с небольшим количеством нод — часто возникают ситуации, где кластер просто “разваливается” на основе такой сетевой инфраструктуры и его приходится восстанавливать. Поэтому я стараюсь использовать именно OVH и Hetzner в работе — подобных инцидентов наблюдал в меньшем количестве, но в первую очередь изучайте хостинг-провайдера, у которого будете размещаться: есть ли у него альтернативная технология, какие решения он предлагает, поддерживает ли мультикаст и так далее.

Установка Proxmox


Proxmox может быть установлен двумя способами: ISO-инсталлятор и установка через shell. Мы выбираем второй способ, поэтому установите Debian на сервер.

Перейдем непосредственно к установке Proxmox на каждый сервер. Установка предельно простая и описана в официальной документации здесь.

Добавим репозиторий Proxmox и ключ этого репозитория:

echo "deb http://download.proxmox.com/debian/pve stretch pve-no-subscription" > /etc/apt/sources.list.d/pve-install-repo.list
wget http://download.proxmox.com/debian/proxmox-ve-release-5.x.gpg -O /etc/apt/trusted.gpg.d/proxmox-ve-release-5.x.gpg
chmod +r /etc/apt/trusted.gpg.d/proxmox-ve-release-5.x.gpg  # optional, if you have a changed default umask

Обновляем репозитории и саму систему:
apt update && apt dist-upgrade

После успешного обновления установим необходимые пакеты Proxmox:
apt install proxmox-ve postfix open-iscsi

Заметка: во время установки будет настраиваться Postfix и grub — одна из них может завершиться с ошибкой. Возможно, это будет вызвано тем, что хостнейм не резолвится по имени. Отредактируйте hosts записи и выполните apt-get update

С этого момента мы можем авторизоваться в веб-интерфейс Proxmox по адресу https://<внешний-ip-адрес>:8006 (столкнетесь с недоверенным сертификатом во время подключения).


Изображение 1. Веб-интерфейс ноды Proxmox

Установка Nginx и Let’s Encrypt сертификата


Мне не очень нравится ситуация с сертификатом и IP адресом, поэтому я предлагаю установить Nginx и настроить Let’s Encrypt сертификат. Установку Nginx описывать не буду, оставлю лишь важные файлы для работы Let’s encrypt сертификата:/etc/nginx/snippets/letsencrypt.conf
location ^~ /.well-known/acme-challenge/ {
  allow all;
  root /var/lib/letsencrypt/;
  default_type "text/plain";
  try_files $uri =404;
}

Команда для выпуска SSL сертификата:
certbot certonly --agree-tos --email [email protected] --webroot -w /var/lib/letsencrypt/ -d proxmox1.domain.name

Конфигурация сайта в NGINX
upstream proxmox1.domain.name  {
      server 127.0.0.1:8006;
}

server {
    listen 80;
    server_name proxmox1.domain.name;

    include snippets/letsencrypt.conf;
    return 301 https://$host$request_uri;
}


server {
    listen 443 ssl;

    server_name  proxmox1.domain.name;

    access_log  /var/log/nginx/proxmox1.domain.name.access.log;
    error_log  /var/log/nginx/proxmox1.domain.name.error.log;

    include snippets/letsencrypt.conf;

    ssl_certificate /etc/letsencrypt/live/proxmox1.domain.name/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/proxmox1.domain.name/privkey.pem;

    location / {
        proxy_pass  https://proxmox1.domain.name;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503                                                                              http_504;
        proxy_redirect off;
        proxy_buffering off;
        proxy_set_header        Host            $host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
   
}


Не забываем после установки SSL сертификата поставить его на автообновление через cron:
0 */12 * * * /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew --renew-hook "systemctl reload nginx"

Отлично! Теперь мы можем обращаться к нашему домену по HTTPS.

Заметка: чтобы отключить информационное окно о подписке, выполните данную команду:

sed -i.bak "s/data.status !== 'Active'/false/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && systemctl restart pveproxy.service

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

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

Создадим сетевой мост для внутренней сети, чтобы наши виртуальные машины (в моем варианте будет LXC контейнер для удобства) во-первых, были подключены к внутренней сети гипервизора и могли взаимодействовать друг с другом. Во-вторых, чуть позже мы добавим мост для внешней сети, чтобы виртуальные машины имели свой внешний IP адрес. Соответственно, контейнеры будут на данный момент за NAT’ом у нас.

Работать с сетевой конфигурацией Proxmox можно двумя способами: через веб-интерфейс или через конфигурационный файл /etc/network/interfaces. В первом варианте вам потребуется перезагрузка сервера (или можно просто переименовать файл interfaces.new в interfaces и сделать перезапуск networking сервиса через systemd). Если вы только начинаете настройку и еще нет виртуальных машин или LXC контейнеров, то желательно перезапускать гипервизор после изменений.

Теперь создадим сетевой мост под названием vmbr1 во вкладке network в веб-панели Proxmox.


Изображение 2. Сетевые интерфейсы ноды proxmox1


Изображение 3. Создание сетевого моста


Изображение 4. Настройка сетевой конфигурации vmbr1

Настройка предельно простая — vmbr1 нам нужен для того, чтобы инстансы получали доступ в Интернет.

Теперь перезапускаем наш гипервизор и проверяем, создался ли интерфейс:


Изображение 5. Сетевой интерфейс vmbr1 в выводе команды ip a

Заметьте: у меня уже есть интерфейс ens19 — это интерфейс с внутренней сетью, на основе ее будет создан кластер.

Повторите данные этапы на остальных двух гипервизорах, после чего приступите к следующему шагу — подготовке кластера.

Также важный этап сейчас заключается во включении форвардинга пакетов — без нее инстансы не будут получать доступ к внешней сети. Открываем файл sysctl.conf и изменяем значение параметра net.ipv4.ip_forward на 1, после чего вводим следующую команду:

sysctl -p

В выводе вы должны увидеть директиву net.ipv4.ip_forward (если не меняли ее до этого)

Настройка Proxmox кластера

Теперь перейдем непосредственно к кластеру. Каждая нода должна резолвить себя и другие ноды по внутренней сети, для этого требуется изменить значения в hosts записях следующих образом (на каждой ноде должна быть запись о других):

172.30.0.15 proxmox1.livelinux.info proxmox1
172.30.0.16 proxmox2.livelinux.info proxmox2
172.30.0.17 proxmox3.livelinux.info proxmox3

Также требуется добавить публичные ключи каждой ноды к остальным — это требуется для создания кластера.

Создадим кластер через веб-панель:


Изображение 6. Создание кластера через веб-интерфейс

После создания кластера нам необходимо получить информацию о нем. Переходим в ту же вкладку кластера и нажимаем кнопку “Join Information”:


Изображение 7. Информация о созданном кластере

Данная информация пригодится нам во время присоединения второй и третьей ноды в кластер. Подключаемся к второй ноде и во вкладке Cluster нажимаем кнопку “Join Cluster”:


Изображение 8. Подключение к кластеру ноды

Разберем подробнее параметры для подключения:

  1. Peer Address: IP адрес первого сервера (к тому, к которому мы подключаемся)
  2. Password: пароль первого сервера
  3. Fingerprint: данное значение мы получаем из информации о кластере


Изображение 9. Состояние кластера после подключения второй ноды

Вторая нода успешно подключена! Однако, такое бывает не всегда. Если вы неправильно выполните шаги или возникнут сетевые проблемы, то присоединение в кластер будет провалено, а сам кластер будет “развален”. Лучшее решение — это отсоединить ноду от кластера, удалить на ней всю информацию о самом кластере, после чего сделать перезапуск сервера и проверить предыдущие шаги. Как же безопасно отключить ноду из кластера? Для начала удалим ее из кластера на первом сервере:

pvecm del proxmox2

После чего нода будет отсоединена от кластера. Теперь переходим на сломанную ноду и отключаем на ней следующие сервисы:
systemctl stop pvestatd.service
systemctl stop pvedaemon.service
systemctl stop pve-cluster.service
systemctl stop corosync
systemctl stop pve-cluster

Proxmox кластер хранит информацию о себе в sqlite базе, ее также необходимо очистить:
sqlite3 /var/lib/pve-cluster/config.db
delete from tree where name = 'corosync.conf';
.quit

Данные о коросинке успешно удалены. Удалим оставшиеся файлы, для этого необходимо запустить кластерную файловую систему в standalone режиме:
pmxcfs -l
rm /etc/pve/corosync.conf
rm /etc/corosync/*
rm /var/lib/corosync/*
rm -rf /etc/pve/nodes/*

Перезапускаем сервер (это необязательно, но перестрахуемся: все сервисы по итогу должны быть запущены и работать корректно. Чтобы ничего не упустить делаем перезапуск). После включения мы получим пустую ноду без какой-либо информации о предыдущем кластере и можем начать подключение вновь.

Установка и настройка ZFS


ZFS — это файловая система, которая может использоваться совместно с Proxmox. С помощью нее можно позволить себе репликацию данных на другой гипервизор, миграцию виртуальной машины/LXC контейнера, доступ к LXC контейнеру с хост-системы и так далее. Установка ее достаточно простая, приступим к разбору. На моих серверах доступно три SSD диска, которые мы объединим в RAID массив.

Добавляем репозитории:

nano /etc/apt/sources.list.d/stretch-backports.list

deb http://deb.debian.org/debian stretch-backports main contrib
deb-src http://deb.debian.org/debian stretch-backports main contrib

nano /etc/apt/preferences.d/90_zfs

Package: libnvpair1linux libuutil1linux libzfs2linux libzpool2linux spl-dkms zfs-dkms zfs-test zfsutils-linux zfsutils-linux-dev zfs-zed
Pin: release n=stretch-backports
Pin-Priority: 990

Обновляем список пакетов:
apt update

Устанавливаем требуемые зависимости:
 apt install --yes dpkg-dev linux-headers-$(uname -r) linux-image-amd64

Устанавливаем сам ZFS:
apt-get install zfs-dkms zfsutils-linux

Если вы в будущем получите ошибку fusermount: fuse device not found, try ‘modprobe fuse’ first, то выполните следующую команду:
modprobe fuse

Теперь приступим непосредственно к настройке. Для начала нам требуется отформатировать SSD и настроить их через parted:Настройка /dev/sda
parted /dev/sda

(parted) print
Model: ATA SAMSUNG MZ7LM480 (scsi)
Disk /dev/sda: 480GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number  Start   End     Size    Type     File system  Flags
 1      1049kB  4296MB  4295MB  primary               raid
 2      4296MB  4833MB  537MB   primary               raid
 3      4833MB  37,0GB  32,2GB  primary               raid

(parted) mkpart
Partition type?  primary/extended? primary
File system type?  [ext2]? zfs
Start? 33GB
End? 480GB
Warning: You requested a partition from 33,0GB to 480GB (sectors 64453125..937500000).
The closest location we can manage is 37,0GB to 480GB (sectors 72353792..937703087).
Is this still acceptable to you?
Yes/No? yes


Аналогичные действия необходимо произвести и для других дисков. После того, как все диски подготовлены, приступаем к следующему шагу:

zpool create -f -o ashift=12 rpool /dev/sda4 /dev/sdb4 /dev/sdc4

Мы выбираем ashift=12 из соображений производительности — это рекомендация самого zfsonlinux, подробнее про это можно почитать в их вики: github.com/zfsonlinux/zfs/wiki/faq#performance-considerations

Применим некоторые настройки для ZFS:

zfs set atime=off rpool
zfs set compression=lz4 rpool
zfs set dedup=off rpool
zfs set snapdir=visible rpool
zfs set primarycache=all rpool
zfs set aclinherit=passthrough rpool
zfs inherit acltype rpool
zfs get -r acltype rpool
zfs get all rpool | grep compressratio

Теперь нам надо рассчитать некоторые переменные для вычисления zfs_arc_max, я это делаю следующим образом:
mem =`free --giga | grep Mem | awk '{print $2}'`
partofmem=$(($mem/10))
echo $setzfscache > /sys/module/zfs/parameters/zfs_arc_max
grep c_max /proc/spl/kstat/zfs/arcstats

zfs create rpool/data
cat > /etc/modprobe.d/zfs.conf << EOL
options zfs zfs_arc_max=$setzfscache
EOL

echo $setzfscache > /sys/module/zfs/parameters/zfs_arc_max
grep c_max /proc/spl/kstat/zfs/arcstats

В данный момент пул успешно создан, также мы создали сабпул data. Проверить состояние вашего пула можно командой zpool status. Данное действие необходимо провести на всех гипервизорах, после чего приступить к следующему шагу.

Теперь добавим ZFS в Proxmox. Переходим в настройки датацентра (именно его, а не отдельной ноды) в раздел «Storage», кликаем на кнопку «Add» и выбираем опцию «ZFS», после чего мы увидим следующие параметры:

ID: Название стораджа. Я дал ему название local-zfs
ZFS Pool: Мы создали rpool/data, его и добавляем сюда.
Nodes: указываем все доступные ноды

Данная команда создает новый пул с выбранными нами дисками. На каждом гипервизоре должен появится новый storage под названием local-zfs, после чего вы сможете смигрировать свои виртуальные машины с локального storage на ZFS.

Репликация инстансов на соседний гипервизор


В кластере Proxmox есть возможность репликации данных с одного гипервизора на другой: данный вариант позволяет осуществлять переключение инстанса с одного сервера на другой. Данные будут актуальны на момент последней синхронизации — ее время можно выставить при создании репликации (стандартно ставится 15 минут). Существует два способа миграции инстанса на другую ноду Proxmox: ручной и автоматический. Давайте рассмотрим в первую очередь ручной вариант, а в конце я предоставлю вам Python скрипт, который позволит создавать виртуальную машину на доступном гипервизоре при недоступности одного из гипервизоров.

Для создания репликации необходимо перейти в веб-панель Proxmox и создать виртуальную машину или LXC контейнер. В предыдущих пунктах мы с вами настроили vmbr1 мост с NAT, что позволит нам выходить во внешнюю сеть. Я создам LXC контейнер с MySQL, Nginx и PHP-FPM с тестовым сайтом, чтобы проверить работу репликации. Ниже будет пошаговая инструкция.

Загружаем подходящий темплейт (переходим в storage —> Content —> Templates), пример на скриншоте:


Изображение 10. Local storage с шаблонами и образами ВМ

Нажимаем кнопку “Templates” и загружаем необходимый нам шаблон LXC контейнера:


Изображение 11. Выбор и загрузка шаблона

Теперь мы можем использовать его при создании новых LXC контейнеров. Выбираем первый гипервизор и нажимаем кнопку “Create CT” в правом верхнем углу: мы увидим панель создания нового инстанса. Этапы установки достаточно просты и я приведу лишь конфигурационный файл данного LXC контейнера:

arch: amd64
cores: 3
memory: 2048
nameserver: 8.8.8.8
net0: name=eth0,bridge=vmbr1,firewall=1,gw=172.16.0.1,hwaddr=D6:60:C5:39:98:A0,ip=172.16.0.2/24,type=veth
ostype: centos
rootfs: local:100/vm-100-disk-1.raw,size=10G
swap: 512
unprivileged: 

Контейнер успешно создан. К LXC контейнерам можно подключаться через команду pct enter , я также перед установкой добавил SSH ключ гипервизора, чтобы подключаться напрямую через SSH (в PCT есть небольшие проблемы с отображением терминала). Я подготовил сервер и установил туда все необходимые серверные приложения, теперь можно перейти к созданию репликации.

Кликаем на LXC контейнер и переходим во вкладку “Replication”, где создаем параметр репликации с помощью кнопки “Add”:


Изображение 12. Создание репликации в интерфейсе Proxmox


Изображение 13. Окно создания Replication job

Я создал задачу реплицировать контейнер на вторую ноду, как видно на следующем скриншоте репликация прошла успешно — обращайте внимание на поле “Status”, она оповещает о статусе репликации, также стоит обращать внимание на поле “Duration”, чтобы знать, сколько длится репликация данных.


Изображение 14. Список синхронизаций ВМ

Теперь попробуем смигрировать машину на вторую ноду с помощью кнопки “Migrate”

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

Ошибка “Host Key Verification Failed”

Иногда при настройке кластера может возникать подобная проблема — она мешает мигрировать машины и создавать репликацию, что нивелирует преимущества кластерных решений. Для исправления этой ошибки удалите файл known_hosts и подключитесь по SSH к конфликтной ноде:

/usr/bin/ssh -o 'HostKeyAlias=proxmox2' [email protected]

Примите Hostkey и попробуйте ввести эту команду, она должна подключить вас к серверу:
/usr/bin/ssh -o 'BatchMode=yes' -o 'HostKeyAlias=proxmox2' [email protected]

Особенности сетевых настроек на Hetzner


Переходим в панель Robot и нажимаем на кнопку “Virtual Switches”. На следующей странице вы увидите панель создания и управления интерфейсов Virtual Switch: для начала его необходимо создать, а после “подключить” выделенные сервера к нему. В поиске добавляем необходимые сервера для подключения — их не не нужно перезагружать, только придется подождать до 10-15 минут, когда подключение к Virtual Switch будет активно.

После добавления серверов в Virtual Switch через веб-панель подключаемся к серверам и открываем конфигурационные файлы сетевых интерфейсов, где создаем новый сетевой интерфейс:

auto enp4s0.4000
iface enp4s0.4000 inet static
        address  10.1.0.11/24
        mtu 1400
        vlan-raw-device enp4s0

Давайте разберем подробнее, что это такое. По своей сути — это VLAN, который подключается к единственному физическому интерфейсу под названием enp4s0 (он у вас может отличаться), с указанием номера VLAN — это номер Virtual Switch’a, который вы создавали в веб-панели Hetzner Robot. Адрес можете указать любой, главное, чтобы он был локальный.

Отмечу, что конфигурировать enp4s0 следует как обычно, по сути он должен содержать внешний IP адрес, который был выдан вашему физическому серверу. Повторите данные шаги на других гипервизорах, после чего перезагрузите на них networking сервис, сделайте пинг до соседней ноды по IP адресу Virtual Switch. Если пинг прошел успешно, то вы успешно установили соединение между серверами по Virtual Switch.

Я также приложу конфигурационный файл sysctl.conf, он понадобится, если у вас будут проблемы с форвардингом пакетом и прочими сетевыми параметрами:

net.ipv6.conf.all.disable_ipv6=0
net.ipv6.conf.default.disable_ipv6 = 0
net.ipv6.conf.all.forwarding=1
net.ipv4.conf.all.rp_filter=1
net.ipv4.tcp_syncookies=1
net.ipv4.ip_forward=1
net.ipv4.conf.all.send_redirects=0

Добавление IPv4 подсети в Hetzner

Перед началом работ вам необходимо заказать подсеть в Hetzner, сделать это можно через панель Robot.

Создадим сетевой мост с адресом, который будет из этой подсети. Пример конфигурации:

auto vmbr2
iface vmbr2 inet static
        address ip-address
        netmask 29
        bridge-ports none
        bridge-stp off
        bridge-fd 0

Теперь переходим в настройки виртуальной машины в Proxmox и создаем новый сетевой интерфейс, который будет прикреплен к мосту vmbr2. Я использую LXC контейнер, его конфигурацию можно изменять сразу же в Proxmox. Итоговая конфигурация для Debian:
auto eth0
iface eth0 inet static
        address ip-address
        netmask 26
        gateway bridge-address

Обратите внимание: я указал 26 маску, а не 29 — это требуется для того, чтобы сеть на виртуальной машине работала.

Добавление IPv4 адреса в Hetzner

Ситуация с одиночным IP адресом отличается — обычно Hetzner дает нам дополнительный адрес из подсети сервера. Это означает, что вместо vmbr2 нам требуется использоваться vmbr0, но на данный момент его у нас нет. Суть в том, что vmbr0 должен содержать IP адрес железного сервера (то есть использовать тот адрес, который использовал физический сетевой интерфейс enp2s0). Адрес необходимо переместить на vmbr0, для этого подойдет следующая конфигурация (советую заказать KVM, чтобы в случае чего возобновить работу сети):

auto enp2s0
iface enp2s0 inet manual

auto vmbr0
iface vmbr0 inet static
        address  ip-address
        netmask  255.255.255.192
        gateway  ip-gateway
        bridge-ports enp2s0
        bridge-stp off
        bridge-fd 0

Перезапустите сервер, если это возможно (если нет, перезапустите сервис networking), после чего проверьте сетевые интерфейсы через ip a:
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master vmbr0 state UP group default qlen 1000
    link/ether 44:8a:5b:2c:30:c2 brd ff:ff:ff:ff:ff:ff

Как здесь видно, enp2s0 подключен к vmbr0 и не имеет IP адрес, так как он был переназначен на vmbr0.

Теперь в настройках виртуальной машины добавляем сетевой интерфейс, который будет подключен к vmbr0. В качестве gateway укажите адрес, прикрепленный к vmbr0.

В завершении


Надеюсь, что данная статья пригодится вам, когда вы будете настраивать Proxmox кластер в Hetzner. Если позволит время, то я расширю статью и добавлю инструкцию для OVH — там тоже не все очевидно, как кажется на первый взгляд. Материал получился достаточно объемным, если найдете ошибки, то, пожалуйста, напишите в комментарии, я их исправлю. Всем спасибо за уделенное внимание.

Автор: Илья Андреев, под редакцией Алексея Жадан и команды «Лайв Линукс»

сетевые соединения и динамическое размещение ресурсов кластера / Habr

Ноды кластера очень сильно зависят от их физического соединения. Как показывает практика, большинство случаев отработки failove-миграций ресурсов происходит по вине именно сетевых соединений. Поэтому от того, как у вас осуществляется соединение между нодами и настроены размещения ресурсов, зависит очень многое.

Для примера, я буду рассматривать кластер состоящий из двух нод. Одна нода будет в состоянии Active, а другая в состоянии Hot Spare. Наш кластер будет обслуживать внутреннюю приватную сеть и содержать следующие ресурсы кластера: Mysql сервер и Mysql VIP. На двух нодах Mysql сервер будет запущен c репликацией Master-Master. Однако вся работа будет производиться только с одним экземпляром через виртуальный ip адрес. Такая схема позволяет получить максимально быстрый failover. Опустим выбор именно данной конфигурации её плюсы и минусы — нас сейчас интересует доступность этих ресурсов в случае падения сетевых линков.


рис. 1 Схема класстера

Главное на что следует обратить внимание при проектировании любого кластера это избыточность сетевого соединения между нодами кластера. Другими словами должны быть как минимум два крос-соединения между нашими нодами. Их можно объединить посредствам бондинга в один интерфейс либо просто использовать два разных интерфейса в конфигурации heartbeat или corosynс. При проектировании нового кластера я бы рекомендовал использовать corosync, не только потому что разработка heartbeat потихоньку сворачивается в сторону pacemaker и corosync, а потому, что он обладает более гибкими настройками для работы с несколькими интерфейсами и может использовать их параллельно или в режиме “действующий и запасной”.

Не следование правилам резервирования или выделения отдельных сетевых интерфейсов может привести к ситуации расщепления разума (split brain). Что в принципе не сулит ничего хорошего. Также удостоверьтесь что используете разные сетевые карты, а то будет не много толку при аппаратном сбое.

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

	crm configure property no-quorum-policy="ignore" 

Так же для кластера из двух нод я рекомендую делать кластер не симметричным. Это позволит более точно провести его настройку и отловить странное поведение:
	crm configure property symmetric-cluster="false"

Несимметричный кластер не будет запускать ресурсы если у них явно не указаны значения стоимости их запуска на каждой из нод. К примеру, вот так мы можем задать значение 100 для некого ресурса P_RESOURCE для ноды first.local и значиение 10 — для ноды second.local.
	location  L_RESOURCE_01 P_RESOURCE 100: first.local
	location  L_RESOURCE_02 P_RESOURCE  10: second.local

Данная конфигурация говорит нам, что ресурс запустится на ноде first.local — т.к. у него суммарная стоимость на этой ноде оказалась больше чем на ноде second.local.

Я умышленно опускаю первичные настройки нод, настройку бондига (по желанию), установку pacemaker и corosync, настройку Master-Master реплиацию и т.д. Этого и так достаточно в интернетах и легко находится. В свою очередь я покажу как нужно правильно настраивать ресурсы кластера с учётом сетевой специфики.

Условимся, что у нас приватная сеть: 192.168.56.0/24, Mysql VIP — 192.168.56.133 и две ноды в сети, которые мы будем использовать для оценки адекватности сетевого соединения: 192.168.56.1 и 192.168.56.100.

Небольшое отступление: для правильной работы Mysql в связке с pacemaker нужно отключить его автоматический старт:

	chkconfig mysql --list
	mysql 0:off 1:off 2:off 3:off 4:off 5:off 6:off

Т.к. Муsql сервер используется только в приватной сети — падение приватного коннекта на активной ноде должно приводить к миграции ресурса на другую ноду, где коннект присутсвует. Добьёмся такого поведения.

Мы должны проверять состояния хостов в приватной сети. Для этого мы будем использовать ресурс кластера ping. В данный момент существуют следующие ресурсы, которые позволяют производить мониторинг состояния сети:

	ocf:heartbeat:pingd (Deprecated)
	ocf:pacemaker:pingd (Deprecated)
	ocf:pacemaker:ping

Два из которых являются устаревшими.

На основе этих ресурсов мы можем управлять размещением ресурсов на нодах. Делается это при помощи параметра location.

Для примера, сначала, опишем конфигурацию pacemaker кластера показанную на рисунке (рис. 1):

	crm configure
	primitive P_MYSQL lsb:mysql
	primitive P_MYSQL_IP ocf:heartbeat:IPaddr2 params \ 
		ip="192.168.56.133" nic="eth0"
	clone CL_MYSQL P_MYSQL clone-max="2" clone-node-max="1" \
 		globally-unique="false"

Данная конфигурация описывает кластер из двух нод с двумя Mysql мастерами (клонированными). Работа с базой ведётся через VIP адрес.
Для случае несемметричного кластера нам необходимо явно задать значения для location:
	location L_MYSQL_01 CL_MYSQL 100: first.local
	location L_MYSQL_02 CL_MYSQL 100: second.local

Данная запись говорит нам о том, что ресурc типа “clone” стоит запускать на двух нодах кластера.

Теперь тоже самое для VIP:

	location L_MYSQL_IP_01 P_MYSQL_IP 100: first.local
	location L_MYSQL_IP_02 P_MYSQL_IP  10: second.local

Здесь мы отдаём предпочтение на запуск VIP на ноде first.local
И завершаем настройку:
	commit

Если теперь проверить как работает failover — то при запуске VIP стартует на first.local при её падении (kill -9 corosync) — он переезжает на second.local. Однако при возвращении ноды first.local — он возвращается обратно. Это связано с тем, что значение score для first.local болше чем на secon.local (100 > 10). Чтобы предотвратить такие переезды на высоконагруженном кластере, которые могут привести к нежелательным простоям, мы должны задать параметр “липкости” (resource-stickiness):
	crm configure property rsc_defaults resource-stickiness="110"

Теперь повторяя ту же операцию мы имеем значение score: 110+10=120 против 100, что предотвращает переезд.

Кластер работает и позволяет в случае неполадок с железом/питанием переключаться автоматически на резервную ноду.
Теперь настроем мониторинг внутренней сети. Будем пинговать 192.168.56.1 и 192.168.56.100:

	crm configure
	primitive P_INTRANET ocf:pacemaker:ping \
		params host_list="192.168.56.1 192.168.56.100"  \
		multiplier="111" name="ping_intranet" \ 
		op monitor interval="5s" timeout="20s"
	clone CL_INTRANET P_INTRANET globally-unique="false"
	location L_INTRANET_01 CL_INTRANET 100: first.local
	location L_INTRANET_02 CL_INTRANET 100: second.local
	commit

Данная конфигурация пингует два хоста. Каждый хост оценивается в 111 очков. Суммарное значение для каждой ноды хранится в переменной ping_intranet. Эти значения можно и нужно использовать при определении места расположения ресурса. Теперь укажем VIP чтобы он использовал эти очки в решении, где ему находиться:
	crm configure
	location L_MYSQL_IP_PING_INTRANET P_MYSQL_IP  rule \
		ping_intranet: defined intranet
	commit

Эти дополнительные очки сумируются с пердыдущими заданными нами. И исходя из итоговой суммы определяется положение ресурса.
Мониторинг состояния кластера с указанием значении score производиться двумя утилитами: ptest и crm_mon:
  • ptest -sL — показывает текущие значение размещения для кажой ноды.
  • crm_mon -A — показывает состояние переменной ping_intranet для каждой из нод.
Итого мы имеем следующие расчёты для разных ситуаций:

Для того, чтобы перевести кластер в исходное положение необходимо перенести ресурс на ноду first.local:

	crm resource move P_MYSQL_IP first.local

После этого ресур получает location с 1000000 очками (это INF для pacemaker) и переезжает на first.local. Очень важно дальше сделать unmove этого ресурса, который вернёт очки locatoin на место, но не поменяет расположение ресурса, т.к. у него и так будет больше очков (см. начальную ситуацию):
	crm resource unmove P_MYSQL_IP 

Что ещё можно делать с location и ping

Можно проверять запущен ли ресурс ping’a и проверять его значение:
	location L_RESOURCE P_RESOURCE rule -inf: not_defined ping_intranet or ping_intranet lte 0

Данный location запрещает размещать ресурс P_RESOURCE на ноде, где пинг меньше либо равен 0 (lte — less then or equal) или не запущен ресурс пинга.

Можно также совместить это правило с именем ноды:

	location L_RESOURCE P_RESOURCE rule -inf: #host eq first.local and ping_intranet lte 0

Говорит нам что если это нода first.local и пинг =

Leave a comment