基本的な考え方はILMサポートチームのブログでひろとさんが書いているのでそちらを見てもらうとして、、
http://blogs.technet.com/jpilmblg/archive/2008/09/29/miis-ilm.aspx
http://blogs.technet.com/jpilmblg/archive/2008/10/22/miis-ilm-2.aspx
ここで紹介されている情報を含め基本はSQL ServerのクラスタリングとコールドスタンバイでのILMの冗長化という構成がメーカサポートの限界っぽいのですが、ここではあえてサポートを気にせずILM自体のクラスタリングをしてみます。
(ということでNonサポートです)
<参考URL>
http://blogs.msdn.com/alextch/archive/2005/12/17/clusteredmiis.aspx
http://social.technet.microsoft.com/Forums/en-US/identitylifecyclemanager/thread/bb508bbd-ca49-4cf8-8159-bde0570098bf
まず、セットアップ前の準備ですが通常のインストールと違い、以下のポイントに注意が必要です。
・サービスアカウントはドメインユーザを利用する
※ローカルAdministrator権限は不要
・MIISAdminsなどのグループアカウントはドメイン上のグローバルグループを利用する
※インストール前にあらかじめ作成が必要
※以下のメンバを所属させておく必要あり
ILMサービスアカウント
クラスタサービスアカウント:MSCS経由で実行する際に必要
尚、クラスタサービスアカウントは通常ローカルAdministrator権限は不要ですが、
ILMを使う場合はローカルAdministrator権限が必要・・・
次にILMのセットアップですが、以下の順番に実施します。
1.プライマリノードでセットアップ
データベースはリモートサーバを指定
グループはあらかじめ作成したドメイングループを使用する(DOM\GROUP形式で指定)
2.プライマリノードでILMを停止
3.セカンダリノードでセットアップ
データベースはリモートサーバを指定
データベースの認識をする際にすでにデータベースが存在している旨が表示されるのでOKする
グループはあらかじめ作成したドメイングループを使用する(DOM\GROUP形式で指定)
キーファイル(*.bin)プライマリノードで作成したものをコピーする
4.セカンダリノードでILMを停止
5.プラまりノードでILMを起動
通常通りの起動方法だと、こんなエラーが出てしまう。
イベントログはこんな感じ
というわけで、起動方法は
miisactivate.exe キーファイル サービスアカウント パスワード
となります。(クラスタエージェントもこのコマンドをサイレントモードで実行します)
ここまで来たら次はクラスタへの組み込みです。
注意点は下記の通りです。
・登録するクラスタグループに優先ノードの設定を入れておく
※スクリプトの作りの問題です(設定していないとスクリプトがエラーを出すので必ず設定が必要)
・sleep.exeを使うのでWindows Server 2003のリソースキットが必要
・クラスタエージェント(下記のスクリプト)およびILMのキーファイルはILMインストールフォルダ\bin以下に
配置する(miisactivate.exeと同一フォルダである必要がある)
・CSV MAなどを使う場合、MADATAフォルダはローカルにあるので、CSVファイルは必ず両方のサーバに配置するような仕組みが別途必要です
※インストールオプションでMADATAだけ共有ディスクに移動できないか試したのですが、どうやら無理でした。。。
早速のセットアップですが、以下の流れです。
・リソースの種類は「汎用スクリプト」を使用
・登録してオンラインにした状態
クラスタエージェントスクリプトはこんな感じです。(参考URLに載っているものに一部バグがあったので修正しています)
各関数の解説
関数名 | 種別 | 機能/解説 |
Open | クラスタのエントリポイント | エージェントがロードされた時に呼ばれる。 |
Online | クラスタのエントリポイント | リソースをオンラインにする時に呼ばれる。 実行されたノードがGetPrefferedOwners関数で取得した優先ノードでなかった場合、CheckMIISServiceStatus関数で優先ノードでILMが実行されるか確認、もし実行中だった場合はStopRunningProfiles、StopMIISService関数を使って優先ノード上のILMを停止する。 その上でMiisactivateコマンドでILMの起動を試み、CheckMIISServiceStatus関数で起動状態を確認する。 |
LooksAlive | クラスタのエントリポイント | クラスタのエントリポイント。リソースのポーリングを行う。 CheckMIISServiceStatus関数を呼び出してILMのサービス死活を監視する。 |
IsAlive | クラスタのエントリポイント | クラスタのエントリポイント。リソースのポーリングを行う。 GetNumberOfMVRecords関数を呼び出してILMのサービス死活を監視する。 |
Offline | クラスタのエントリポイント | クラスタのエントリポイント。リソースをオンラインにする時に呼ばれる。 StopRunningProfiles関数を呼び出して実行中のプロファイルを停止し、StopMIISService関数でILMのサービスを停止する |
Terminate | クラスタのエントリポイント | クラスタのエントリポイント。特に何もしない。 |
Close | クラスタのエントリポイント | クラスタのエントリポイント。特に何もしない。 |
GetPrefferedOwners | プライベート関数 | WMI経由でMSCS関連のレジストリより優先ノード情報を取得する |
CheckMIISServiceStatus | プライベート関数 | WMI経由でmiiserverサービスの実行状態を取得する |
StopMIISService | プライベート関数 | WMI経由でmiiserverサービスを停止する |
StopRunningProfiles | プライベート関数 | WMI経由でILMに接続し、実行中のプロファイルがあれば停止する |
GetNumberOfMVRecords | プライベート関数 | WMI経由でILMに接続し、Metaverseのオブジェクト数を確認する(ポーリング目的) |
実際のスクリプト
Option Explicit
'##################################################################################
'GLOBAL DECLARATIONS - MODIFY ACCORDING TO YOUR ENVIRONMENT
'CLUSTER GROUP WHICH CONTAINS MIIS SQL AND SCRIPT RESOURCES
Dim miisgroup
miisgroup = "MSSQL" ' ILM2007リソースを作成するクラスタグループ名
Dim miisServiceAccount
miisServiceAccount = "mscs\ilmservice" ' ILMサービスアカウント
Dim miisServiceAccountPwd
miisServiceAccountPwd = "P@ssw0rd" ' ILMサービスアカウントのパスワード
Dim miisEncryptKey
miisEncryptKey = "miiskey.bin"
Dim miisServiceStartupTime 'time in seconds for MIIS Service to come up
miisServiceStartupTime = 400
'###################################################################################
Dim activeNode
Dim prefferedOwners
Dim miisActivateCmd
Function Open()
Dim WshNetwork
Resource.LogInformation("Entering Open() for group" & Resource.Name)
Set WshNetwork = CreateObject("WSCript.Network")
activeNode = WshNetwork.ComputerName
prefferedOwners = GetPrefferedOwners()
miisActivateCmd = "miisactivate.exe " & miisEncryptKey & " " & miisServiceAccount & " " & miisServiceAccountPwd & " /q"
Resource.LogInformation("MIISActivate Command - " & miisActivateCmd)
Open = True
End Function
Function Online( )
Dim Node
Dim WshShell
Dim oExec
Dim oWait
Dim i
Resource.LogInformation("Entering Online()")
'Ensurting that MIIS Service is not running on other preffered nodes of the cluster grp
For Each Node In prefferedOwners
If (Node <> activeNode) And (CheckMIISServiceStatus(Node) = True) Then
StopRunningProfiles(Node)
StopMIISService(Node)
End If
Next
'Check if MIIS Service is already running on the active Node, if yes just exit
If CheckMIISServiceStatus(activeNode) = True Then
Online = True
Exit Function
End If
'Run MIISActivate on the Active Cluster Noded
Resource.LogInformation("About to execute:" & miisActivateCmd)
Set WshShell = CreateObject("WScript.Shell")
WshShell.CurrentDirectory = "C:\Program Files\Microsoft Identity Integration Server\Bin"
Set oExec = WshShell.Exec(miisActivateCmd)
' ... Allow time for operation to complete...
For i = 0 To miisServiceStartupTime
Resource.LogInformation("Waiting for MIIS Service to come-up...")
WshShell.Run "sleep 5" ,0,True
If CheckMIISServiceStatus(activeNode) = True Then
Resource.LogInformation("MIIS Service Started by MIISMonitor Script")
Exit For
End if
Next
If CheckMIISServiceStatus(activeNode) = False Then
Resource.LogInformation("Failed to MIISActivate on Node:" & activeNode)
Online = False
Else
Resource.LogInformation("MIISActivated on Node:" & activeNode)
Online = True
End If
End Function
Function LooksAlive()
If CheckMIISServiceStatus(activeNode) = True Then
Resource.LogInformation("MIIS Service LooksAlive")
LooksAlive = True
Else
Resource.LogInformation("MIIS Service Failed")
LooksAlive = False
End If
End Function
Function IsAlive()
'Perform various MIIS calls to ensure that it is alive
If GetNumberOfMVRecords(activeNode) = True Then
Resource.LogInformation("MIIS Service is Alive")
IsAlive = True
Else
Resource.LogInformation("MIIS Service failed isAlive check")
IsAlive = False
End If
End Function
Function Offline()
Resource.LogInformation("Entering Offline()")
Resource.LogInformation("About to stop MIIS Service on node:" & activeNode)
StopRunningProfiles(activeNode)
StopMIISService(activeNode)
End Function
Function Terminate()
Terminate = True
End Function
Function Close()
Close = True
End Function
Function GetPrefferedOwners()
Const HKEY_LOCAL_MACHINE = &H80000002
Dim oReg
Dim strKeyPath
Dim arrSubKeys
Dim strValueName
Dim strValue
Dim arrValues
Dim subkey
Dim strPrefferedNodes()
Dim i
i = 0
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
activeNode & "\root\default:StdRegProv")
strKeyPath = "Cluster\Groups\"
oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
For Each subkey In arrSubKeys
strKeyPath = "Cluster\Groups\" & subkey
strValueName = "Name"
oReg.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
If strValue = miisgroup Then
strValueName = "PreferredOwners"
oReg.GetMultiStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,arrValues
For Each strValue In arrValues
strKeyPath = "Cluster\Nodes\" & strValue
strValueName = "NodeName"
oReg.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
ReDim Preserve strPrefferedNodes(i)
strPrefferedNodes(i) = strValue
i = i + 1
Next
End If
Next
GetPrefferedOwners = strPrefferedNodes
End Function
Function CheckMIISServiceStatus(Node)
On Error Resume Next
Dim objWMIService
Dim strWMIQuery
Dim colServices
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & Node & "\root\cimv2")
strWMIQuery = "Select * from Win32_Service where Name = 'miiserver' and State = 'running'"
Set colServices = objWMIService.ExecQuery(strWMIQuery)
If Err.Number <> 0 Then
Resource.LogInformation("Unable to complete WMI call in CheckMIISServiceStatus, error code " & Err.Number)
CheckMIISService = False
Exit Function
End If
If colServices.Count = 1 Then
CheckMIISServiceStatus = True
Else
CheckMIISServiceStatus = False
End If
End Function
Function StopMIISService(Node)
On Error Resume Next
Dim objWMIService
Dim colServiceList
Dim objService
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & Node & "\root\cimv2")
Set colServiceList = objWMIService.ExecQuery _
("Select * from Win32_Service where Name='miiserver' and State = 'running'")
For Each objService In colServiceList
objService.StopService()
If Err.Number <> 0 Then
Resource.LogInformation("Unable to complete WMI call to stop MIIS during StopMIISService, error code " & Err.Number)
End If
Next
End Function
Function StopRunningProfiles(Node)
On Error Resume Next
Dim objWMIService
Dim Runs
Dim Run
Dim ManagementAgent
'First stop all running jobs
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & Node & "\root\MicrosoftIdentityIntegrationServer")
Set Runs = objWMIService.ExecQuery("Select * From MIIS_RunHistory where RunStatus = 'in-progress'")
For Each Run in Runs
Resource.LogInformation("Stopping " & Run.MaName & " profile " & Run.RunProfile)
Set ManagementAgent = objWMIService.Get("MIIS_ManagementAgent.Name='" & Run.MaName & "'")
ManagementAgent.Stop()
If Err.Number <> 0 Then
Resource.LogInformation("Unable to complete WMI to get Run History call during StopRunningProfiles, error code " & Err.Number)
End If
Next
End Function
Function GetNumberOfMVRecords(Node)
Dim Service
Dim Server
Dim numOfMvObjects
Set Service = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & Node & "\root\MicrosoftIdentityIntegrationServer")
Set Server = Service.Get("MIIS_Server.Name='MIIS_Server1'")
numOfMvObjects = Server.NumMvObjects()
If numOfMvObjects = "connection-failure" Or numOfMvObjects = "call-failure:0x80230621" Then
Resource.LogInformation("Unable to complete WMI call in isAlive, error code " & Err.Number & ":" & numOfMvObjects )
GetNumberOfMVRecords = False
Else
Resource.LogInformation("Count of Metaverse Objects = " & numOfMvObjects)
GetNumberOfMVRecords = True
End If
End Function
0 件のコメント:
コメントを投稿