Como criar seu primeiro aplicativo de contêiner do Service Fabric no Windows
Executar um aplicativo existente em um contêiner do Windows em um cluster do Service Fabric não requer alterações no seu aplicativo. Este artigo mostra como criar uma imagem do Docker que contém um aplicativo Web Python Flask e como implantá-lo em um cluster do Azure Service Fabric. Você também compartilhará seu aplicativo em contêineres pelo Registro de Contêiner do Azure. Este artigo pressupõe uma compreensão básica sobre o Docker. Saiba mais sobre o Docker lendo a Visão geral de Docker.
Observação
Este artigo se aplica a um ambiente de desenvolvimento do Windows. O runtime do cluster do Service Fabric e o runtime do Docker devem estar em execução no mesmo sistema operacional. Você não pode executar contêineres do Windows em um cluster do Linux.
Observação
Recomendamos que você use o módulo Az PowerShell do Azure para interagir com o Azure. Para começar, consulte Instalar o Azure PowerShell. Para saber como migrar para o módulo Az PowerShell, confira Migrar o Azure PowerShell do AzureRM para o Az.
Pré-requisitos
Um computador de desenvolvimento executando:
- Visual Studio 2015 ou Visual Studio 2019.
- Ferramentas e SDK do Service Fabric.
- Docker para Windows. Obter Docker CE para o Windows (estável). Depois de instalar e iniciar o Docker, clique no ícone de bandeja e selecione Alternar para contêineres do Windows. Essa etapa é necessária para executar imagens do Docker com base no Windows.
Um cluster do Windows com três ou mais nós em execução no Windows Server com contêineres.
Neste artigo, a versão (build) do Windows Server com contêineres em execução em nós do cluster deve corresponder em seu computador de desenvolvimento. Isso ocorre porque você compila a imagem do docker em seu computador de desenvolvimento e há restrições de compatibilidade entre versões do sistema operacional do contêiner e o sistema operacional do host no qual ele foi implantado. Para obter mais informações, consulte Compatibilidade do sistema operacional do contêiner e do sistema operacional do host do Windows Server.
Para determinar a versão do Windows Server com contêineres que você precisa para seu cluster, execute o comando
ver
em um prompt de comando do Windows no computador de desenvolvimento. Consulte a Compatibilidade entre o sistema operacional do contêiner do Windows Server e o sistema operacional do host antes de criar um cluster.Um registro no Registro de Contêiner do Azure - Crie um registro de contêiner em sua assinatura do Azure.
Observação
A implantação de contêineres em um cluster do Service Fabric em execução no Windows 10 tem suporte. Consulte este artigo para obter informações sobre como configurar o Windows 10 para executar contêineres do Windows.
Observação
O Service Fabric versões 6.2 e posteriores dá suporte para implantação de contêineres em clusters em execução no Windows Server versão 1709.
Defina o contêiner Docker
Crie uma imagem com base na imagem do Python localizada no Hub do Docker.
Especifique o contêiner do Docker em um Dockerfile. O Dockerfile é composto por instruções para configurar o ambiente do seu contêiner, carregar o aplicativo que você deseja executar e mapear portas. O Dockerfile é a entrada para o comando docker build
, que cria a imagem.
Crie um diretório vazio e crie o arquivo Dockerfile (sem extensão de arquivo). Adicione o seguinte ao Dockerfile e salve as alterações:
# 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"]
Leia a referência do Dockerfile para saber mais informações.
Criar um aplicativo Web básico
Crie um aplicativo Web Flask que escuta a porta 80 retornar Hello World!
. No mesmo diretório, crie o arquivo requirements.txt. Adicione o seguinte e salve as alterações:
Flask
Crie também o arquivo app.py e adicione o seguinte snippet:
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)
Fazer logon no Docker e criar a imagem
Em seguida, criaremos a imagem que executa seu aplicativo Web. Ao efetuar pull de imagens públicas do Docker (como python:2.7-windowsservercore
em nosso Dockerfile), a melhor prática é autenticar com sua conta do Docker Hub em vez de fazer uma solicitação de pull anônima.
Observação
Ao fazer solicitações de pull anônimas frequentes, você poderá ver erros de Docker semelhantes a ERROR: toomanyrequests: Too Many Requests.
ou You have reached your pull rate limit.
. Faça a autenticação no Docker Hub para evitar esses erros. Consulte Gerenciar conteúdo público com o Registro de Contêiner do Azure para obter mais informações.
Abra uma janela do PowerShell e acesse o diretório que contém o Dockerfile. Em seguida, execute os comandos a seguir:
docker login
docker build -t helloworldapp .
Esse comando cria a nova imagem usando as instruções no seu Dockerfile de nomeando (marcação -t) a imagem helloworldapp
. Para criar uma imagem de contêiner, primeiro a imagem base é baixada do Hub do Docker ao qual o aplicativo foi adicionado.
Depois de concluir o comando de compilação, execute o comando docker images
para ver informações sobre a nova imagem:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworldapp latest 8ce25f5d6a79 2 minutes ago 10.4 GB
Executar o aplicativo localmente
Verifique a imagem localmente antes de enviá-la ao registro de contêiner.
Execute o aplicativo:
docker run -d --name my-web-site helloworldapp
name fornece um nome para o contêiner em execução (em vez da ID do contêiner).
Depois que o contêiner iniciar, localize seu endereço IP para que você pode se conectar ao seu contêiner em execução em um navegador:
docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" my-web-site
Se esse comando não retorna nada, execute o seguinte comando e inspecione o elemento NetworkSettings->Networks para ver o endereço IP:
docker inspect my-web-site
Conectar-se ao contêiner em execução. Abra um navegador da Web apontando para o endereço IP retornado, por exemplo “http://172.31.194.61"”. Você deve ver o título "Olá, Mundo!" exibido no navegador.
Para interromper o contêiner, execute:
docker stop my-web-site
Exclua o contêiner do seu computador de desenvolvimento:
docker rm my-web-site
Enviar a imagem para o registro de contêiner
Depois de verificar que o contêiner é executado na máquina de desenvolvimento, envie a imagem para seu registro no Registro de Contêiner do Azure.
Execute docker login
para entrar em seu registro de contêiner com as credenciais de registro.
O exemplo a seguir passa a ID e a senha de uma entidade de serviço do Microsoft Entra. Por exemplo, você pode atribuir uma entidade de serviço ao registro para um cenário de automação. Ou, você pode entrar usando o nome de usuário e a senha do registro.
docker login myregistry.azurecr.io -u xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -p myPassword
O comando a seguir cria uma marca ou alias imagem, com um caminho totalmente qualificado para o registro. Este exemplo coloca a imagem no namespace samples
para evitar confusão na raiz do registro.
docker tag helloworldapp myregistry.azurecr.io/samples/helloworldapp
Enviar a imagem para o eu registro de contêiner:
docker push myregistry.azurecr.io/samples/helloworldapp
Crie o serviço em contêineres no Visual Studio
As ferramentas e o SDK do Service Fabric oferecem um modelo de serviço para ajudar você a criar um aplicativo em contêineres.
- Inicie o Visual Studio. Selecione Arquivo>Novo>Projeto.
- Selecione Aplicativo do Service Fabric, nomeie-o como "MyFirstContainer" e clique em OK.
- Selecione Contêiner na lista de modelos de serviço.
- Em Nome da imagem insira "myregistry.azurecr.io/samples/helloworldapp", a imagem é enviada para o seu repositório de contêiner.
- Dê um nome ao seu serviço e clique em OK.
Configurar a comunicação
O serviço em contêineres precisa de um ponto de extremidade para comunicação. Adicione um elemento Endpoint
com o protocolo, a porta e o tipo ao arquivo ServiceManifest.xml. Neste exemplo, uma porta fixa 8081 é usada. Se nenhuma porta for especificada, uma porta aleatória do intervalo de portas de aplicativo é escolhida.
<Resources>
<Endpoints>
<Endpoint Name="Guest1TypeEndpoint" UriScheme="http" Port="8081" Protocol="http"/>
</Endpoints>
</Resources>
Observação
Endpoints adicionais para um serviço podem ser adicionados declarando elementos EndPoint adicionais com valores de propriedade aplicáveis. Cada porta só pode declarar um valor de protocolo.
Definindo um ponto de extremidade, o Service Fabric publica o ponto de extremidade para o Serviço de nomeação. Outros serviços em execução no cluster podem resolver este contêiner. Você também pode executar a comunicação de contêiner para contêiner usando o proxy reverso. A comunicação é realizada fornecendo a porta de escuta de proxy reverso HTTP e o nome dos serviços com os quais você deseja se comunicar como variáveis de ambiente.
O serviço está ouvindo em uma porta específica (8081 neste exemplo). Quando o aplicativo for implantado para um cluster no Azure, o cluster e o aplicativo executam atrás de um balanceador de carga do Azure. A porta do aplicativo deve estar aberta no balanceador de carga do Microsoft Azure para que o tráfego de entrada pode obter por meio para o serviço. Você pode abrir essa porta no balanceador de carga do Microsoft Azure usando um script do PowerShell ou o portal do Azure.
Configurar e definir as variáveis de ambiente
Variáveis de ambiente podem ser especificadas para cada pacote de códigos no manifesto do serviço. Esse recurso está disponível para todos os serviços, independentemente de eles serem implantados como contêineres ou processos ou executáveis convidados. Você pode substituir valores de variáveis de ambiente no manifesto do aplicativo ou especificá-los durante a implantação como parâmetros de aplicativo.
O snippet XML do manifesto do serviço a seguir mostra um exemplo de como especificar variáveis de ambiente para um pacote de códigos:
<CodePackage Name="Code" Version="1.0.0">
...
<EnvironmentVariables>
<EnvironmentVariable Name="HttpGatewayPort" Value=""/>
</EnvironmentVariables>
</CodePackage>
Essas variáveis de ambiente podem ser substituídas no manifesto do aplicativo:
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="Guest1Pkg" ServiceManifestVersion="1.0.0" />
<EnvironmentOverrides CodePackageRef="FrontendService.Code">
<EnvironmentVariable Name="HttpGatewayPort" Value="19080"/>
</EnvironmentOverrides>
...
</ServiceManifestImport>
Configurar mapeamento de porta para host e descoberta de contêiner para contêiner
Configure uma porta de host usada para se comunicar com o contêiner. A associação de porta mapeia a porta na qual o serviço está escutando dentro do contêiner para uma porta no host. Adicionar um elemento PortBinding
no elemento ContainerHostPolicies
do arquivo ApplicationManifest.xml. Para este artigo, ContainerPort
é 80 (o contêiner expõe a porta 80, conforme especificado no Dockerfile) e EndpointRef
é "Guest1TypeEndpoint" (o ponto de extremidade definido anteriormente no manifesto do serviço). As solicitações de entrada para o serviço na porta 8081 são mapeadas para a porta 80 no contêiner.
<ServiceManifestImport>
...
<Policies>
<ContainerHostPolicies CodePackageRef="Code">
<PortBinding ContainerPort="80" EndpointRef="Guest1TypeEndpoint"/>
</ContainerHostPolicies>
</Policies>
...
</ServiceManifestImport>
Observação
PortBindings adicionais para um serviço podem ser adicionados, declarando elementos PortBinding adicionais com valores de propriedade aplicável.
Configurar a autenticação do repositório de contêiner
Consulte Autenticação de repositório de contêiner para saber como configurar diferentes tipos de autenticação para download de imagem de contêiner.
Configurar o modo de isolamento
O Windows dá suporte a dois modos de isolamento para contêineres: processo e Hyper-V. Com o modo de isolamento de processo, todos os contêineres em execução no mesmo computador host compartilham o kernel com o host. Com o modo de isolamento do Hyper-V, os kernels são isolados entre cada contêiner do Hyper-V e o host do contêiner. O modo de isolamento é especificado no elemento ContainerHostPolicies
no arquivo de manifesto do aplicativo. Os modos de isolamento que podem ser especificados são process
, hyperv
e default
. O padrão é o modo de isolamento de processo nos hosts do Windows Server. Em hosts do Windows 10, somente o modo de isolamento do Hyper-V tem suporte, assim o contêiner é executado no modo de isolamento do Hyper-V, independentemente de sua configuração de modo de isolamento. O snippet a seguir mostra como o modo de isolamento é especificado no arquivo de manifesto do aplicativo.
<ContainerHostPolicies CodePackageRef="Code" Isolation="hyperv">
Observação
O modo de isolamento do Hyper-v está disponível nas SKUs do Azure Ev3 e Dv3 que têm suporte para virtualização aninhada.
Configurar governança de recursos
A governança de recursos restringe os recursos que o contêiner pode usar no host. O elemento ResourceGovernancePolicy
, especificado no manifesto do aplicativo, é usado para declarar os limites de recurso para um pacote de códigos de serviço. Os limites de recursos podem ser definidos para os seguintes recursos: Memory, MemorySwap, CpuShares (CPU relative weight), MemoryReservationInMB, BlkioWeight (BlockIO relative weight). Neste exemplo, o pacote de serviço Guest1Pkg obtém um núcleo nos nós de cluster em que ele é colocado. Os limites de memória são absolutos e, portanto, o pacote de códigos é limitado a 1024 MB de memória (e a uma reserva de garantia reversível da mesma). Os pacotes de códigos (contêineres ou processos) não podem alocar mais memória do que esse limite. A tentativa de fazer isso resultará em uma exceção de memória insuficiente. Para que a imposição do limite de recursos funcione, todos os pacotes de códigos em um pacote de serviço devem ter limites de memória especificados.
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="Guest1Pkg" ServiceManifestVersion="1.0.0" />
<Policies>
<ServicePackageResourceGovernancePolicy CpuCores="1"/>
<ResourceGovernancePolicy CodePackageRef="Code" MemoryInMB="1024" />
</Policies>
</ServiceManifestImport>
Configurar o HEALTHCHECK do Docker
Iniciando a versão 6.1, o Service Fabric integra automaticamente os eventos do HEALTHCHECK do Docker em seu relatório de integridade do sistema. Isso significa que, se o contêiner tiver o HEALTHCHECK habilitado, o Service Fabric relatará a integridade sempre que o status de integridade do contêiner for alterado conforme relatado pelo Docker. Um relatório de integridade OK será exibido no Service Fabric Explorer quando o health_status for íntegro e um AVISO aparecerá quando o health_status for não íntegro.
Com a atualização mais recente da v6.4, você tem a opção de especificar que as avaliações de HEALTHCHECK do Docker devem ser relatadas como um erro. Se essa opção estiver habilitada, um relatório de integridade OK será exibido quando health_status for healthy e ERROR será exibido quando health_status for unhealthy.
A instrução do HEALTHCHECK apontando para a verificação real que é executada para monitorar a integridade do contêiner deve estar presente no Dockerfile usado ao gerar a imagem de contêiner.
Você pode configurar o comportamento do HEALTHCHECK para cada contêiner especificando as opções do HealthConfig como parte do ContainerHostPolicies no ApplicationManifest.
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="ContainerServicePkg" ServiceManifestVersion="2.0.0" />
<Policies>
<ContainerHostPolicies CodePackageRef="Code">
<HealthConfig IncludeDockerHealthStatusInSystemHealthReport="true"
RestartContainerOnUnhealthyDockerHealthStatus="false"
TreatContainerUnhealthyStatusAsError="false" />
</ContainerHostPolicies>
</Policies>
</ServiceManifestImport>
Por padrão, IncludeDockerHealthStatusInSystemHealthReport é definido como true, RestartContainerOnUnhealthyDockerHealthStatus é definido como false e TreatContainerUnhealthyStatusAsError é definido como false.
Se o RestartContainerOnUnhealthyDockerHealthStatus for definido como true, um contêiner relatando repetidamente um estado não íntegro será reiniciado (possivelmente em outros nós).
Se TreatContainerUnhealthyStatusAsError for definido como true, os relatórios de integridade com ERROR serão exibidos quando o health_status do contêiner for unhealthy.
Se você deseja desabilitar a integração do HEALTHCHECK para todo o cluster do Service Fabric, precisará definir o EnableDockerHealthCheckIntegration como false.
Como implantar o aplicativo de contêiner
Salve todas as suas alterações e compile o aplicativo. Para publicar o seu aplicativo, clique o botão direito do mouse em MyFirstContainer no Gerenciador de Soluções e selecione Publicar.
Em Ponto de Extremidade de Conexão, insira o ponto de extremidade de gerenciamento para o cluster. Por exemplo, containercluster.westus2.cloudapp.azure.com:19000
. Você pode encontrar o ponto de extremidade de conexão do cliente na guia de Visão geral para o cluster no portal do Azure.
Clique em Publicar.
O Service Fabric Explorer é uma ferramenta baseada na Web para inspecionar e gerenciar aplicativos e nós em um cluster do Service Fabric. Abra um navegador e navegue até http://containercluster.westus2.cloudapp.azure.com:19080/Explorer/
e siga a implantação do aplicativo. O aplicativo é implantado, mas fica em estado de erro até que a imagem seja baixada nos nós de cluster (o que pode levar algum tempo, dependendo do tamanho da imagem):
O aplicativo está pronto quando ele está em Ready
estado:
Abra um navegador e navegue até http://containercluster.westus2.cloudapp.azure.com:8081
. Você deve ver o título "Olá, Mundo!" exibido no navegador.
Limpeza
Você continua a incorrer em encargos enquanto o cluster estiver em execução, considere excluir o cluster.
Depois que você enviar a imagem para o registro de contêiner, você pode excluir a imagem local do seu computador de desenvolvimento:
docker rmi helloworldapp
docker rmi myregistry.azurecr.io/samples/helloworldapp
Compatibilidade do sistema operacional do contêiner e do sistema operacional do host do Windows Server
Os contêineres do Windows Server não são compatíveis em todas as versões de um sistema operacional do host. Por exemplo:
- Os contêineres do Windows Server criados usando o Windows Server versão 1709 não funcionam em um host executando o Windows Server versão 2016.
- Os contêineres do Windows Server são criados usando o Windows Server 2016 no modo de isolamento Hyper-V somente em um host que executa o Windows Server versão 1709.
- Com contêineres do Windows Server criados usando o Windows Server 2016, pode ser necessário garantir que a revisão do sistema operacional do contêiner e sistema operacional do host são as mesmas durante a execução no modo de isolamento do processo em um host executando o Windows Server 2016.
Para obter mais informações, consulte Compatibilidade de versão de contêiner do Windows.
Considere a compatibilidade do sistema operacional do host e do sistema operacional do contêiner ao compilar e implantar contêineres para o cluster do Service Fabric. Por exemplo:
- Verifique se que você implanta os contêineres com um sistema operacional compatível com o sistema operacional nos nós do cluster.
- Certifique-se de que o modo de isolamento especificado para o aplicativo de contêiner é consistente com o suporte para o sistema operacional do contêiner no nó onde ele está sendo implantado.
- Considere como as atualizações do sistema operacional para os nós do cluster ou contêineres podem afetar sua compatibilidade.
Recomendamos as seguintes práticas para certificar-se de que os contêineres são implantados corretamente no cluster do Service Fabric:
- Use a marcação de imagem explícita com as imagens do Docker para especificar a versão do sistema operacional do Windows Server a partir da qual um contêiner é criado.
- Use a marcação do SO em seu arquivo de manifesto do aplicativo para certificar-se de que seu aplicativo é compatível com versões e atualizações diferentes do Windows Server.
Observação
Com o Service Fabric versão 6.2 e posterior, você pode implantar contêineres baseados no Windows Server 2016 localmente em um host do Windows 10. No Windows 10, os contêineres são executados no modo de isolamento do Hyper-V, independentemente do modo de isolamento definido no manifesto do aplicativo. Para obter mais informações, consulte Configurar o modo de isolamento.
Especifique a compilação do sistema operacional das imagens de contêiner específicas
Os contêineres do Windows Server podem não ser compatíveis entre diferentes versões do sistema operacional. Por exemplo, os contêineres do Windows Server criados usando o Windows Server 2016 não funcionam na versão 1709 do Windows Server no modo de isolamento do processo. Portanto, se os nós do cluster forem atualizados para a versão mais recente, os serviços de contêiner criados com versões anteriores do sistema operacional poderão falhar. Para contornar isso com a versão 6.1 do runtime e mais recente, o Service Fabric oferece suporte à especificação de várias imagens do sistema operacional por contêiner e marca-as com as versões de compilação do sistema operacional no manifesto do aplicativo. Você pode obter a versão do sistema operacional executando winver
em um prompt de comando do Windows. Atualize os manifestos do aplicativo e especificar as substituições de imagem por versão do sistema operacional antes de atualizar o sistema operacional nos nós. O snippet de código a seguir mostra como especificar várias imagens de contêiner no manifesto do aplicativo, 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>
A versão de build do Windows Server 2016 é a 14393 e a versão de build da versão 1709 do Windows Server é a 16299. O manifesto do serviço continua a especificar apenas uma imagem por serviço de contêiner, como mostra o seguinte:
<ContainerHost>
<ImageName>myregistry.azurecr.io/samples/helloworldapp</ImageName>
</ContainerHost>
Observação
Os recursos de marcação da versão de compilação do sistema operacional só estão disponíveis para o Service Fabric no Windows
Se o sistema operacional subjacente na VM é a compilação 16299 (versão 1709), o Service Fabric escolherá a imagem do contêiner correspondente a essa versão do Windows Server. Se uma imagem de contêiner sem marcas também for fornecida junto com as imagens de contêiner marcadas no manifesto do aplicativo, o Service Fabric tratará a imagem não marcada como uma que funciona entre versões diferentes. Marque as imagens de contêiner explicitamente para evitar problemas durante as atualizações.
A imagem de contêiner sem marcas funcionará como substituição da fornecida em ServiceManifest. Portanto, a imagem myregistry.azurecr.io/samples/helloworldappDefault"imagem" substituirá ImageName "myregistry.azurecr.io/samples/helloworldapp" no ServiceManifest.
Exemplo completo de manifestos de serviço e aplicativo do Service Fabric
Aqui estão os manifestos de aplicativo e serviço completos usados neste artigo.
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>
Configurar o intervalo de tempo antes do contêiner ser forçado a terminar
Você pode configurar um intervalo de tempo para a execução aguardar antes do contêiner ser removido após a exclusão do serviço (ou um movimento para outro nó) ter iniciado. Configurar o intervalo de tempo envia o comando docker stop <time in seconds>
para o contêiner. Para obter mais detalhes, consulte parar docker. O intervalo de tempo de espera é especificado na seção Hosting
. A seção Hosting
pode ser adicionada na criação do cluster ou posteriormente em uma atualização de configuração. O snippet de manifesto do cluster a seguir mostra como definir o intervalo de espera:
"fabricSettings": [
...,
{
"name": "Hosting",
"parameters": [
{
"name": "ContainerDeactivationTimeout",
"value" : "10"
},
...
]
}
]
O intervalo de tempo padrão é definido para 10 segundos. Como essa configuração é dinâmica, uma configuração somente atualiza no cluster que atualiza no tempo limite.
Configurar a execução para remover as imagens de contêiner não utilizadas
Você pode configurar o cluster do Service Fabric para remover as imagens de contêiner não utilizadas do nó. Essa configuração permite que o espaço em disco seja recapturado se houver imagens de contêiner demais no nó. Para habilitar esse recurso, atualize a seção Hosting no manifesto do cluster, conforme mostrado no seguinte snippet:
"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|..."
}
...
}
]
}
]
Para as imagens que não devem ser excluídas, você pode especificá-las no parâmetro ContainerImagesToSkip
.
Configurar o tempo de download de imagem de contêiner
O runtime do Service Fabric aloca 20 minutos para baixar e extrair as imagens de contêiner, o que funciona para a maioria das imagens de contêiner. Para imagens grandes, ou quando a conexão de rede estiver lenta, talvez seja necessário aumentar o tempo de espera antes de cancelar o download e a extração da imagem. Esse tempo limite é definido usando o atributo ContainerImageDownloadTimeout na seção Hospedagem do manifesto do cluster, conforme mostrado no snippet de código a seguir:
"fabricSettings": [
...,
{
"name": "Hosting",
"parameters": [
{
"name": "ContainerImageDownloadTimeout",
"value": "1200"
}
]
}
]
Definir política de retenção de contêiner
Para ajudar a diagnosticar as falhas de inicialização do contêiner, o Service Fabric (versão 6.1 ou superiores) oferece suporte à retenção de contêineres que encerraram ou falharam na inicialização. Essa política pode ser definida no arquivo ApplicationManifest.xml conforme mostrado no snippet de código a seguir:
<ContainerHostPolicies CodePackageRef="NodeService.Code" Isolation="process" ContainersRetentionCount="2" RunInteractive="true">
A configuração ContainersRetentionCount especifica o número de contêineres mantidos quando ocorre uma falha. Se um valor negativo for especificado, todos os contêineres com falha serão mantidos. Quando o atributo ContainersRetentionCount não for especificado, nenhum contêiner será retido. O atributo ContainersRetentionCount também oferece suporte a Parâmetros de Aplicativo para que os usuários possam especificar valores diferentes para clusters de teste e produção. Use restrições de posicionamento para direcionar o serviço de contêiner para um determinado nó quando esses recursos forem usados com a finalidade de impedir que o serviço de contêiner se mova para outros nós. Todos os contêineres retidos usando esse recurso devem ser removidos manualmente.
Iniciar o daemon do Docker com argumentos personalizados
Com a versão 6.2, e superiores, do runtime do Service Fabric, você pode iniciar o daemon do Docker com argumentos personalizados. Ao especificar argumentos personalizados, o Service Fabric não passa outro argumento para o mecanismo do docker, com exceção do argumento --pidfile
. Portanto, não passe --pidfile
como um argumento. Além disso, o argumento deve manter a escuta do daemon do docker no pipe de nome padrão no Windows (ou um soquete de domínio do unix no Linux) para o Service Fabric se comunicar com o Daemon. Os argumentos personalizados são passados no manifesto do cluster na seção Hospedagem em ContainerServiceArguments conforme mostrado no snippet de código a seguir:
"fabricSettings": [
...,
{
"name": "Hosting",
"parameters": [
{
"name": "ContainerServiceArguments",
"value": "-H localhost:1234 -H unix:///var/run/docker.sock"
}
]
}
]
Substituição de EntryPoint
Com a versão 8.2 do ServiceFabric Runtime, o ponto de entrada para o contêiner e o pacote de código do host exe podem ser substituídos. Isso pode ser usado nos casos em que todos os elementos de manifesto permanecem os mesmos, mas a imagem de contêiner precisa ser alterada e, em seguida, o provisionamento de uma versão de tipo de aplicativo diferente não é mais necessário ou argumentos diferentes precisam ser passados com base no cenário de teste ou de produção e o ponto de entrada permanece o mesmo.
Veja o seguinte exemplo de como substituir o ponto de entrada do contêiner:
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>
Depois que as substituições no manifesto do aplicativo são especificadas, o contêiner com o nome de imagem myregistry.azurecr.io/samples/helloworldapp, comando commandsOverride, fonte sourceOverride e ponto de entrada entryPointOverride será iniciado.
Da mesma forma, abaixo está um exemplo de como substituir o ExeHost:
<?xml version="1.0" encoding="utf-8"?>
<Policies>
<CodePackagePolicy CodePackageRef="Code">
<EntryPointOverride>
<ExeHostOverride>
<Program>[Program]</Program>
<Arguments>[Entry]</Arguments>
</ExeHostOverride>
</EntryPointOverride>
</CodePackagePolicy>
</Policies>
Observação
Não há suporte para a substituição do ponto de entrada no SetupEntryPoint.
Próximas etapas
- Saiba mais sobre como executar contêineres no Service Fabric.
- Leia o tutorial Como implantar um aplicativo .NET em um contêiner.
- Leia mais sobre o ciclo de vida do aplicativo do Service Fabric.
- Confira os exemplos de código do Service Fabric no GitHub.