Одним из наиболее существенных нововведений в Windows Server 2012 лично для меня является новая фича – DHCP Failover. Этот механизм предоставляет возможность балансировки нагрузки и создания избыточности для DHCP сервиса без применения каких-либо кластерных технологий. Но что если, по каким-либо причинам, у вас нет возможности использовать Windows Server 2012 в вашей среде, как и все возможные кластерные технологии? В этом случае к нам на помощь приходит PowerShell. Описанное ниже решение просто, эффективно и основано на следующих компонентах: PowerShell 2.0, встроенная в Windows утилита netsh и стандартный системный планировщик.
Предположим, у нас есть основной DHCP сервер и необходимость обеспечить бесперебойную доступность DHCP сервиса. Для этого поднимаем второй такой же сервер, на который мы будем автоматом переключаться в случае недоступности основного сервера или крутящегося там DHCP сервиса. Для такого переключения нам необходимо запустить резервный DHCP сервис с более-менее свежей DHCP базой.
Первый шаг: пишем на Powershell бэкап скрипт и запускаем его на основном DHCP сервере с помощью планировщика, ежедневно в 00-00:
Script 1
#
# DHCP db backup script.
# Requires Powershell 2.0.
# Prepared by Alexander Lipovetskiy 19.01.2014.
#
cls
# Basic variables
$Log = "C:DHCP_FailoverDHCP_Backup.log"
$DL = "Alexander.Lipovetskiy@firma.at", "admins@firma.at"
# Functions
function Date { Get-Date -Format G }
function Sendmail
{
Send-MailMessage `
-to $DL `
-From "MainDHCPServer@firma.at" `
-Subject "DHCP service failure!" `
-priority High `
-Body "$(Date) $Message" `
-SmtpServer "mail.firma.at"
}
function Alert
{
Write-Host "$(Date) $Message" -ForegroundColor Red
Write-Output "$(Date) $Message" | Out-File -FilePath $Log -Append
}
function Notification
{
Write-Host "$(Date) $Message"
Write-Output "$(Date) $Message" | Out-File -FilePath $Log -Append
}
# DHCP db backup procedure.
$Message = "Starting DHCP db backup procedure..."
Notification
# Let's keep one old copy of db.
Move-Item -Path "\BackupDHCPServerDHCP_FailoverDHCP_Backup.db" -Destination "\BackupDHCPServer DHCP_FailoverDHCP_Backup.db.previous" -Force
# Run the backup
netsh dhcp server export "\BackupDHCPServer DHCP_FailoverDHCP_Backup.db" all
$Message = "DHCP db backup is completed."
Notification
# Check if dhcp service is running after backup.
Start-Sleep -Seconds 30
$DHCPservice = Get-Service -Name "DHCPServer"
if ($DHCPservice.Status -ne 'Running')
{
$Message = "DHCP service is down after backing up! Trying to start it..."
Alert
Sendmail
$DHCPservice | Start-Service -Confirm:$false
# one more check
Start-Sleep -Seconds 30
$DHCPservice = Get-Service -Name "DHCPServer"
if ($DHCPservice.Status -ne 'Running')
{
$Message = "DHCP service is still down and can't be started!"
Alert
Sendmail
}
else
{
$Message = "DHCP service has been started from second attempt and running now."
Notification
Sendmail
}
}
else
{
$Message = "DHCP service is up and running after the backup procedure."
Notification
}
Этот скрипт запускает netsh для выгрузки DHCP базы в сетевую папку резервного сервера, оставляя там одну предыдущую копию базы. После выгрузки скрипт проверяет запустился ли DHCP сервис и если этого не произошло, то пытается запустить его еще раз (во процессе выгрузки netsh останавливает DHCP сервис, выгружает базу, затем снова его запускает). Скрипт ведет лог всех ошибок и в случае проблем оповещает нужных лиц по почте. Для этого естественно необходимо наличие в вашей сети почтового сервера, разрешающего пересылку внутренней почты без авторизации. При запуске скрипта из консоли можно увидеть больше информации о его работе т.к. в лог идут только ошибки.
Второй шаг: это наш основной failover механизм, который находится на резервном сервере. Там мы вешаем скрипт, который запускается каждую минуту, начиная с 00-05 в течение 23 часов 50 минут (оставим окно в 10 минут на время бэкапа).
Script 2
#
# DHCP failover script.
# Requires Powershell 2.0.
# Prepared by Alexander Lipovetskiy 19.01.2014.
#
cls
# Basic variables
$Log = "C:DHCP_FailoverDHCP_Failover.log"
$DHCPMain = "MainDHCPServer"
$DL = "Alexander.Lipovetskiy@firma.at", "admins@firma.at"
# Functions
function Date { Get-Date -Format G }
function Sendmail
{
Send-MailMessage `
-to $DL `
-From "BackupDHCPServer@firma.at" `
-Subject "DHCP service failure!" `
-priority High `
-Body "$(Date) $Message" `
-SmtpServer "mail.firma.at"
}
function Alert
{
Write-Host "$(Date) $Message" -ForegroundColor Red
Write-Output "$(Date) $Message" | Out-File -FilePath $Log -Append
}
function Notification
{
Write-Host "$(Date) $Message"
Write-Output "$(Date) $Message" | Out-File -FilePath $Log -Append
}
function StartBackupDHCPservice
{
#Start backup dhcp service
try
{
$DHCPsrvBackup | Start-Service -Confirm:$false
#import dhcp db from last backup
try
{
netsh dhcp server import "C:DHCP_FailoverDHCP_Backup.db" all
$Message = "DHCP db import from last backup is completed."
Notification
}
catch
{
$Message = "DHCP db import can't be done! Have to use old data."
Alert
Sendmail
}
$Message = "Backup DHCP service has been started."
Notification
SendMail
}
catch
{
$Message = "Backup DHCP service can't be started!"
Alert
Sendmail
}
}
# Check if main DHCP server is online.
if (Test-Connection -ComputerName $DHCPMain -Quiet)
{
$Message = "Main DHCP server is online."
Write-Host "$(Date) $Message"
# Check if main dhcp service is running.
$DHCPsrvMain = Get-Service -Name "DHCPServer" -ComputerName $DHCPMain
if ($DHCPsrvMain.Status -eq 'Running')
{
$Message = "DHCP service is running on main server."
Write-Host "$(Date) $Message"
# Stop backup dhcp service if it's running after main dhcp is back.
$DHCPsrvBackup = Get-Service -Name "DHCPServer"
if ($DHCPsrvBackup.Status -ne 'Stopped')
{
$DHCPsrvBackup | Stop-Service -Confirm:$false -Force
$Message = "Backup DHCP service has been stopped as main DHCP is back."
Notification
SendMail
}
else
{
$Message = "Backup DHCP service is not running."
Write-Host "$(Date) $Message"
}
break
}
else
# Start backup dhcp service if it's not running yet
{
$DHCPsrvBackup = Get-Service -Name "DHCPServer"
if ($DHCPsrvBackup.Status -eq 'Running')
{
$Message = "Backup DHCP service is running while main DHCP service is down."
Write-Host "$(Date) $Message"
break
}
else
{
# To prevent unnecessary failovers: wait 30 sec, check again and only then start
Start-Sleep -Seconds 30
$DHCPsrvMain = Get-Service -Name "DHCPServer" -ComputerName $DHCPMain
if ($DHCPsrvMain.Status -ne 'Running')
{
$Message = "DHCP service on main server is down! Starting backup DHCP service..."
Alert
Sendmail
StartBackupDHCPservice
}
else
{
$Message = "Main DHCP service is back after a short outage. Do nothing."
Notification
break
}
}
}
}
else
{
# Start backup dhcp service if it's not running yet
$DHCPsrvBackup = Get-Service -Name "DHCPServer"
if ($DHCPsrvBackup.Status -eq 'Running')
{
$Message = "Backup DHCP service is running while main DHCP server is offline."
Write-Host "$(Date) $Message"
break
}
else
{
$Message = "Main DHCP server is offline! Starting backup DHCP service..."
Alert
Sendmail
StartBackupDHCPservice
}
}
Вкратце, этот скрипт мониторит основной DHCP сервер и запускает свой резервный DHCP сервис в случае, если основной сервер недоступен или в случае, если основной сервер доступен, но DHCP сервис там не работает по каким-либо причинам. Происходит запуск резервного DHCP и подгрузка последней базы. Когда основной сервер снова в строю — происходит отключение резервного сервиса. Ну и также ведется лог и происходят все те же почтовые оповещения с информацией, соответствующей тому, что произошло.
Оба скрипта правильнее будет запускать от имении специально выделенного для этого аккаунта, дав ему при этом права админа на обоих серверах.
Если я что-то забыл или у вас просто есть вопросы – буду рад ответить в комментах.
Автор: alex_at