Поделиться через


Создание первого приложения контейнера Service Fabric в Windows

Запуск существующего приложения в контейнере Windows в кластере Service Fabric не требует каких-либо изменений в приложении. В этой статье описано, как создать образ Docker, содержащий веб-приложение Python Flask и развернуть его в кластере Azure Service Fabric. Кроме того, вы будете совместно использовать контейнерное приложение через Реестр контейнеров Azure. В этой статье предполагается базовое понимание Docker. Вы можете узнать о Docker, прочитав обзор Docker.

Примечание.

Эта статья относится к среде разработки Windows. Среда выполнения кластера Service Fabric и среда выполнения Docker должны работать в той же ОС. Вы не можете запускать контейнеры Windows в кластере Linux.

Примечание.

Мы рекомендуем использовать модуль Azure Az PowerShell для взаимодействия с Azure. Чтобы начать работу, см. статью Установка Azure PowerShell. Чтобы узнать, как осуществить переход на модуль Az PowerShell, см. статью Перенос Azure PowerShell с AzureRM на Az.

Предпосылки

  • Компьютер для разработки, на котором работает:

  • Кластер Windows с тремя или более узлами, работающими на Windows Server с установленным Docker. Дополнительные сведения о том, как установить Docker в кластере, см. в разделе "Установка среды выполнения Mirantis".

    Для этого случая версия (сборка) Windows Server, запущенная на узлах кластера, должна соответствовать версии на вашей машине для разработки. Это связано с тем, что вы создаете образ Docker на компьютере разработки, и существуют ограничения совместимости между версиями ОС контейнера и операционной системой узла, на которой она развернута. Дополнительные сведения см. в разделе о совместимости ОС контейнера Windows Server и ОС узла.

    Чтобы определить версию Windows Server с контейнерами, необходимыми для кластера, выполните ver команду из командной строки Windows на компьютере разработки. Перед созданием кластера обратитесь к совместимости ОС контейнера и хоста Windows Server.

  • Реестр контейнеров Azure— создание реестра контейнеров в подписке Azure.

Примечание.

Развертывание контейнеров в кластере Service Fabric, работающем в Windows 10, поддерживается. Сведения о настройке Windows 10 для запуска контейнеров Windows см. в этой статье .

Примечание.

Service Fabric версии 6.2 и более поздних версий поддерживает развертывание контейнеров в кластерах, работающих в Windows Server версии 1709.

Определение контейнера Docker

Создайте образ на основе образа Python , расположенного в Docker Hub.

Укажите контейнер Docker в Dockerfile. Dockerfile состоит из инструкций для настройки среды в вашем контейнере, загрузки приложения, которое требуется запустить, и сопоставления портов. Dockerfile — это входной файл для команды docker build, создающей образ.

Создайте пустой каталог и создайте файл Dockerfile (без расширения файла). Добавьте следующее в Dockerfile и сохраните изменения:

# Use an official Python runtime as a base image
FROM python:2.7-windowsservercore

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
ADD . /app

# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "app.py"]

Дополнительные сведения см. в справочнике по Dockerfile .

Создание базового веб-приложения

Создайте веб-приложение Flask, которое прослушивает порт 80 и возвращает Hello World!. В том же каталоге создайте файл requirements.txt. Добавьте следующие изменения и сохраните изменения:

Flask

Также создайте файл app.py и добавьте следующий фрагмент кода:

from flask import Flask

app = Flask(__name__)


@app.route("/")
def hello():

    return 'Hello World!'


if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

Вход в Docker и создание образа

Далее мы создадим образ, который запускает веб-приложение. При извлечении общедоступных образов из Docker (например python:2.7-windowsservercore, в нашем Dockerfile) рекомендуется аутентифицироваться в своей учетной записи Docker Hub вместо анонимного запроса на извлечение.

Примечание.

При частом выполнении анонимных pull-запросов могут возникать ошибки Docker, аналогичные ERROR: toomanyrequests: Too Many Requests. или You have reached your pull rate limit.. Чтобы предотвратить эти ошибки, выполните аутентификацию в Docker Hub. Дополнительные сведения см. в статье "Управление общедоступным содержимым с помощью реестра контейнеров Azure ".

Откройте окно PowerShell и перейдите в каталог, содержащий Dockerfile. Затем выполните следующие команды:

docker login
docker build -t helloworldapp .

Эта команда создает новый образ с помощью инструкций в Dockerfile, именования (-t тегов) образа helloworldapp. Чтобы создать образ контейнера, базовый образ сначала скачан из Docker Hub, в который добавляется приложение.

