適用対象: Azure Local 2311.2 以降。Windows Server 2022、Windows Server 2019
この記事では、Azure Local と Windows Server のヘルス サービスの障害に関する詳細情報を提供します。
ヘルス サービスの障害について
ヘルス サービスは、問題を検出して "障害" を生成するために、記憶域スペース ダイレクト クラスターを常に監視します。1 つのコマンドレットで現在の障害がすべて表示されるため、すべてのエンティティまたは機能を順番に調べることなく、デプロイの正常性を簡単に確認できます。 障害は正確で理解しやすく、意思決定に役立つように設計されています。
各障害には、5 つの重要なフィールドがあります。
- 重大度
- 問題の説明
- 問題対処のために推奨される次のステップ
- 障害が発生したエンティティの識別情報
- 物理的な場所 (該当する場合)
たとえば、一般的な障害は次のとおりです。
Severity: MINOR
Reason: Connectivity has been lost to the physical disk.
Recommendation: Check that the physical disk is working and properly connected.
Part: Manufacturer Contoso, Model XYZ9000, Serial 123456789
Location: Seattle DC, Rack B07, Node 4, Slot 11
注
物理的な場所は、障害ドメインの構成から取得されます。 障害ドメインの詳細については、「障害ドメインの認識」を参照してください。 この情報を指定していない場合、location フィールドはあまり役に立ちません。 たとえば、スロット番号のみが表示されることがあります。
障害に関するリファレンス情報については、「 ヘルス サービスの障害リファレンス」を参照してください。
根本原因分析
ヘルス サービスでは、障害が発生しているエンティティで潜在的な原因を評価し、同じ根本的な問題の結果である障害を特定して結び付けることができます。 作用連鎖を認識することで、細かすぎないレポートを作成できます。 たとえば、サーバーがダウンしている場合、サーバー内のドライブにも接続できないと想定されます。 したがって、根本原因として示される障害は 1 つのみ、つまりこの場合はサーバーです。
PowerShell での使用法
PowerShell で現在の障害を確認するには、次のコマンドレットを実行します。
Get-HealthFault
これにより、記憶域スペース ダイレクト クラスター全体に影響を与える障害が返されます。 ほとんどの場合、このような障害は、ハードウェアまたは構成に関連します。 障害がない場合、コマンドレットからは何も返されません。
注
非運用環境では、ご自身で障害をトリガーすることにより、自己責任でこの機能を試すことができます。 たとえば、1 つの物理ディスクを削除したり、1 つのノードをシャット ダウンしたりすることができます。 障害が表示されたら、物理ディスクを再挿入するか、ノードを再起動して障害を解消します。
.NET および C# での使用方法
このセクションでは、ヘルス サービスへの接続、検出オブジェクトの使用、および障害クエリの実行の方法について説明します。
接続
ヘルス サービスのクエリを実行するには、クラスターと CimSession を確立します。 これを行うには、完全な Microsoft .NET でのみ使用できるいくつかのものが必要です。つまり、Web アプリやモバイル アプリから直接これを簡単に行うことはできません。 このセクションのコード サンプルでは、このデータ アクセス層のための最も単純な選択肢である C# を使用します。
using System.Security;
using Microsoft.Management.Infrastructure;
public CimSession Connect(string Domain = "...", string Computer = "...", string Username = "...", string Password = "...")
{
SecureString PasswordSecureString = new SecureString();
foreach (char c in Password)
{
PasswordSecureString.AppendChar(c);
}
CimCredential Credentials = new CimCredential(
PasswordAuthenticationMechanism.Default, Domain, Username, PasswordSecureString);
WSManSessionOptions SessionOptions = new WSManSessionOptions();
SessionOptions.AddDestinationCredentials(Credentials);
Session = CimSession.Create(Computer, SessionOptions);
return Session;
}
指定するユーザー名は、ターゲット コンピューターのローカル管理者である必要があります。
パスワードがプレーン テキストでメモリに格納されないようにするため、ユーザー入力からパスワードの SecureString をリアルタイムで直接構築することをお勧めします。 これは、さまざまなセキュリティの問題を軽減するために役立ちます。 ただし、実際には、ひな形作成の目的で上記のように構築するのが一般的です。
オブジェクトを検出します
CimSession が確立されると、クラスターの Windows Management Instrumentation (WMI) に対してクエリを実行できます。
障害またはメトリックを取得するには、いくつかの関連オブジェクトのインスタンスを取得する必要があります。 まず、クラスター上の記憶域スペース ダイレクトを表す MSFT_StorageSubSystem を取得します。 それを使用すると、クラスター内のすべての MSFT_StorageNode や、データ ボリュームのすべての MSFT_Volume を取得できます。 最後に、MSCluster_ClusterHealthService (ヘルス サービス自体) を取得する必要があります。
CimInstance Cluster;
List<CimInstance> Nodes;
List<CimInstance> Volumes;
CimInstance HealthService;
public void DiscoverObjects(CimSession Session)
{
// Get MSFT_StorageSubSystem for Storage Spaces Direct
Cluster = Session.QueryInstances(@"root\microsoft\windows\storage", "WQL", "SELECT * FROM MSFT_StorageSubSystem")
.First(Instance => (Instance.CimInstanceProperties["FriendlyName"].Value.ToString()).Contains("Cluster"));
// Get MSFT_StorageNode for each cluster node
Nodes = Session.EnumerateAssociatedInstances(Cluster.CimSystemProperties.Namespace,
Cluster, "MSFT_StorageSubSystemToStorageNode", null, "StorageSubSystem", "StorageNode").ToList();
// Get MSFT_Volumes for each data volume
Volumes = Session.EnumerateAssociatedInstances(Cluster.CimSystemProperties.Namespace,
Cluster, "MSFT_StorageSubSystemToVolume", null, "StorageSubSystem", "Volume").ToList();
// Get MSFT_StorageHealth itself
HealthService = Session.EnumerateAssociatedInstances(Cluster.CimSystemProperties.Namespace,
Cluster, "MSFT_StorageSubSystemToStorageHealth", null, "StorageSubSystem", "StorageHealth").First();
}
これらは、PowerShell で Get-StorageSubSystem、Get-StorageNode、および Get-Volume のようなコマンドレットを使用して取得するものと同じオブジェクトです。
Storage Management API クラスに記載されている、同じプロパティのすべてにアクセスできます。
using System.Diagnostics;
foreach (CimInstance Node in Nodes)
{
// For illustration, write each node's Name to the console. You could also write State (up/down), or anything else!
Debug.WriteLine("Discovered Node " + Node.CimInstanceProperties["Name"].Value.ToString());
}
障害のクエリ
Diagnose を呼び出して、ターゲットの CimInstance (クラスターまたは任意のボリューム) をスコープとする現在の障害を取得できます。
public void GetFaults(CimSession Session, CimInstance Target)
{
// Set Parameters (None)
CimMethodParametersCollection FaultsParams = new CimMethodParametersCollection();
// Invoke API
CimMethodResult Result = Session.InvokeMethod(Target, "Diagnose", FaultsParams);
IEnumerable<CimInstance> DiagnoseResults = (IEnumerable<CimInstance>)Result.OutParameters["DiagnoseResults"].Value;
// Unpack
if (DiagnoseResults != null)
{
foreach (CimInstance DiagnoseResult in DiagnoseResults)
{
// TODO: Whatever you want!
}
}
}
省略可能: MyFault クラス
独自の障害表現を構築して保持することに意味があることもあります。 たとえば MyFault クラスには、FaultId など、障害のいくつかの主要なプロパティが格納されます。これは、後で同じエラーが複数回検出された場合に、更新の関連付け、通知の削除、重複除去を行うために使用できます。
public class MyFault {
public String FaultId { get; set; }
public String Reason { get; set; }
public String Severity { get; set; }
public String Description { get; set; }
public String Location { get; set; }
// Constructor
public MyFault(CimInstance DiagnoseResult)
{
CimKeyedCollection<CimProperty> Properties = DiagnoseResult.CimInstanceProperties;
FaultId = Properties["FaultId" ].Value.ToString();
Reason = Properties["Reason" ].Value.ToString();
Severity = Properties["PerceivedSeverity" ].Value.ToString();
Description = Properties["FaultingObjectDescription"].Value.ToString();
Location = Properties["FaultingObjectLocation" ].Value.ToString();
}
}
List<MyFault> Faults = new List<MyFault>;
foreach (CimInstance DiagnoseResult in DiagnoseResults)
{
Faults.Add(new Fault(DiagnoseResult));
}
各障害のプロパティの全一覧 (DiagnoseResult) については、後の「障害のプロパティ」セクションで説明します。
障害イベント
障害が作成、削除、または更新されると、ヘルスサービスが WMI イベントを生成します。 これらは、頻繁にポーリングを行わなくてもアプリケーションの状態を同期するために不可欠であり、たとえば、電子メール アラートをいつ送信するかを決定するために役立ちます。 これらのイベントをサブスクライブするため、次のサンプル コードではオブザーバー デザイン パターンを使用します。
まず、MSFT_StorageFaultEvent イベントにサブスクライブします。
public void ListenForFaultEvents()
{
IObservable<CimSubscriptionResult> Events = Session.SubscribeAsync(
@"root\microsoft\windows\storage", "WQL", "SELECT * FROM MSFT_StorageFaultEvent");
// Subscribe the Observer
FaultsObserver<CimSubscriptionResult> Observer = new FaultsObserver<CimSubscriptionResult>(this);
IDisposable Disposeable = Events.Subscribe(Observer);
}
次に、オブザーバーを実装し、新しいイベントが生成されるたびに、その OnNext() メソッドが呼び出されるようにします。
各イベントには、障害の作成、削除、または更新を示す ChangeType と、関連する FaultId が含まれます。
さらに、各イベントには、その障害自体のすべてのプロパティが含まれています。
class FaultsObserver : IObserver
{
public void OnNext(T Event)
{
// Cast
CimSubscriptionResult SubscriptionResult = Event as CimSubscriptionResult;
if (SubscriptionResult != null)
{
// Unpack
CimKeyedCollection<CimProperty> Properties = SubscriptionResult.Instance.CimInstanceProperties;
String ChangeType = Properties["ChangeType"].Value.ToString();
String FaultId = Properties["FaultId"].Value.ToString();
// Create
if (ChangeType == "0")
{
Fault MyNewFault = new MyFault(SubscriptionResult.Instance);
// TODO: Whatever you want!
}
// Remove
if (ChangeType == "1")
{
// TODO: Use FaultId to find and delete whatever representation you have...
}
// Update
if (ChangeType == "2")
{
// TODO: Use FaultId to find and modify whatever representation you have...
}
}
}
public void OnError(Exception e)
{
// Handle Exceptions
}
public void OnCompleted()
{
// Nothing
}
}
障害のライフサイクルについて
障害は、ユーザーが "確認済み" または解決済みとしてマークすることは意図していません。 ヘルス サービスによって問題が観察されると作成され、問題が観察されなくなると自動的に削除されます。 これは通常、問題が修正されたことを示します。
ただし場合によっては、フェールオーバーや間欠的な接続の後などに、ヘルス サービスによって障害が再度検出されることもあります。 このため、独自の障害表現を保持し、簡単に重複を解消できるようにしておくことに意味がある場合があります。 これは、電子メール アラートまたはそれに相当するものを送信する場合に特に重要です。
障害のプロパティ
次の表に、障害オブジェクトのいくつかの主要なプロパティを示します。 完全なスキーマについては、storagewmi.mof 内の MSFT_StorageDiagnoseResult クラスを調べてください。
プロパティ | 例 |
---|---|
障害ID | {12345-12345-12345-12345-12345} |
故障タイプ | Microsoft.Health.FaultType.Volume.Capacity |
理由 | "ボリュームの空き領域が不足しています。" |
認識された重症度 | 5 |
障害対象説明 | Contoso XYZ9000 S.N.123456789 |
障害オブジェクト位置 | ラック A06、RU 25、スロット 11 |
推奨されるアクション | {"ボリュームを拡張してください。", "ワークロードを他のボリュームに移行してください。"} |
FaultId: 1 つのクラスターのスコープ内の一意の ID。
PerceivedSeverity: PerceivedSeverity = { 4, 5, 6 } = { "情報", "警告", "エラー" }、または青、黄、赤などの対応する色。
FaultingObjectDescription: ハードウェアのパーツ情報。ソフトウェア オブジェクトの場合、通常は空白です。
FaultingObjectLocation: ハードウェアの位置情報。ソフトウェア オブジェクトの場合、通常は空白です。
RecommendedActions: 個別の推奨アクションのリスト。順不同です。 現在、このリストの長さは通常は 1 です。
障害イベントのプロパティ
次の表に、障害イベントのいくつかの主要なプロパティを示します。 完全なスキーマについては、storagewmi.mof 内の MSFT_StorageFaultEvent クラスを調べてください。
障害の作成、削除、または更新を示す ChangeType と、関連する FaultId に注目してください。 イベントには、影響を受けた障害のすべてのプロパティも含まれます。
プロパティ | 例 |
---|---|
ChangeType | 0 |
障害ID | {12345-12345-12345-12345-12345} |
故障タイプ | Microsoft.Health.FaultType.Volume.Capacity |
理由 | "ボリュームの空き領域が不足しています。" |
認識された重症度 | 5 |
障害対象説明 | Contoso XYZ9000 S.N.123456789 |
障害オブジェクト位置 | ラック A06、RU 25、スロット 11 |
推奨されるアクション | {"ボリュームを拡張してください。", "ワークロードを他のボリュームに移行してください。"} |
ChangeType: ChangeType = { 0, 1, 2 } = { "Create", "Remove", "Update" }.
ヘルスサービスの障害に関する参照
Azure Local および Windows Server のヘルス サービスは、ストレージ、ネットワーク、コンピューティング リソースなど、さまざまなシステム コンポーネント間の障害を検出できます。
障害の重大度マッピング、正常性設定 (データ型、障害の関連付け、既定値、説明)、収集されたメトリックの一覧など、正常性エラーの詳細な概要については、 Health Service の障害 スプレッドシートをダウンロードしてください。
ヘルス サービスの障害に関する考慮事項:
一部の障害は既定で無効になっています。 障害を有効にするには、対応する正常性設定を true に設定します。 たとえば、障害の種類
Microsoft.Health.FaultType.PhysicalDisk.HighLatency.AverageIO
は既定で無効になっています。 有効にするには、正常性設定System.Storage.PhysicalDisk.HighLatency.Threshold.Tail.Enabled
true に設定します。ファン、電源、センサーなどの記憶域エンクロージャ コンポーネントの正常性は、SCSI エンクロージャ サービス (SES) から取得されます。 ベンダーがこの情報を提供しない場合、ヘルス サービスでは表示できません。