Служба DNS в Azure Service Fabric
Служба DNS — это необязательная системная служба, которую можно включить в кластере для обнаружения других служб с помощью протокола DNS.
Ко многим службам, особенно контейнерным, можно обращаться через существующие URL-адреса. Предпочтительно разрешать эти службы с помощью стандартного протокола DNS, а не протокола службы именования Service Fabric. Служба DNS позволяет сопоставлять DNS-имена с именем службы и, следовательно, разрешать IP-адреса конечных точек. Такая функциональность обеспечивает переносимость контейнерных служб на разных платформах и упрощает сценарии "лифт и смена", позволяя использовать существующие URL-адреса службы, а не переписать код для использования службы именования.
Служба DNS сопоставляет DNS-имена с именами служб, которые, в свою очередь, разрешаются службой именования для возврата конечной точки службы. DNS-имя службы предоставляется при создании. На следующей схеме показано, как служба DNS работает для служб без отслеживания состояния. Для краткости схемы отображают только одну конечную точку для служб, хотя каждая служба может иметь несколько конечных точек.
Начиная с версии 6.3 Service Fabric, протокол DNS Service Fabric был расширен и теперь включает схему адресации секционированных служб с отслеживанием состояния. Эти расширения позволяют разрешать IP-адреса определенных секций, используя сочетание DNS-имени службы с отслеживанием состояния и имени секции. Поддерживаются все три схемы секционирования:
- секционирование по именам;
- секционирование по диапазонам;
- секционирование по отдельным базам данных.
На следующей схеме показано, как служба DNS работает для секционированных служб с отслеживанием состояния.
Дополнительные сведения о секционированных запросах см. в разделе ниже.
Поддержка ОС
Служба DNS поддерживается как в кластерах Windows, так и в Linux, хотя поддержка Linux в настоящее время ограничена контейнерными службами и не может быть включена через портал Azure. Однако Windows поддерживает все типы служб и модели развертывания.
Включение службы DNS
Примечание.
Включение службы DNS переопределит некоторые параметры DNS на узлах. Если возникнут проблемы с подключением к Интернету, проверьте параметры DNS.
Новые кластеры
Кластеры с помощью шаблонов ARM
Чтобы развернуть новый кластер с помощью шаблонов ARM, можно использовать примеры шаблонов или написать собственные. Если это еще не сделано, служба DNS может быть включена в шаблонах с помощью минимальных поддерживаемых версий API и путем добавления соответствующих параметров. Подробные сведения о том, как это сделать, можно увидеть ниже в пунктах 1 и 2 нумерованного списка.
Кластеры с помощью портал Azure
Если вы создаете стандартный кластер на портале, служба DNS включена по умолчанию в параметре "Включить службу DNS " в разделе "Добавление компонентов ".
Если вы создаете управляемый кластер на портале, служба DNS включена по умолчанию в параметре службы DNS в разделе "Добавление компонентов".
Существующие кластеры
Если вы обновляете существующий управляемый кластер, чтобы включить службу DNS, вы можете сделать это на портале, перейдя на страницу служб надстройки на странице ресурсов кластера. В противном случае можно включить службу DNS с помощью альтернативных методов, на которые ссылается следующая ссылка:
- Используйте шаблон ARM, который использовался для развертывания кластера, если применимо.
- Перейдите к кластеру в обозревателе ресурсов Azure и обновите ресурс кластера, как показано ниже (на шаге 2 и далее).
- Перейдите к кластеру на портале и нажмите кнопку "Экспорт шаблона". Чтобы узнать больше, ознакомьтесь с разделом Экспорт шаблона из группы ресурсов.
После создания шаблона можно включить службу DNS с помощью следующих действий:
Для стандартных кластеров убедитесь, что
apiVersion
для ресурса задано2017-07-01-preview
значение или более поздней версииMicrosoft.ServiceFabric/clusters
, а если нет, обновите его, как показано в следующем примере:{ "apiVersion": "2017-07-01-preview", "type": "Microsoft.ServiceFabric/clusters", "name": "[parameters('clusterName')]", "location": "[parameters('clusterLocation')]", ... }
Для управляемых кластеров убедитесь, что
apiVersion
для ресурса задано2020-01-01-preview
значение или более поздней версииMicrosoft.ServiceFabric/managedClusters
, а если нет, обновите его, как показано в следующем примере:{ "apiVersion": "2020-01-01-preview", "type": "Microsoft.ServiceFabric/managedClusters", "name": "[parameters('clusterName')]", "location": "[parameters('clusterLocation')]", ... }
Теперь включите службу DNS одним из следующих способов:
Чтобы включить службу DNS с параметрами по умолчанию, добавьте ее
addonFeatures
в раздел внутриproperties
раздела, как показано в следующем примере:"properties": { ... "addonFeatures": [ "DnsService" ], ... }
Чтобы включить службу с параметрами, отличными от параметров по умолчанию, добавьте блок
DnsService
в разделfabricSettings
внутри разделаproperties
. В этом случае добавлять DnsService в разделaddonFeatures
не требуется. Дополнительные сведения о свойствах, которые можно задать для службы DNS, см. в разделе параметров службы DNS."properties": { ... "fabricSettings": [ ... { "name": "DnsService", "parameters": [ { "name": "IsEnabled", "value": "true" }, { "name": "<key>", "value": "<value>" } ] }, ... ] }
После обновления шаблона кластера примените изменения и дождитесь завершения обновления. По завершении обновления в кластере запустится системная служба DNS. Имя этой службы —
fabric:/System/DnsService
, и ее можно найти в разделе служб Система в обозревателе Service Fabric.
Примечание.
При обновлении DNS с отключения до включения Service Fabric Explorer может не отражать новое состояние. Чтобы устранить проблему, перезапустите узлы, изменив политику обновления в шаблоне.
Настройка DNS-имени для службы
Dns-имена для служб можно задать с помощью шаблонов ARM, служб по умолчанию в файле ApplicationManifest.xml или с помощью команд PowerShell.
DNS-имя службы можно разрешить во всем кластере, поэтому важно обеспечить уникальность DNS-имени в кластере.
Настоятельно рекомендуется использовать схему именования <ServiceName>.<AppName>
. Пример: service1.application1
. Если приложение развернуто с помощью Docker Compose, службам автоматически присваиваются DNS-имена с помощью данной схемы именования.
Настройка DNS-имени с помощью шаблона ARM
Если вы используете шаблоны ARM для развертывания служб, вы можете добавить serviceDnsName
свойство в соответствующий раздел и назначить ему значение. Ниже приведены примеры.
Кластеры уровня «Стандартный»
Для стандартных кластеров убедитесь, что apiVersion
для ресурса задано 2019-11-01-preview
значение или более поздней версии Microsoft.ServiceFabric/clusters/applications/services
, а если нет, обновите его, как показано в следующем примере:
{
"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')]"
}
}
Управляемые кластеры
Для управляемых кластеров убедитесь, что apiVersion
для ресурса задано 2022-10-01-preview
значение или более поздней версии Microsoft.ServiceFabric/managedclusters/applications/services
, а если нет, обновите его, как показано в следующем примере:
{
"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')]"
}
}
Настройка DNS-имени службы по умолчанию в файле ApplicationManifest.xml
Откройте проект в 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>
Настройка DNS-имени для службы с помощью PowerShell
При создании службы можно задать DNS-имя, используя New-ServiceFabricService
команду PowerShell. В следующем примере создается новая служба без отслеживания состояния с 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-имя службы, как показано на следующем рисунке:
Примечание.
Это представление может отличаться в зависимости от используемой версии 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-имени службы.
В следующих примерах показаны DNS-запросы для секционированных служб, запущенных в кластере, где используются значения по умолчанию для PartitionPrefix
и PartitionSuffix
:
- Чтобы разрешить раздел "0" службы с DNS-именем
backendrangedschemesvc.application
, использующим схему секционирования с диапазоном, используйтеbackendrangedschemesvc--0.application
. - Чтобы разрешить раздел "first" службы с DNS-именем
backendnamedschemesvc.application
, использующим именованную схему секционирования, используйтеbackendnamedschemesvc--first.application
.
Служба DNS возвращает IP-адрес конечной точки, связанной с первичной репликой секции. Если секция не указана, служба DNS случайно выбирает секцию.
Использование DNS-имен в службах
При развертывании служб с DNS-именами можно найти IP-адрес предоставляемых конечных точек, ссылаясь на DNS-имя. Служба 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-серверов пересылки, запрос будет остановлен после того, как все серверы были предпринята ровно один раз.
- RecursiveQuerySerialTimeout — значение времени ожидания в секундах для каждого выполняемого последовательного запроса.
- RecursiveQueryParallelMaxAttempts — количество попыток параллельных запросов. Параллельные запросы выполняются после максимального числа попыток последовательных запросов.
- RecursiveQueryParallelTimeout — значение времени ожидания в секундах для каждого параллельного запроса.
Известные проблемы и ограничения
- Динамические порты не поддерживаются службой DNS. Чтобы разрешать службы, предоставляемые через динамические порты, используйте службу обратного прокси-сервера.
- Поддержка Linux в настоящее время ограничена контейнерными службами. В настоящее время службы на основе процессов в Linux не могут использовать службу DNS.
- Служба DNS для кластеров Linux не может быть включена через портал Azure.
- Если DNS-имя изменено для службы, обновления имен могут не сразу отображаться в некоторых сценариях. Чтобы устранить проблему, экземпляры службы DNS следует перезапустить в кластере.
Следующие шаги
Дополнительные сведения о взаимодействии служб в кластере см. в статье Подключение к службам в Service Fabric и взаимодействие с ними.