После завершения команды сборки выполните docker images команду, чтобы просмотреть сведения о новом образе:

$ docker images

REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
helloworldapp                 latest              8ce25f5d6a79        2 minutes ago       10.4 GB

Локальное запуск приложения

Перед отправкой образа в реестр контейнеров проверьте образ локально.

Запустите приложение:

docker run -d --name my-web-site helloworldapp

Имя присваивает запущенным контейнеру имя (вместо идентификатора контейнера).

После запуска контейнера найдите его IP-адрес, чтобы подключиться к работающему контейнеру из браузера:

docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" my-web-site

Если эта команда не возвращает ничего, выполните следующую команду и проверьте элемент NetworkSettings-Networks> для IP-адреса:

docker inspect my-web-site

Подключитесь к работающему контейнеру. Откройте веб-браузер, указывающий на возвращенный IP-адрес, например "http://172.31.194.61". В браузере появится заголовок Hello World!

Чтобы остановить контейнер, выполните следующую команду:

docker stop my-web-site

Удалите контейнер с компьютера разработки:

docker rm my-web-site

Отправьте образ в реестр контейнеров

После того как вы убедились, что контейнер выполняется на вашей рабочей машине, загрузите образ в Azure Container Registry.

Выполните docker login вход в вашу реестр контейнеров с помощью ваших учетных данных реестра.

В следующем примере передается идентификатор и пароль сервисного принципала Microsoft Entra. Например, вы могли назначить сервисный принципал вашему реестру для сценария автоматизации. Кроме того, вы можете войти с помощью имени пользователя и пароля реестра.

docker login myregistry.azurecr.io -u xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -p myPassword

Следующая команда создает тег или псевдоним изображения с полным путем к реестру. В этом примере изображение помещается в пространство имен samples, чтобы избежать захламлённости в корневой части реестра.

docker tag helloworldapp myregistry.azurecr.io/samples/helloworldapp

Отправьте образ в реестр контейнеров:

docker push myregistry.azurecr.io/samples/helloworldapp

Создание контейнерной службы в Visual Studio

Пакет SDK и средства Service Fabric предоставляют шаблон службы для создания контейнерного приложения.

  1. Запустите Visual Studio. Выберите Файл>Создать>Проект.
  2. Выберите приложение Service Fabric, назовите его "MyFirstContainer" и нажмите кнопку "ОК".
  3. Выберите контейнер из списка шаблонов служб.
  4. В поле «Имя образа» введите "myregistry.azurecr.io/samples/helloworldapp", образ, который вы отправили в ваш репозиторий контейнеров.
  5. Присвойте службе имя и нажмите кнопку "ОК".

Настройка связи

Контейнерная служба нуждается в конечной точке для обмена данными. Endpoint Добавьте элемент с протоколом, портом и типом в файл ServiceManifest.xml. В этом примере используется фиксированный порт 8081. Если порт не указан, выбирается случайный порт из диапазона портов приложения.

<Resources>
  <Endpoints>
    <Endpoint Name="Guest1TypeEndpoint" UriScheme="http" Port="8081" Protocol="http"/>
  </Endpoints>
</Resources>

Примечание.

Дополнительные конечные точки для службы можно добавить, объявив дополнительные элементы EndPoint с применимыми значениями свойств. Каждый порт может объявлять только одно значение протокола.

Определив конечную точку, Service Fabric публикует конечную точку в службе именования. Другие службы, работающие в кластере, могут определять этот контейнер. Вы также можете выполнять обмен данными между контейнерами с помощью обратного прокси-сервера. Обмен данными выполняется путем предоставления порта прослушивания обратного прокси-сервера и имени служб, с которыми вы хотите взаимодействовать в качестве переменных среды.

Служба прослушивает определенный порт (8081 в этом примере). Когда приложение разворачивается в кластере Azure, и кластер, и приложение работают за балансировщиком нагрузки Azure. Порт приложения должен быть открыт в подсистеме балансировки нагрузки Azure, чтобы входящий трафик можно было пройти через службу. Этот порт можно открыть в подсистеме балансировки нагрузки Azure с помощью скрипта PowerShell или на портале Azure.

Настройка и установка переменных среды

Переменные среды можно указать для каждого пакета кода в манифесте службы. Эта функция доступна для всех служб независимо от того, развертываются ли они как контейнеры или процессы или гостевые исполняемые файлы. Можно переопределить значения переменных среды в манифесте приложения или указать их во время развертывания в качестве параметров приложения.

В следующем фрагменте XML-кода манифеста службы показан пример указания переменных среды для пакета кода:

