Как обновить универсальное приложение, работающее в отказоустойчивом кластере Windows

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

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

Кто-нибудь, кто использовал эту функцию, может:

  1. Можете описать, как он это сделал?
  2. Есть ли особые требования для его включения?
  3. Это рекомендуется?

person barakcaf    schedule 23.09.2018    source источник
comment
Вы размещаете службу Windows в кластере?   -  person UserName    schedule 24.09.2018
comment
@UserName — да (это встроенная опция отказоустойчивого кластера Microsoft)   -  person barakcaf    schedule 25.09.2018
comment
То, что вы спрашиваете, не связано с программированием. Это административная операция, описанная в Technet с 2008 года, если не раньше. Особенности варьируются от одной ОС к другой, поэтому вам следует проверить документы, относящиеся к вашему целевому серверу. Более новые ОС будут иметь более новые, лучшие или простые в использовании методы для обеспечения высокой доступности.   -  person Panagiotis Kanavos    schedule 25.09.2018
comment
Что касается того, хорошая это идея или нет, это зависит от требований. Например, веб-службы/службы REST не нуждаются в кластере Windows для обеспечения доступности и обновлений. Возможно, зависимостей так много, что лучше переместить всю виртуальную машину, а не одну службу. Контейнеры добавляют еще один аспект, который не имеет аппаратных требований Windows Clustering.   -  person Panagiotis Kanavos    schedule 25.09.2018
comment
Если хотите, я могу описать, как мы обновляем/обновляем наши кластерные [WSFC] службы Windows.   -  person UserName    schedule 25.09.2018
comment
Документы (больше не обновляются) для Windows 2008 R2: здесь Раздел за 2016 год здесь. Существуют различные сообщения в блогах, например о создании универсальных сервисных ресурсов от 2009 года.   -  person Panagiotis Kanavos    schedule 25.09.2018
comment
@UserName - да, пожалуйста   -  person barakcaf    schedule 25.09.2018
comment
@Panagiotis Kanavos - спасибо за ответ - я знаком с ресурсами, на которые вы ссылались. Я не думаю, что это не связано с программированием, поскольку, если возможно автоматически обновить общий сервис кластера FO, наверняка будут некоторые ограничения на способ реализации обновления сервиса (например, совместимость схемы БД)   -  person barakcaf    schedule 25.09.2018
comment
@barakcaf, если вам нужны хорошие ответы, вам придется спросить на serverfault.com. Да, есть и другие подобные вопросы, на самом деле вы можете считать это дубликатом (или слишком широким). Однако ответы в конечном итоге указывают на соответствующий вопрос на serverfault.com. PS: вам нужно будет указать конкретную версию Windows Server. Функции доступности сильно меняются от одной версии к другой.   -  person Panagiotis Kanavos    schedule 25.09.2018
comment
@Panagiotis Kanavos Я также разместил этот вопрос на сервере с ошибкой - и не получил ответа. Я также искал там и не смог найти похожий вопрос - если вы можете отослать меня к тому вопросу, о котором вы говорили, или, что еще лучше, к ответу, я был бы очень признателен. (Мне нужно поддерживать как можно больше версий сервера после 2008 r2)   -  person barakcaf    schedule 26.09.2018
comment
Подготовил ответ. Я надеюсь, что это будет полезно.   -  person UserName    schedule 28.09.2018


Ответы (1)


У нас есть кластерные службы Windows, которые используют стек .NET. На данный момент каждая роль кластера размещается только на двух узлах. Процесс развертывания и обновления выполняется через Ansible. Следующие фрагменты охватывают только часть обновления.


Для развертывания сервиса используются Nuget пакета. Используемый .nuspec представлен ниже. Таким образом, пакеты представляют собой .zip архивы, содержащие все содержимое в корне.

<?xml version="1.0"?>
<package>

  <metadata>
    <id>$Id$</id>

    <version>$Version$</version>
    <authors>$Authors$</authors>

    <description> $Description$ </description>
    <releaseNotes>$ReleaseNotes$</releaseNotes>
  </metadata>

  <files>
    <file src="$PackageInput$" target=" "/>
  </files>

</package>

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

- name: 'Copy the cluster_role.ps1 to all hosts'
  win_copy:
    src : 'cluster_role.ps1'
    dest: 'cluster_role.ps1'

