Azure Service Fabric 中的 DNS 服務

DNS 服務是一個選用的系統服務,您可以在叢集中啟用以使用 DNS 通訊協定來探索其他服務。

許多服務 (特別是容器化服務) 都可透過既有的 URL 來定址。 使用標準 DNS 通訊協定來解析這些服務,而不使用 Service Fabric 命名服務通訊協定,是有其效益的。 DNS 服務可讓您將 DNS 服務對應到某個服務名稱,再由此解析端點 IP 位址。 這類功能可保有容器化服務在不同平台間的可攜性,並簡化「隨即轉移」案例,因為您可以使用現有的服務 URL,而不需要重寫程式碼以使用命名服務。

DNS 服務會將 DNS 名稱對應到服務名稱,接著服務名稱會由命名服務解析並傳回服務端點。 服務的 DNS 名稱是在建立時提供的。 下圖顯示 DNS 服務運用於無狀態服務的情形。 為求簡潔,圖表中只會顯示服務的一個端點,但每個服務其實可以有多個端點。

Diagram showing how DNS names are mapped to service names by DNS service for stateless services.

從 Service Fabric 6.3 版開始,Service Fabric DNS 通訊協定已進行擴充,而包含為分割的具狀態服務定址的配置。 這些擴充功能可讓您使用具狀態服務 DNS 名稱和分割區名稱的組合,來解析特定分割區的 IP 位址。 三種分割配置均受到支援:

  • 具名分割
  • 定界分割
  • 單一分割

下圖顯示 DNS 服務運用於分割具狀態服務的情形。

Diagram showing how DNS names are mapped to service names by DNS service for partitioned stateful services.

如需已分割查詢的詳細資訊,請參閱下面的章節

OS 支援

Windows 和 Linux 叢集都支援 DNS 服務,但是 Linux 的支援目前僅限於容器化服務,且無法透過 Azure 入口網站來啟用。 不過,Windows 支援所有服務類型和部署模型。

啟用 DNS 服務

注意

啟用 DNS 服務會覆寫節點上的一些 DNS 設定。 如果您在連線到網際網路時遇到問題,請檢查您的 DNS 設定。

新叢集

使用 ARM 範本的叢集

若要使用 ARM 範本部署新的叢集,您可以使用範例範本或自行撰寫範本。 您可以藉由使用受支援的最低 API 版本,以及藉由新增適當的設定,在範本中啟用 DNS 服務 (如果尚未啟用的話)。 如需如何完成這項作業的詳細資料,請查看下面編號清單的第 1 點和第 2 點。

使用 Azure 入口網站的叢集

如果您要在入口網站中建立標準叢集,則 [附加元件功能] 區段下的 [包含 DNS 服務] 選項中預設會啟用 DNS 服務。

Screenshot of enabling DNS service for a standard cluster through the portal.

如果您要在入口網站中建立受控叢集,則 [附加元件功能] 區段下的 [DNS 服務] 選項中預設會啟用 DNS 服務。

Screenshot of enabling DNS service for a managed cluster through the portal.

現有叢集

如果您要更新現有受控叢集以啟用 DNS 服務,則可以從入口網站的叢集資源頁面瀏覽 [附加元件服務] 頁面來這麼做。 否則,您也可以使用下面參考的替代方法來啟用 DNS 服務:

  • 如果適用,請使用用來部署叢集的 ARM 範本。
  • 瀏覽至 Azure 資源總管上的叢集並更新叢集資源,如後續步驟中所示 (從步驟 2 開始的步驟)。
  • 瀏覽至入口網站上的叢集,然後按一下 [匯出範本]。 若要深入了解,請參閱從資源群組匯出範本