<CodePackage Name="Code" Version="1.0.0">
  ...
  <EnvironmentVariables>
    <EnvironmentVariable Name="HttpGatewayPort" Value=""/>    
  </EnvironmentVariables>
</CodePackage>

Эти переменные среды можно переопределить в манифесте приложения:

<ServiceManifestImport>
  <ServiceManifestRef ServiceManifestName="Guest1Pkg" ServiceManifestVersion="1.0.0" />
  <EnvironmentOverrides CodePackageRef="FrontendService.Code">
    <EnvironmentVariable Name="HttpGatewayPort" Value="19080"/>
  </EnvironmentOverrides>
  ...
</ServiceManifestImport>

Настройка сопоставления порта контейнера с портом хоста и обнаружения контейнера к контейнеру

Настройте порт узла, используемый для взаимодействия с контейнером. Привязка портов сопоставляет порт, на котором служба прослушивает внутри контейнера, с портом на узле. Добавьте элемент PortBinding в элемент ContainerHostPolicies файла ApplicationManifest.xml. Для этой статьи ContainerPort используется значение 80 (контейнер предоставляет порт 80, как указано в Dockerfile) и EndpointRef является "Guest1TypeEndpoint" (конечная точка, ранее определенная в манифесте службы). Входящие запросы к службе через порт 8081 сопоставляются с портом 80 на контейнере.

<ServiceManifestImport>
    ...
    <Policies>
        <ContainerHostPolicies CodePackageRef="Code">
            <PortBinding ContainerPort="80" EndpointRef="Guest1TypeEndpoint"/>
        </ContainerHostPolicies>
    </Policies>
    ...
</ServiceManifestImport>

Примечание.

Дополнительные связывания портов для службы можно добавить, объявив дополнительные элементы PortBinding с подходящими значениями свойств.

Настройка проверки подлинности репозитория контейнеров

Ознакомьтесь с проверкой подлинности репозитория контейнеров, чтобы узнать, как настроить различные типы проверки подлинности для скачивания образа контейнера.

Настройка режима изоляции

Windows поддерживает два режима изоляции для контейнеров: процесс и Hyper-V. В режиме изоляции процесса все контейнеры, работающие на одном компьютере узла, совместно используют ядро с узлом. При использовании режима изоляции Hyper-V ядра изолированы между каждым контейнером Hyper-V и узлом-хостом контейнера. Режим изоляции указывается в элементе ContainerHostPolicies в файле манифеста приложения. Режимы изоляции, которые можно указать, это process, hyperv и default. По умолчанию используется режим изоляции процесса на узлах Windows Server. На узлах Windows 10 поддерживается только режим изоляции Hyper-V, поэтому контейнер выполняется в режиме изоляции Hyper-V независимо от его параметра режима изоляции. В следующем фрагменте кода показано, как режим изоляции указан в файле манифеста приложения.

<ContainerHostPolicies CodePackageRef="Code" Isolation="hyperv">

Примечание.

Режим изоляции Hyper-V доступен на SKU Azure Ev3 и Dv3, которые поддерживают вложенную виртуализацию.

Настройка управления ресурсами

Управление ресурсами ограничивает ресурсы, которые контейнер может использовать на узле. Элемент ResourceGovernancePolicy , указанный в манифесте приложения, используется для объявления ограничений ресурсов для пакета кода службы. Ограничения ресурсов можно задать для следующих ресурсов: memory, MemorySwap, CpuShares (относительный вес ЦП), MemoryReservationInMB, BlkioWeight (BlockIO относительный вес). В этом примере пакет службы Guest1Pkg получает одно ядро на узлах кластера, где он размещен. Ограничения памяти являются абсолютными, поэтому пакет кода ограничен 1024 МБ памяти (и мягким гарантированным резервированием такого же объёма). Пакеты кода (контейнеры или процессы) не могут выделить больше памяти, чем это ограничение, и попытка сделать это приводит к исключению из памяти. Для обеспечения работы ограничения ресурсов все пакеты кода в пакете службы должны иметь ограничения памяти.

<ServiceManifestImport>
  <ServiceManifestRef ServiceManifestName="Guest1Pkg" ServiceManifestVersion="1.0.0" />
  <Policies>
    <ServicePackageResourceGovernancePolicy CpuCores="1"/>
    <ResourceGovernancePolicy CodePackageRef="Code" MemoryInMB="1024"  />
  </Policies>
</ServiceManifestImport>

Настройка docker HEALTHCHECK

