Azure Service Fabric の DNS サービス
オプションのシステム サービスである DNS サービスをクラスターで有効にし、DNS プロトコルを使用して他のサービスを検出できます。
多くのサービス、特にコンテナー化されたサービスは、既存の URL を使ってアドレス指定することができます。 これらのサービスは、Service Fabric Naming Service プロトコルではなく標準の DNS プロトコルを使って解決できることが望まれます。 DNS サービスを使用すると、DNS 名をサービス名にマップして、エンドポイントの IP アドレスを解決できます。 異なるプラットフォームにまたがるコンテナー化されたサービスの可搬性は、こうした機能により確保されています。Naming Service を使用するようにコードを書き換えるのではなく、既存のサービスの URL を使用できることから、"リフト アンド シフト" のシナリオが実現しやすくなっているのです。
DNS サービスによって DNS 名がサービス名にマップされ、それが Naming Service によって解決され、サービス エンドポイントに返されます。 サービスの DNS 名は、作成時に提供されます。 次の図は、ステートレス サービスでの DNS サービスの動作を示しています。 簡潔にするために、図はサービスのエンドポイントを 1 つだけ示していますが、各サービスは複数のエンドポイントを持つことができます。
Service Fabric バージョン 6.3 以降では、Service Fabric の DNS プロトコルが拡張され、パーティション分割型ステートフル サービスをアドレス指定するためのスキームが追加されています。 これらの拡張機能では、ステートフル サービスの DNS 名とパーティション名とを組み合わせて、特定のパーティションの IP アドレスを解決することができます。 次の 3 つのパーティション分割構成がすべてサポートされています。
- 名前付きパーティション分割
- 範囲パーティション分割
- 単一パーティション分割
次の図は、パーティション分割型ステートフル サービスでの DNS サービスの動作を示しています。
パーティション分割型クエリの詳細については、以下のセクションを参照してください。
OS のサポート
DNS サービスは Windows と Linux の両方のクラスターでサポートされていますが、Linux のサポートは現在、コンテナー化されたサービスに限定されており、Azure portal から有効にすることはできません。 ただし、Windows では、すべてのサービスの種類とデプロイ モデルがサポートされています。
DNS サービスを有効にする
Note
DNS サービスを有効にすると、ノード上の一部の DNS 設定がオーバーライドされます。 インターネットへの接続で問題が発生する場合は、DNS の設定を確認してください。
新しいクラスター
ARM テンプレートを使用したクラスター
ARM テンプレートを使用して新しいクラスターをデプロイするには、サンプル テンプレートを使用するか、独自のテンプレートを記述します。 まだ行っていない場合は、サポートされている API の最小バージョンを使用し、適切な設定を追加することで、テンプレートで DNS サービスを有効にすることができます。 これを実現する方法の詳細については、次に示す番号付きリストのポイント 1 と 2 を参照してください。
Azure portal を使用したクラスター
ポータルで標準クラスターを作成する場合、[アドオン機能] セクションの [DNS サービスを含める] オプションで DNS サービスが既定で有効になります。
ポータルでマネージド クラスターを作成する場合、[アドオン機能] セクションの [DNS サービス] オプションで DNS サービスが既定で有効になります。
既存のクラスター
DNS サービスを有効にするために既存のマネージド クラスターを更新する場合は、クラスター リソースのページから [アドオン サービス] ページにアクセスして、ポータルからこれを行うことができます。 それ以外の場合は、次に示す別の方法を使用して DNS サービスを有効にすることができます。
- クラスターのデプロイに使用された ARM テンプレートを使用します (該当する場合)。
- Azure Resource Explorer でクラスターに移動し、次に示す手順 (手順 2 以降) を参照してクラスター リソースを更新します。
- ポータルでクラスターに移動し、[テンプレートのエクスポート] をクリックします。 詳細については、「リソース グループからのテンプレートのエクスポート」を参照してください。
テンプレートが用意されたら、次の手順で DNS サービスを有効にできます。
標準クラスターの場合は、
Microsoft.ServiceFabric/clusters
リソースのapiVersion
が2017-07-01-preview
以降に設定されていることを確認し、設定されていない場合は、それを次の例に示すように更新します。{ "apiVersion": "2017-07-01-preview", "type": "Microsoft.ServiceFabric/clusters", "name": "[parameters('clusterName')]", "location": "[parameters('clusterLocation')]", ... }
マネージド クラスターの場合は、
Microsoft.ServiceFabric/managedClusters
リソースのapiVersion
が2020-01-01-preview
以降に設定されていることを確認し、設定されていない場合は、それを次の例に示すように更新します。{ "apiVersion": "2020-01-01-preview", "type": "Microsoft.ServiceFabric/managedClusters", "name": "[parameters('clusterName')]", "location": "[parameters('clusterLocation')]", ... }
ここで、次のいずれかの方法で DNS サービスを有効にします。
既定の設定で DNS サービスを有効にするには、次の例のように、
properties
セクション内のaddonFeatures
セクションに DNS サービスを追加します。"properties": { ... "addonFeatures": [ "DnsService" ], ... }
既定以外の設定でサービスを有効にするには、
properties
セクション内のfabricSettings
セクションにDnsService
セクションを追加します。 このケースでは、DnsService をaddonFeatures
に追加する必要はありません。 DNS サービスに関して設定できるプロパティの詳細については、DNS サービスの設定に関するページを参照してください。"properties": { ... "fabricSettings": [ ... { "name": "DnsService", "parameters": [ { "name": "IsEnabled", "value": "true" }, { "name": "<key>", "value": "<value>" } ] }, ... ] }
必要な変更でクラスター テンプレートを更新したら、変更を適用してアップグレードを完了します。 アップグレードが完了すると、DNS システム サービスはクラスター内で実行を開始します。 サービス名は
fabric:/System/DnsService
であり、それは Service Fabric Explorer の [システム] サービス セクションで見つかります。
Note
DNS を無効から有効にアップグレードしたときに、Service Fabric Explorer に新しい状態が反映されない場合があります。 解決するには、テンプレート内でアップグレード ポリシーを変更して、ノードを再起動します。
サービスの DNS 名を設定する
サービスの DNS 名は、ARM テンプレート、ApplicationManifest.xml ファイルの既定のサービス、または PowerShell コマンドを使用して設定できます。
サービスの DNS 名は、クラスターの全体にわたって解決可能です。したがってクラスター全体で DNS 名の一意性を確保することが重要となります。
<ServiceName>.<AppName>
(service1.application1
など) の名前付けスキームを使用することを強くお勧めします。 アプリケーションが Docker Compose を使用してデプロイされる場合、サービスには、この名前付けスキームを使用した DNS 名が自動的に割り当てられます。
ARM テンプレートを使用して DNS 名を設定する
ARM テンプレートを使用してサービスをデプロイする場合は、適切なセクションに serviceDnsName
プロパティを追加し、それに値を割り当てることができます。 次に例を示します。
標準クラスター
標準クラスターの場合は、Microsoft.ServiceFabric/clusters/applications/services
リソースの apiVersion
が 2019-11-01-preview
以降に設定されていることを確認し、設定されていない場合は、それを次の例に示すように更新します。
{
"apiVersion": "2019-11-01-preview",
"type": "Microsoft.ServiceFabric/clusters/applications/services",
"name": "[concat(parameters('clusterName'), '/', parameters('applicationName'), '/', parameters('serviceName'))]",
"location": "[variables('clusterLocation')]",
"dependsOn": [
"[concat('Microsoft.ServiceFabric/clusters/', parameters('clusterName'), '/applications/', parameters('applicationName'))]"
],
"properties": {
"provisioningState": "Default",
"serviceKind": "Stateless",
"serviceTypeName": "[parameters('serviceTypeName')]",
"instanceCount": "-1",
"partitionDescription": {
"partitionScheme": "Singleton"
},
"correlationScheme": [],
"serviceLoadMetrics": [],
"servicePlacementPolicies": [],
"serviceDnsName": "[parameters('serviceDnsName')]"
}
}
マネージド クラスター
マネージド クラスターの場合は、Microsoft.ServiceFabric/managedclusters/applications/services
リソースの apiVersion
が 2022-10-01-preview
以降に設定されていることを確認し、設定されていない場合は、それを次の例に示すように更新します。
{
"apiVersion": "2022-10-01-preview",
"type": "Microsoft.ServiceFabric/managedclusters/applications/services",
"name": "[concat(parameters('clusterName'), '/', parameters('applicationName'), '/', parameters('serviceName'))]",
"location": "[variables('clusterLocation')]",
"dependsOn": [
"[concat('Microsoft.ServiceFabric/managedclusters/', parameters('clusterName'), '/applications/', parameters('applicationName'))]"
],
"properties": {
"serviceKind": "Stateless",
"serviceTypeName": "[parameters('serviceTypeName')]",
"instanceCount": "-1",
"partitionDescription": {
"partitionScheme": "Singleton"
},
"correlationScheme": [],
"serviceLoadMetrics": [],
"servicePlacementPolicies": [],
"serviceDnsName": "[parameters('serviceDnsName')]"
}
}
ApplicationManifest.xml で既定のサービスの DNS 名を設定する
Visual Studio またはお好みのエディターでプロジェクトを開いて、ApplicationManifest.xml ファイルを開きます。 既定のサービスのセクションに移動し、各サービスに ServiceDnsName
属性を追加します。 次の例は、サービスの DNS 名を stateless1.application1
に設定する方法を示します。
<Service Name="Stateless1" ServiceDnsName="stateless1.application1">
<StatelessService ServiceTypeName="Stateless1Type" InstanceCount="[Stateless1_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>
次の例では、ステートフル サービスの DNS 名を stateful1.application1
に設定しています。 このサービスは、名前付きパーティション構成を使用しています。 パーティション名が小文字になっていることに注目してください。 これは、DNS クエリで対象となるパーティションの要件です。詳細については、「Making DNS queries on a stateful service partition (ステートフル サービス パーティションに対する DNS クエリの実行)」を参照してください。
<Service Name="Stateful1" ServiceDnsName="stateful1.application1" />
<StatefulService ServiceTypeName="Stateful1Type" TargetReplicaSetSize="2" MinReplicaSetSize="2">
<NamedPartition>
<Partition Name="partition1" />
<Partition Name="partition2" />
</NamedPartition>
</StatefulService>
</Service>
PowerShell を使用してサービスの DNS 名を設定する
サービスの作成時に、New-ServiceFabricService
PowerShell コマンドを使用してサービスの DNS 名を設定できます。 次の例では、DNS 名が stateless1.application1
の新しいステートレス サービスを作成します。
New-ServiceFabricService `
-Stateless `
-PartitionSchemeSingleton `
-ApplicationName fabric:/application1 `
-ServiceName fabric:/application1/stateless1 `
-ServiceTypeName Stateless1Type `
-InstanceCount 1 `
-ServiceDnsName stateless1.application1
Update-ServiceFabricService
PowerShell コマンドを使用して、既存のサービスを更新することもできます。 次の例では、既存のステートレス サービスを更新して DNS 名 stateless1.application1
を追加します。
Update-ServiceFabricService `
-Stateless `
-ServiceName fabric:/application1/stateless1 `
-ServiceDnsName stateless1.application1
DNS 名が設定されていることを Service Fabric Explorer で確認する
DNS 名を指定してサービスをデプロイすると、次の図に示すように、Service Fabric Explorer にサービスの DNS 名が表示されます。
Note
このビューは、使用している Service Fabric Explorer のバージョンによって異なる場合がありますが、DNS 名フィールドはサービス ページに何らかの形式で表示されます。
ステートフル サービス パーティションに対する DNS クエリの実行
Service Fabric バージョン 6.3 以降では、DNS サービスはサービス パーティションのクエリをサポートしています。 パーティション分割型サービス クエリのサポートを有効にするには、DNS サービスの設定を更新して EnablePartitionedQuery
オプションを true
に設定する必要があります。
DNS クエリで使用されるパーティションについては、名前付けに関して次の制限が適用されます。
- パーティションには、DNS 準拠の名前を使用する必要があります。
- ドット "." を含む複数ラベルのパーティション名は使用しないでください。
- パーティション名は小文字にする必要があります。
特定のパーティションを対象とした DNS クエリの書式は次のとおりです。
<First-Label-Of-Partitioned-Service-DNSName><PartitionPrefix><Target-Partition-Name><PartitionSuffix>.<Remaining-Partitioned-Service-DNSName>
各値の説明:
- <First-Label-Of-Partitioned-Service-DNSName> は、サービスの DNS 名の最初の部分です。
- <PartitionPrefix> は、クラスター マニフェストの DnsService セクションで設定できる値、またはクラスターの ARM テンプレートで設定できる値です。 既定値は "--" です。 詳細については、DNS サービスの設定に関するページを参照してください。
- <Target-Partition-Name> は、パーティションの名前です。
- <PartitionSuffix> は、クラスター マニフェストの DnsService セクションで設定できる値、またはクラスターの ARM テンプレートで設定できる値です。 既定値は空の文字列です。 詳細については、DNS サービスの設定に関するページを参照してください。
- <Remaining-Partitioned-Service-DNSName> は、サービスの DNS 名の残りの部分です。
次の例は、PartitionPrefix
と PartitionSuffix
が既定値に設定されたクラスター上で実行されているパーティション分割型サービスの DNS クエリを示しています。
- 範囲パーティション分割構成を使用した、DNS 名が
backendrangedschemesvc.application
であるサービスのパーティション "0" を解決するには、backendrangedschemesvc--0.application
を使用します。 - 名前付きパーティション構成を使用した、DNS 名が
backendnamedschemesvc.application
であるサービスのパーティション "first" を解決するには、backendnamedschemesvc--first.application
を使用します。
DNS サービスからは、パーティションのプライマリ レプリカに関連付けられたエンドポイントの IP アドレスが返されます。 パーティションが指定されていない場合、DNS サービスによってパーティションがランダムに選択されます。
サービスで DNS 名を使用する
DNS 名を指定してサービスをデプロイした場合は、DNS 名を参照することで、公開されているエンドポイントの IP アドレスを確認できます。 DNS サービスは、ステートレス サービスで機能するほか、Service Fabric バージョン 6.3 以降では、ステートフル サービスでも機能します。 Service Fabric のバージョン 6.3 未満で実行されているステートフル サービスの場合、特定のサービス パーティションを呼び出すための HTTP 呼び出しには、ビルトインのリバース プロキシ サービスを使用してください。
動的ポートは、DNS サービスではサポートされていません。 動的ポートを使用するサービスを解決するには、リバース プロキシ サービスを使用してください。
次のコードは、DNS を通じてステートレス サービスを呼び出す方法を示しています。 これはごく普通の HTTP 呼び出しであり、DNS 名とポート、省略可能なパスを URL の一部として指定します。
public class ValuesController : Controller
{
// GET api
[HttpGet]
public async Task<string> Get()
{
string result = "";
try
{
Uri uri = new Uri("http://stateless1.application1:8080/api/values");
HttpClient client = new HttpClient();
var response = await client.GetAsync(uri);
result = await response.Content.ReadAsStringAsync();
}
catch (Exception e)
{
Console.Write(e.Message);
}
return result;
}
}
次のコードは、ステートフル サービスの特定のパーティションに対する呼び出しを示しています。 この例では、DNS 名にパーティション名 (partition1) が含まれています。 この呼び出しでは、PartitionPrefix
と PartitionSuffix
に既定値が使用されているクラスターを想定しています。
public class ValuesController : Controller
{
// GET api
[HttpGet]
public async Task<string> Get()
{
string result = "";
try
{
Uri uri = new Uri("http://stateful1--partition1.application1:8080/api/values");
HttpClient client = new HttpClient();
var response = await client.GetAsync(uri);
result = await response.Content.ReadAsStringAsync();
}
catch (Exception e)
{
Console.Write(e.Message);
}
return result;
}
}
再帰クエリ
DNS サービス単独では解決できない DNS 名 (パブリック DNS 名など) の場合、クエリはノード上の既存の再帰 DNS サーバーに転送されます。
Service Fabric 9.0 より前は、これらのサーバーは 5 秒間の固定タイムアウト期間で、応答が受信されるまで、順次クエリが実行されました。 タイムアウト期間内にサーバーが応答しなかった場合は、次のサーバー (使用可能な場合) にクエリが実行されます。 これらの DNS サーバーで問題が発生した場合、DNS クエリの完了には 5 秒を超える時間がかかります。これは理想的ではありません。
Service Fabric 9.0 以降、並列再帰クエリのサポートが追加されました。 並列クエリを使用すると、すべての再帰 DNS サーバーに一度に接続でき、最初の応答が優先されます。 これにより、前に説明したシナリオでの応答が速くなります。 既定では、このオプションは無効になっています。
また、Service Fabric 9.0 では、タイムアウト期間やクエリ試行回数など、再帰クエリの動作を制御するための詳細なオプションも導入されています。 これらのオプションは、次に示す DNS サービスの設定で設定できます。
- RecursiveQuerySerialMaxAttempts - 最大で試行される直列クエリの数。 この数が DNS サーバーの転送回数より大きい場合、すべてのサーバーが 1 回だけ試行されると、クエリが停止します。
- RecursiveQuerySerialTimeout - 試行される直列クエリごとのタイムアウト値 (秒単位)。
- RecursiveQueryParallelMaxAttempts - 並列クエリが試行される回数。 並列クエリは、直列クエリの最大試行回数に達した後に実行されます。
- RecursiveQueryParallelTimeout - 試行される並列クエリごとのタイムアウト値 (秒単位)。
制限事項と既知の問題
- 動的ポートは、DNS サービスではサポートされていません。 動的ポート上で公開されたサービスを解決するには、リバース プロキシ サービスを使用します。
- 現在、Linux のサポートはコンテナー化されたサービスに限定されています。 現在、Linux のプロセスベースのサービスでは DNS サービスを使用できません。
- Linux クラスターの DNS サービスを Azure portal から有効にすることはできません。
- サービスの DNS 名が変更された場合、状況によっては、名前の更新がすぐに表示されないことがあります。 この問題を解決するには、クラスター全体で DNS サービスのインスタンスを再起動する必要があります。
次のステップ
サービスとの接続と通信に関する記事を参照して、クラスター内でのサービスの通信の詳細を確認する