擁有範本後,您可以使用下列步驟來啟用 DNS 服務:

  1. 若為標準叢集,請檢查 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')]",
        ...
    }
    
  2. 現在,請以下列其中一種方式啟用 DNS 服務:

    • 若要使用預設設定啟用 DNS 服務,將其新增至 properties 區段內的 addonFeatures區段,如下列範例所示:

      "properties": {
        ...
        "addonFeatures": [
          "DnsService"
          ],
        ...
      }
      
    • 若要以預設值以外的設定啟用服務,請將 DnsService 區段新增至 properties 區段內的 fabricSettings 區段。 在此案例中,您不需要將 DnsService 新增至 addonFeatures。 若要深入了解可為 DNS 服務設定的屬性,請參閱 DNS 服務設定

      "properties": {
       ...
       "fabricSettings": [
         ...
         {
           "name": "DnsService",
           "parameters": [
             {
               "name": "IsEnabled",
               "value": "true"
             },
             {
               "name": "<key>",
               "value": "<value>"
             }
           ]
         },
         ...
       ]
      }
      
  3. 在使用您的變更將叢集範本更新之後,請加以套用,使升級完成。 升級完成後,DNS 系統服務就會開始在叢集中執行。 服務名稱是 fabric:/System/DnsService,而且您可以在 Service Fabric Explorer 的 [系統] 服務區段下找到它。

注意

將 DNS 從 disabled 升級為 enabled 時,Service Fabric Explorer 可能不會反映新的狀態。 若要解決此問題,請藉由修改範本中的升級原則來重新啟動節點。

為您的服務設定 DNS 名稱

您可以透過 ARM 範本、透過 ApplicationManifest.xml 檔案中的預設服務,或透過 PowerShell 命令,來為您的服務設定 DNS 名稱。

服務的 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 查詢中作為目標的分割區所需符合的要求;如需詳細資訊,請參閱對具狀態服務分割區進行 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

確認已在 Service Fabric Explorer 中設定 DNS 名稱

使用 DNS 名稱部署服務之後,Service Fabric Explorer 會顯示服務的 DNS 名稱,如下圖所示:

Screenshot of the DNS name in Service Fabric Explorer.

注意

視所使用的 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 名稱的其餘部分。

下列範例顯示對於在叢集上執行、PartitionPrefixPartitionSuffix 採用預設設定的分割服務所做的 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 呼叫的內建反向 Proxy 服務,來呼叫特定的服務分割區。

DNS 服務不支援動態連接埠。 您可以使用反向 Proxy 服務來解析使用動態連接埠的服務。

下列程式碼說明如何透過 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)。 此呼叫採用 PartitionPrefixPartitionSuffix 皆為預設值的叢集。

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 伺服器。

Diagram showing how DNS queries for public names are resolved.

在 Service Fabric 9.0 之前,這些伺服器會以 5 秒的固定逾時期間循序進行查詢,直到收到回應為止。 如果伺服器未在逾時期間內回應,則會查詢下一部伺服器 (若可用)。 在這些 DNS 伺服器遇到任何問題時,完成 DNS 查詢需要超過 5 秒的時間,這並不理想。

從 Service Fabric 9.0 開始,已新增平行遞迴查詢的支援。 使用平行查詢時,可以一次連絡所有遞迴 DNS 伺服器,其中第一個回應會勝出。 這會導致上述案例中的回應更快。 預設不啟用這個選項。

Service Fabric 9.0 中也引進精細的選項來控制遞迴查詢的行為,包括逾時期間和查詢嘗試。 您可以在 DNS 服務設定中設定這些選項:

  • RecursiveQuerySerialMaxAttempts - 會嘗試的序列查詢數目上限。 如果此數目高於轉送 DNS 伺服器的數目,查詢將會在嘗試所有伺服器一次後停止。
  • RecursiveQuerySerialTimeout - 每個嘗試序列查詢的逾時值 (以秒為單位)。
  • RecursiveQueryParallelMaxAttempts - 將嘗試平行查詢的次數。 在序列查詢達到嘗試上限之後,便會執行平行查詢。
  • RecursiveQueryParallelTimeout - 每個嘗試平行查詢的逾時值 (以秒為單位)。

限制和已知問題

  • DNS 服務不支援動態連接埠。 若要解決動態連接埠上所公開的服務,請使用反向 Proxy 服務
  • 對於 Linux 的支援目前僅限於容器化服務。 Linux 上的程序型服務目前無法使用 DNS 服務。
  • 無法透過 Azure 入口網站啟用 Linux 叢集的 DNS 服務。
  • 如果服務的 DNS 名稱有所變更,在某些情況下可能無法立即看到名稱更新。 若要解決此問題,請在叢集上重新啟動 DNS 服務執行個體。

下一步

若要深入了解叢集內的服務通訊,請參閱連接服務並與其進行通訊