Начиная с версии 6.1 Service Fabric автоматически интегрирует события docker HEALTHCHECK в отчет о работоспособности системы. Это означает, что если в контейнере включена функция HEALTHCHECK , Service Fabric будет сообщать о работоспособности всякий раз, когда состояние работоспособности контейнера изменяется, как сообщает Docker. Отчет о работоспособности OK появится в Service Fabric Explorer , когда health_statusработоспособен , и предупреждение появится, когда health_statusнеработоспособен.

Начиная с последнего обновления версии 6.4, можно указать, что результаты проверки docker HEALTHCHECK должны восприниматься как ошибка. Если этот параметр включен, отчет о состоянии здоровья ОК будет отображаться, когда health_statusздоровое состояние, а ОШИБКА будет отображаться, когда health_statusнездоровое состояние.

Инструкция HEALTHCHECK , указывающая на фактическую проверку работоспособности контейнера, должна присутствовать в Dockerfile, используемой при создании образа контейнера.

Снимок экрана показывает сведения о развернутом пакете службы NodeServicePackage.

HealthCheckUnhealthyApp

HealthCheckUnhealthyDsp

Вы можете настроить поведение HEALTHCHECK для каждого контейнера, указав параметры HealthConfig в составе ContainerHostPolicies в ApplicationManifest.

<ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="ContainerServicePkg" ServiceManifestVersion="2.0.0" />
    <Policies>
      <ContainerHostPolicies CodePackageRef="Code">
        <HealthConfig IncludeDockerHealthStatusInSystemHealthReport="true"
		      RestartContainerOnUnhealthyDockerHealthStatus="false" 
		      TreatContainerUnhealthyStatusAsError="false" />
      </ContainerHostPolicies>
    </Policies>
</ServiceManifestImport>

По умолчанию параметр IncludeDockerHealthStatusInSystemHealthReport имеет значение true, параметр RestartContainerOnUnhealthyDockerHealthStatus задано значение false, а параметр TreatContainerUnhealthyStatusAsError задано значение false.

Если параметр RestartContainerOnUnhealthyDockerHealthStatus установлен в true, контейнер с нездоровым состоянием перезапускается (возможно, на других узлах).

Если параметр TreatContainerUnhealthyStatusAsError имеет значение true, отчеты о работоспособности ERROR будут отображаться, когда health_status контейнера неработоспособен.

Если вы хотите отключить интеграцию HEALTHCHECK для всего кластера Service Fabric, необходимо задать для параметра EnableDockerHealthCheckIntegrationзначение false.

Развертывание приложения контейнера

Сохраните все изменения и создайте приложение. Чтобы опубликовать приложение, щелкните правой кнопкой мыши MyFirstContainer в обозревателе решений и выберите "Опубликовать".

В конечной точке подключения введите конечную точку управления для кластера. Например, containercluster.westus2.cloudapp.azure.com:19000. Конечную точку подключения клиента можно найти на вкладке "Обзор" кластера на портале Azure.

Нажмите кнопку Опубликовать.

Service Fabric Explorer — это веб-средство для проверки приложений и узлов в кластере Service Fabric и управления ими. Откройте браузер, перейдите к http://containercluster.westus2.cloudapp.azure.com:19080/Explorer/ и следуйте инструкциям по развертыванию приложения. Приложение развертывается, но находится в состоянии ошибки, пока образ не будет скачан на узлах кластера (что может занять некоторое время в зависимости от размера изображения): Ошибка

Приложение готово, когда оно находится в Ready состоянии: Готово

Откройте веб-браузер и перейдите по адресу http://containercluster.westus2.cloudapp.azure.com:8081. В браузере появится заголовок Hello World!

Очистка

Пока кластер запущен, продолжает взиматься плата; рассмотрите удаление кластера.

После отправки образа в реестр контейнеров можно удалить локальный образ с компьютера разработки:

docker rmi helloworldapp
docker rmi myregistry.azurecr.io/samples/helloworldapp

Совместимость ОС контейнера Windows Server и ОС хоста

Контейнеры Windows Server несовместимы во всех версиях ос узла. Рассмотрим пример.

  • Контейнеры Windows Server, созданные с помощью Windows Server версии 1709, не работают на узле под управлением Windows Server версии 2016.
  • Контейнеры Windows Server, созданные с помощью Windows Server 2016, работают в режиме изоляции Hyper-V только на узле под управлением Windows Server версии 1709.
  • При использовании контейнеров Windows Server, созданных с помощью Windows Server 2016, может потребоваться убедиться, что редакция ОС контейнера и ос узла совпадают при выполнении в режиме изоляции процесса на узле под управлением Windows Server 2016.