Эта задача необходима для копирования на все хосты сценария PowerShell, необходимого для определения узла-владельца и для перемещения роли между узлами.

param([String]$ClusterRoleName, [String]$ExcludeNode)

# Task: Define the owner node
if ($ClusterRoleName -ne [string]::Empty -and $ExcludeNode -eq [string]::Empty)
{
    Get-ClusterResource -Name $ClusterRoleName | Format-List -Property OwnerNode
    exit
}

# Task: Move the cluster role
if ($ClusterRoleName -ne [string]::Empty -and $ExcludeNode -ne [string]::Empty)
{
    Move-ClusterGroup $ClusterRoleName (Get-ClusterNode | Where-Object { $_.State -eq 'Up' -and $_.Name -ne $ExcludeNode })
    exit
}

- name: 'Define the owner node'
  win_shell: 'cluster_role.ps1 -ClusterRoleName {{ cluster_role }}'
  register: owner_node
  run_once: True
  when: 'cluster_role is defined'


- name: 'Define the owner node metadata'
  set_fact:
    owner_node_host: '{{ owner_node.stdout.split(":")[1] | trim }}.{{ windows_domain }}'
    owner_node_name: '{{ owner_node.stdout.split(":")[1] | trim }}'
  run_once: True
  when: 'cluster_role is defined'

Эти задачи необходимы для обнаружения узла-владельца. Первая задача возвращает узел-владелец, например: s001srv000. Вторая задача создает две переменные следующих типов:

owner_node_host  : s001srv.domain.net
owner_node_name: s001srv000 

- name: 'Apply the application roles on the inactive nodes'
  include_role:
    name: '{{ item }}'
  when  : 'cluster_role is defined and (cluster_sets is defined or cluster_full is defined) and owner_node_host != inventory_hostname'
  with_items: '{{ dependencies }}'

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


- pause:
    prompt : 'A manual failover must be manually performed'
    minutes: 30
  run_once : True
  when: 'cluster_full is defined and environment_type == "prod"'


- name: 'Move the cluster role'
  win_shell: 'cluster_role.ps1 -ClusterRoleName {{ cluster_role }} -ExcludeNode {{ owner_node_name }}'
  run_once : True
  when: 'cluster_move is defined or cluster_full is defined'

Эти задачи необходимы для управления процессом обновления. Если текущая среда — STG, то обновление будет выполнено автоматически, в противном случае — с аварийным переключением вручную в момент паузы.


- name: 'Apply the application roles on the nodes which were active a moment ago'
  include_role:
    name: '{{ item }}'                                                                                                  
  when  : 'cluster_role is defined and cluster_full is defined and owner_node_host == inventory_hostname'

Эта задача такая же, как 'Apply the application roles on the inactive nodes', но для узлов, которые были активны минуту назад.

person UserName    schedule 28.09.2018
comment
Tnx - это очень полезно! как насчет обновления БД? Правильно ли вы описываете приложение SAAS (вы развертываете его в контролируемой вами среде)? - person barakcaf; 30.09.2018
comment
Эти задачи включают в себя другие роли, такие как загрузка пакета новой версии — что это за роль — общая роль приложения? - person barakcaf; 30.09.2018
comment
@barakcaf, развертывание происходит в собственных средах. На данный момент такие элементы, как развертывание баз данных, настройка пользователей, настройка связанных серверов, кластеризация автоматизированы. Обновление схем таблиц не автоматизировано. На данный момент проводится тестирование Liquibase для миграции баз данных, но без какой-либо автоматизации. - person UserName; 30.09.2018
comment
@barakcaf, да, это общие роли приложений. Все компоненты находятся в приватном репозитории Nuget. В нашем проекте Ansible существует базовый файл. Он описывает пары ключ-значение, такие как component:version, которые используются при обновлении - загрузка новой версии. Также все компоненты имеют файлы конфигурации, которые изменяются при обновлении в соответствии с конфигурацией среды и шаблоном конфигурации. - person UserName; 30.09.2018
comment
@barakcaf, я не описываю детали обновления базы данных, потому что это будет дополнительная статья, но если у вас есть вопросы.. - person UserName; 30.09.2018