Дополнительные сведения см. в статье о совместимости версий контейнеров Windows.

При создании и развертывании контейнеров в кластере Service Fabric следует учитывать совместимость операционной системы узла и операционной системы контейнеров. Рассмотрим пример.

  • Убедитесь, что вы развертываете контейнеры с ОС, совместимой с ОС на узлах кластера.
  • Убедитесь, что режим изоляции, указанный для приложения контейнера, согласуется с поддержкой ОС контейнера на узле, в котором он развертывается.
  • Рассмотрим, как обновление ОС до узлов кластера или контейнеров может повлиять на их совместимость.

Мы рекомендуем использовать следующие методики, чтобы убедиться, что контейнеры развернуты правильно в кластере Service Fabric:

  • Используйте явные теги изображений с образами Docker, чтобы указать версию ОС Windows Server, из которую создан контейнер.
  • Используйте теги ОС в файле манифеста приложения, чтобы убедиться, что приложение совместимо с различными версиями и обновлениями Windows Server.

Примечание.

С помощью Service Fabric версии 6.2 и более поздних версий можно развернуть контейнеры на основе Windows Server 2016 локально на узле Windows 10. В Windows 10 контейнеры выполняются в режиме изоляции Hyper-V независимо от режима изоляции, заданного в манифесте приложения. Дополнительные сведения см. в разделе "Настройка режима изоляции".

Указание контейнерных образов, специфичных для сборки ОС

Контейнеры Windows Server могут быть несовместимы в разных версиях ОС. Например, контейнеры Windows Server, созданные с помощью Windows Server 2016, не работают в Windows Server версии 1709 в режиме изоляции процесса. Таким образом, если узлы кластера обновляются до последней версии, службы контейнеров, созданные с использованием более ранних версий ОС, могут выйти из строя. Чтобы обойти это с версией 6.1 среды выполнения и более новой, Service Fabric поддерживает указание нескольких образов ОС для каждого контейнера и их маркировку с помощью версий сборки ОС в манифесте приложения. Вы можете получить версию сборки ОС, выполнив команду winver в командной строке Windows. Обновите манифесты приложения и укажите переопределения образов для каждой версии операционной системы перед обновлением ОС на узлах. В следующем фрагменте кода показано, как указать несколько образов контейнеров в манифесте приложения ,ApplicationManifest.xml:

      <ContainerHostPolicies> 
         <ImageOverrides> 
	       <Image Name="myregistry.azurecr.io/samples/helloworldappDefault" /> 
               <Image Name="myregistry.azurecr.io/samples/helloworldapp1701" Os="14393" /> 
               <Image Name="myregistry.azurecr.io/samples/helloworldapp1709" Os="16299" /> 
         </ImageOverrides> 
      </ContainerHostPolicies> 

Версия сборки для Windows Server 2016 — 14393, а версия сборки для Windows Server версии 1709 — 16299. Манифест службы продолжает указывать только один образ для каждой службы контейнеров, как показано ниже.

<ContainerHost>
    <ImageName>myregistry.azurecr.io/samples/helloworldapp</ImageName> 
</ContainerHost>

Примечание.

Функция тегов версии сборки ОС доступна только для Service Fabric в Windows.

Если базовая ОС на виртуальной машине сборка 16299 (версия 1709), Service Fabric выбирает образ контейнера, соответствующий этой версии Windows Server. Если образ контейнера без тегов также предоставляется вместе с помеченными образами контейнеров в манифесте приложения, то Service Fabric обрабатывает образ без тегов как образ, который работает во всех версиях. Отмечайте изображения контейнеров явно, чтобы избежать проблем при обновлениях.

Образ контейнера без метки будет использоваться для замены предоставленного в ServiceManifest. Поэтому изображение "myregistry.azurecr.io/samples/helloworldappDefault" переопределит имя образа "myregistry.azurecr.io/samples/helloworldapp" в ServiceManifest.

Полный пример манифестов приложений и служб Service Fabric

Ниже приведены полные манифесты службы и приложения, используемые в этой статье.

ServiceManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="Guest1Pkg"
                 Version="1.0.0"
                 xmlns="http://schemas.microsoft.com/2011/01/fabric"
                 xmlns:xsd="https://www.w3.org/2001/XMLSchema"
                 xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
  <ServiceTypes>
    <!-- This is the name of your ServiceType.
         The UseImplicitHost attribute indicates this is a guest service. -->
    <StatelessServiceType ServiceTypeName="Guest1Type" UseImplicitHost="true" />
  </ServiceTypes>

  <!-- Code package is your service executable. -->
  <CodePackage Name="Code" Version="1.0.0">
    <EntryPoint>
      <!-- Follow this link for more information about deploying Windows containers to Service Fabric: https://aka.ms/sfguestcontainers -->
      <ContainerHost>
        <ImageName>myregistry.azurecr.io/samples/helloworldapp</ImageName>
        <!-- Pass comma delimited commands to your container: dotnet, myproc.dll, 5" -->
        <!--Commands> dotnet, myproc.dll, 5 </Commands-->
        <Commands></Commands>
      </ContainerHost>
    </EntryPoint>
    <!-- Pass environment variables to your container: -->    
    <EnvironmentVariables>
      <EnvironmentVariable Name="HttpGatewayPort" Value=""/>
      <EnvironmentVariable Name="BackendServiceName" Value=""/>
    </EnvironmentVariables>

  </CodePackage>

  <!-- Config package is the contents of the Config directory under PackageRoot that contains an
       independently-updateable and versioned set of custom configuration settings for your service. -->
  <ConfigPackage Name="Config" Version="1.0.0" />

  <Resources>
    <Endpoints>
      <!-- This endpoint is used by the communication listener to obtain the port on which to
           listen. Please note that if your service is partitioned, this port is shared with
           replicas of different partitions that are placed in your code. -->
      <Endpoint Name="Guest1TypeEndpoint" UriScheme="http" Port="8081" Protocol="http"/>
    </Endpoints>
  </Resources>
</ServiceManifest>

ApplicationManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest ApplicationTypeName="MyFirstContainerType"
                     ApplicationTypeVersion="1.0.0"
                     xmlns="http://schemas.microsoft.com/2011/01/fabric"
                     xmlns:xsd="https://www.w3.org/2001/XMLSchema"
                     xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
  <Parameters>
    <Parameter Name="Guest1_InstanceCount" DefaultValue="-1" />
  </Parameters>
  <!-- Import the ServiceManifest from the ServicePackage. The ServiceManifestName and ServiceManifestVersion
       should match the Name and Version attributes of the ServiceManifest element defined in the
       ServiceManifest.xml file. -->
  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="Guest1Pkg" ServiceManifestVersion="1.0.0" />
    <EnvironmentOverrides CodePackageRef="FrontendService.Code">
      <EnvironmentVariable Name="HttpGatewayPort" Value="19080"/>
    </EnvironmentOverrides>
    <ConfigOverrides />
    <Policies>
      <ContainerHostPolicies CodePackageRef="Code">
        <RepositoryCredentials AccountName="myregistry" Password="MIIB6QYJKoZIhvcNAQcDoIIB2jCCAdYCAQAxggFRMIIBTQIBADA1MCExHzAdBgNVBAMMFnJ5YW53aWRhdGFlbmNpcGhlcm1lbnQCEFfyjOX/17S6RIoSjA6UZ1QwDQYJKoZIhvcNAQEHMAAEg
gEAS7oqxvoz8i6+8zULhDzFpBpOTLU+c2mhBdqXpkLwVfcmWUNA82rEWG57Vl1jZXe7J9BkW9ly4xhU8BbARkZHLEuKqg0saTrTHsMBQ6KMQDotSdU8m8Y2BR5Y100wRjvVx3y5+iNYuy/JmM
gSrNyyMQ/45HfMuVb5B4rwnuP8PAkXNT9VLbPeqAfxsMkYg+vGCDEtd8m+bX/7Xgp/kfwxymOuUCrq/YmSwe9QTG3pBri7Hq1K3zEpX4FH/7W2Zb4o3fBAQ+FuxH4nFjFNoYG29inL0bKEcTX
yNZNKrvhdM3n1Uk/8W2Hr62FQ33HgeFR1yxQjLsUu800PrYcR5tLfyTB8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBBybgM5NUV8BeetUbMR8mJhgFBrVSUsnp9B8RyebmtgU36dZiSObDsI
NtTvlzhk11LIlae/5kjPv95r3lw6DHmV4kXLwiCNlcWPYIWBGIuspwyG+28EWSrHmN7Dt2WqEWqeNQ==" PasswordEncrypted="true"/>
        <PortBinding ContainerPort="80" EndpointRef="Guest1TypeEndpoint"/>
      </ContainerHostPolicies>
      <ServicePackageResourceGovernancePolicy CpuCores="1"/>
      <ResourceGovernancePolicy CodePackageRef="Code" MemoryInMB="1024"  />
    </Policies>
  </ServiceManifestImport>
  <DefaultServices>
    <!-- The section below creates instances of service types, when an instance of this
         application type is created. You can also create one or more instances of service type using the
         ServiceFabric PowerShell module.

         The attribute ServiceTypeName below must match the name defined in the imported ServiceManifest.xml file. -->
    <Service Name="Guest1">
      <StatelessService ServiceTypeName="Guest1Type" InstanceCount="[Guest1_InstanceCount]">
        <SingletonPartition />
      </StatelessService>
    </Service>
  </DefaultServices>
</ApplicationManifest>

Настройка интервала времени до принудительного завершения контейнера

Можно настроить интервал времени для среды выполнения до удаления контейнера после удаления службы (или перехода на другой узел). При настройке интервала времени команда docker stop <time in seconds> отправляется в контейнер. Дополнительные сведения см. в разделе docker stop. Интервал времени ожидания указывается в разделе Hosting . Раздел Hosting можно добавить при создании кластера или позднее при обновлении конфигурации. В следующем фрагменте манифеста кластера показано, как задать интервал ожидания:

"fabricSettings": [
	...,
	{
        "name": "Hosting",
        "parameters": [
          {
                "name": "ContainerDeactivationTimeout",
                "value" : "10"
          },
	      ...
        ]
	}
]

Интервал времени по умолчанию — 10 секунд. Так как эта конфигурация динамическая, обновление конфигурации в кластере обновляет время ожидания.

Настройка среды выполнения для удаления неиспользуемых образов контейнеров

Кластер Service Fabric можно настроить для удаления неиспользуемых образов контейнеров из узла. Эта конфигурация позволяет восстановить место на диске, если на узле присутствует слишком много образов контейнеров. Чтобы включить эту функцию, обновите раздел "Размещение " в манифесте кластера, как показано в следующем фрагменте кода:

"fabricSettings": [
	...,
	{
        "name": "Hosting",
        "parameters": [
          {
                "name": "PruneContainerImages",
                "value": "True"
          },
          {
                "name": "ContainerImagesToSkip",
                "value": "mcr.microsoft.com/windows/servercore|mcr.microsoft.com/windows/nanoserver|mcr.microsoft.com/dotnet/framework/aspnet|..."
          }
          ...
        ]
	} 
]

Для изображений, которые не следует удалять, их можно указать в параметре ContainerImagesToSkip .

Настройка времени загрузки образа контейнера

Среда выполнения Service Fabric выделяет 20 минут для загрузки и извлечения образов контейнеров, что подходит для большинства образов контейнеров. Для больших образов или при медленном подключении к сети может потребоваться увеличить время ожидания, прежде чем прерывать скачивание и извлечение образа. Это время ожидания задается с помощью атрибута ContainerImageDownloadTimeout в разделе "Размещение " манифеста кластера, как показано в следующем фрагменте кода:

"fabricSettings": [
	...,
	{
        "name": "Hosting",
        "parameters": [
          {
              "name": "ContainerImageDownloadTimeout",
              "value": "1200"
          }
          ...
        ]
	}
]

Настройка политики хранения контейнера

Чтобы помочь в диагностике сбоев запуска контейнера, Service Fabric (версия 6.1 или более поздней) поддерживает сохранение контейнеров, которые завершили работу или не удалось запустить. Эту политику можно настроить в файле ApplicationManifest.xml, как показано в следующем фрагменте кода:

 <ContainerHostPolicies CodePackageRef="NodeService.Code" Isolation="process" ContainersRetentionCount="2"  RunInteractive="true"> 

В атрибуте ContainersRetentionCount указывается число контейнеров, которые следует сохранить после сбоя. Если указано отрицательное значение, будут сохраняться все контейнеры после сбоя. Если атрибут ContainerRetentionCount не указан, контейнеры не будут храниться. Атрибут ContainersRetentionCount также поддерживает параметры приложения, поэтому пользователи могут указывать разные значения для тестовых и рабочих кластеров. Чтобы предотвратить перемещение службы контейнеров на другие узлы, при использовании этих функций используйте ограничения на размещение, указав для службы контейнеров конкретный узел. Удаление всех контейнеров, сохраненных с помощью этой функции, выполняется вручную.

Запуск демона Docker с пользовательскими аргументами

Начиная с версии 6.2 среды выполнения Service Fabric и выше, можно запустить демон Docker с пользовательскими аргументами. При указании пользовательских аргументов Service Fabric не передает ни один другой аргумент в подсистему Docker, кроме аргумента --pidfile . Поэтому --pidfile не следует передавать в качестве аргумента. Кроме того, нужно, чтобы аргумент продолжал настраивать демон Docker на прослушивание именованного канала по умолчанию в Windows (или сокета домена UNIX в Linux), чтобы Service Fabric мог взаимодействовать с демоном. Пользовательские аргументы передаются в манифесте кластера в разделе Хостинг в подразделе ПараметрыСлужбыКонтейнеров, как показано в следующем фрагменте кода.

"fabricSettings": [
	...,
	{ 
        "name": "Hosting", 
        "parameters": [ 
          { 
            "name": "ContainerServiceArguments", 
            "value": "-H localhost:1234 -H unix:///var/run/docker.sock" 
          }
          ...
        ] 
	} 
]

Переопределение EntryPoint

В версии 8.2 ServiceFabric Runtime точку входа для пакета кода контейнера и хоста exe можно переопределить. Это можно использовать в случаях, когда все элементы манифеста остаются одинаковыми, но образ контейнера необходимо изменить, а подготовка другой версии типа приложения больше не требуется, или должны быть переданы другие аргументы на основе тестового или производственного сценария, а точка входа остается неизменной.

Ниже приведен пример переопределения точки входа контейнера.

ApplicationManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest ApplicationTypeName="MyFirstContainerType"
                     ApplicationTypeVersion="1.0.0"
                     xmlns="http://schemas.microsoft.com/2011/01/fabric"
                     xmlns:xsd="https://www.w3.org/2001/XMLSchema"
                     xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
  <Parameters>
    <Parameter Name="ImageName" DefaultValue="myregistry.azurecr.io/samples/helloworldapp" />
    <Parameter Name="Commands" DefaultValue="commandsOverride" />
    <Parameter Name="FromSource" DefaultValue="sourceOverride" />
    <Parameter Name="EntryPoint" DefaultValue="entryPointOverride" />
  </Parameters>
  <!-- Import the ServiceManifest from the ServicePackage. The ServiceManifestName and ServiceManifestVersion
       should match the Name and Version attributes of the ServiceManifest element defined in the
       ServiceManifest.xml file. -->
  <ServiceManifestImport>
    <ServiceManifestRef ServiceManifestName="Guest1Pkg" ServiceManifestVersion="1.0.0" />
    <ConfigOverrides />
    <Policies>
      <CodePackagePolicy CodePackageRef="Code">
        <EntryPointOverride>
         <ContainerHostOverride>
            <ImageOverrides>
              <Image Name="[ImageName]" />
            </ImageOverrides>
            <Commands>[Commands]</Commands>
            <FromSource>[Source]</FromSource>
            <EntryPoint>[EntryPoint]</EntryPoint>
          </ContainerHostOverride>
        </EntryPointOverride>
      </CodePackagePolicy>
    </Policies>
  </ServiceManifestImport>
</ApplicationManifest>

ServiceManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="Guest1Pkg"
                 Version="1.0.0"
                 xmlns="http://schemas.microsoft.com/2011/01/fabric"
                 xmlns:xsd="https://www.w3.org/2001/XMLSchema"
                 xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
  <ServiceTypes>
    <!-- This is the name of your ServiceType.
         The UseImplicitHost attribute indicates this is a guest service. -->
    <StatelessServiceType ServiceTypeName="Guest1Type" UseImplicitHost="true" />
  </ServiceTypes>

  <!-- Code package is your service executable. -->
  <CodePackage Name="Code" Version="1.0.0">
    <EntryPoint>
      <!-- Follow this link for more information about deploying Windows containers to Service Fabric: https://aka.ms/sfguestcontainers -->
      <ContainerHost>
        <ImageName>default imagename</ImageName>
        <Commands>default cmd</Commands>
        <EntryPoint>default entrypoint</EntryPoint>
        <FromSource>default source</FromSource>
      </ContainerHost>
    </EntryPoint>
  </CodePackage>

  <ConfigPackage Name="Config" Version="1.0.0" />
</ServiceManifest>

После того как переопределения в манифесте приложения указаны, будет запущен контейнер с именем образа myregistry.azurecr.io/samples/helloworldapp, команда commandsOverride, source sourceOverride и точка входа entryPointOverride.

Аналогичным образом ниже приведен пример переопределения ExeHost:

<?xml version="1.0" encoding="utf-8"?>
<Policies>
  <CodePackagePolicy CodePackageRef="Code">
    <EntryPointOverride>
      <ExeHostOverride>
        <Program>[Program]</Program>
        <Arguments>[Entry]</Arguments>
      </ExeHostOverride>
    </EntryPointOverride>
  </CodePackagePolicy>
</Policies>

Примечание.

Переопределение точки входа не поддерживается для SetupEntryPoint.

Дальнейшие действия