Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
A execução de um aplicativo existente em um contêiner Linux em um cluster do Service Fabric não requer nenhuma alteração no seu aplicativo. Este artigo orienta você na criação de uma imagem do Docker contendo um aplicativo Web Python Flask e na implantação em um cluster do Service Fabric. Você também compartilhará seu aplicativo em contêiner por meio do Registro de Contêiner do Azure. Este artigo pressupõe uma compreensão básica do Docker. Você pode aprender sobre o Docker lendo a Visão geral do Docker.
Observação
Este artigo aplica-se a um ambiente de desenvolvimento Linux. O tempo de execução do cluster do Service Fabric e o tempo de execução do Docker devem estar em execução no mesmo sistema operacional. Não é possível executar contêineres Linux em um cluster do Windows.
Pré-requisitos
Um computador de desenvolvimento executando:
Um cluster Linux com três ou mais nós.
Um registro no Registro de Contêiner do Azure - Crie um registro de contêiner em sua assinatura do Azure.
Definir o contêiner do Docker
Crie uma imagem com base na imagem Python localizada no Docker Hub.
Especifique seu contêiner do Docker em um Dockerfile. O Dockerfile consiste em instruções para configurar o ambiente dentro do contêiner, carregar o aplicativo que você deseja executar e mapear portas. O Dockerfile é a entrada para o docker build comando, 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 suas alterações:
# Use an official Python runtime as a base image
FROM python:2.7-slim
# 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 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 obter mais informações.
Criar um aplicativo Web básico
Crie uma aplicação web Flask escutando na porta 80 que retorna "Hello World!". No mesmo diretório, crie o arquivo requirements.txt. Adicione o seguinte e salve suas alterações:
Flask
Crie também o arquivo app.py e adicione o seguinte trecho:
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)
Faça login no Docker e construa a imagem
Em seguida, criaremos a imagem que executa seu aplicativo Web. Ao extrair imagens públicas do Docker (como python:2.7-slim no nosso Dockerfile), é uma prática recomendada autenticar com a sua conta do Docker Hub em vez de fazer um pull request anónimo.
Observação
Ao fazer solicitações pull anónimas frequentes, poderá ver erros do Docker semelhantes a ERROR: toomanyrequests: Too Many Requests. ou You have reached your pull rate limit.. Autentique-se 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 navegue até o diretório que contém o Dockerfile. Em seguida, execute os seguintes comandos:
docker login
docker build -t helloworldapp .
Este comando cria a nova imagem usando as instruções em seu Dockerfile, nomeando (-t marcando) a imagem helloworldapp. Para criar uma imagem de contêiner, a imagem base é baixada primeiro do Docker Hub ao qual o aplicativo é adicionado.
Quando o comando build for concluído, execute o docker images comando para ver as informações na nova imagem:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworldapp latest 86838648aab6 2 minutes ago 194 MB
Execute o aplicativo localmente
Verifique se a sua aplicação contentorizada é executada localmente antes de enviá-la para o registo do repositório de contentores.
Execute o aplicativo, mapeando a porta 4000 do computador para a porta 80 exposta do contêiner:
docker run -d -p 4000:80 --name my-web-site helloworldapp
name dá um nome ao contêiner em execução (em vez do ID do contêiner).
Conecte-se ao contêiner em execução. Abra um navegador da Web apontando para o endereço IP retornado na porta 4000, por exemplo "http://localhost:4000". Você deve ver o título "Olá Mundo!" exibido no navegador.
Para parar o contêiner, execute:
docker stop my-web-site
Exclua o contêiner da máquina de desenvolvimento:
docker rm my-web-site
Envie a imagem para o repositório do contêiner
Depois de verificar se o aplicativo é executado no Docker, envie a imagem por push para seu registro no Registro de Contêiner do Azure.
Execute docker login para entrar no seu registro de contêiner com suas credenciais de registro.
O exemplo a seguir passa o identificador e a senha de uma entidade de serviço do Microsoft Entra. Por exemplo, poderá ter atribuído um principal de serviço no seu registo para um cenário de automação. Ou, você pode entrar usando seu nome de usuário e senha do registro.
docker login myregistry.azurecr.io -u xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -p myPassword
O comando a seguir cria uma tag, ou alias, da imagem, com um caminho totalmente qualificado para o seu registro. Este exemplo coloca a imagem no namespace samples para evitar confusão na raiz do registo.
docker tag helloworldapp myregistry.azurecr.io/samples/helloworldapp
Envie a imagem para o seu registo de contentores.
docker push myregistry.azurecr.io/samples/helloworldapp
Empacotar a imagem do Docker com Yeoman
O SDK do Service Fabric para Linux inclui um gerador Yeoman que facilita a criação de seu aplicativo e a adição de uma imagem de contêiner. Vamos usar o Yeoman para criar um aplicativo com um único contêiner do Docker chamado SimpleContainerApp.
Para criar um aplicativo de contêiner do Service Fabric, abra uma janela de terminal e execute yo azuresfcontainero .
Nomeie seu aplicativo (por exemplo, mycontainer) e nomeie o serviço de aplicativo (por exemplo, myservice).
Para o nome da imagem, forneça a URL para a imagem de contêiner em um registro de contêiner (por exemplo, "myregistry.azurecr.io/samples/helloworldapp").
Como essa imagem tem um ponto de entrada de carga de trabalho definido, você não precisa especificar explicitamente os comandos de entrada (comandos executados dentro do contêiner, o que manterá o contêiner em execução após a inicialização).
Especifique uma contagem de instâncias de "1".
Especifique o mapeamento de porta no formato apropriado. Para este artigo, você precisa fornecer 80:4000 como o mapeamento de porta. Ao fazer isso, você configurou que todas as solicitações de entrada que chegam à porta 4000 na máquina host são redirecionadas para a porta 80 no contêiner.
Configurar autenticação de repositório de contêiner
Consulte Autenticação de repositório de contêinerpara saber como configurar diferentes tipos de autenticação para download de imagens de contêiner.
Configurar o modo de isolamento
Com a versão de tempo de execução 6.3, o isolamento de VM é suportado para contêineres Linux, suportando assim dois modos de isolamento para contêineres: processo e Hyper-V. Com o modo de isolamento Hyper-V, os kernels são isolados entre cada contêiner e o host do contêiner. O isolamento Hyper-V é implementado usando Clear Containers. O modo de isolamento é especificado para clusters Linux no ServicePackageContainerPolicy elemento no arquivo de manifesto do aplicativo. Os modos de isolamento que podem ser especificados são process, hyperve default. O padrão é o modo de isolamento do processo. O trecho a seguir mostra como o modo de isolamento é especificado no arquivo de manifesto do aplicativo.
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MyServicePkg" ServiceManifestVersion="1.0.0"/>
<Policies>
<ServicePackageContainerPolicy Hostname="votefront" Isolation="hyperv">
<PortBinding ContainerPort="80" EndpointRef="myServiceTypeEndpoint"/>
</ServicePackageContainerPolicy>
</Policies>
</ServiceManifestImport>
Configurar a governança de recursos
A governança de recursos restringe os recursos que o contêiner pode usar no host. O ResourceGovernancePolicy elemento , que é especificado no manifesto do aplicativo, é usado para declarar limites de recursos para um pacote de código de serviço. Os limites de recursos podem ser definidos para os seguintes recursos: Memory, MemorySwap, CpuShares (peso relativo da CPU), MemoryReservationInMB, BlkioWeight (peso relativo do BlockIO). Neste exemplo, o pacote de serviço chamado Guest1Pkg recebe um núcleo nos nós do cluster onde é colocado. Os limites de memória são absolutos, por isso o pacote de código é limitado a 1024 MB de memória (e uma reserva segura do mesmo). Os pacotes de código (contêineres ou processos) não são capazes de alocar mais memória do que esse limite, e tentar fazer isso resulta em uma exceção de falta de memória. Para que a imposição do limite de recursos funcione, todos os pacotes de código dentro de um pacote de serviço devem ter limites de memória especificados.
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MyServicePKg" ServiceManifestVersion="1.0.0" />
<Policies>
<ServicePackageResourceGovernancePolicy CpuCores="1"/>
<ResourceGovernancePolicy CodePackageRef="Code" MemoryInMB="1024" />
</Policies>
</ServiceManifestImport>
Configurar o HEALTHCHECK do Docker
A partir da v6.1, o Service Fabric integra automaticamente os eventos HEALTHCHECK do docker ao seu relatório de integridade do sistema. Isso significa que, se o contentor tiver HEALTHCHECK habilitado, o Service Fabric relatará o estado de saúde sempre que o estado de saúde do contentor for alterado, conforme relatado pelo Docker. Um relatório OK de integridade aparecerá no Service Fabric Explorer quando o health_status estiver saudável e um AVISO aparecerá quando o health_status estiver não saudável.
A partir da última versão de atualização v6.4, terás a opção de especificar que as avaliações HEALTHCHECK do docker devem ser reportadas como um erro. Se essa opção estiver ativada, um relatório de integridade OK aparecerá quando health_status estiver íntegro e ERROR aparecerá quando health_status não estiver íntegro.
A instrução HEALTHCHECK que aponta para a verificação real executada para monitorar a integridade do contêiner deve estar presente no Dockerfile usado durante a geração da imagem do contêiner.
Você pode configurar o comportamento HEALTHCHECK para cada contêiner especificando opções HealthConfig como parte de ContainerHostPolicies em 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 está definido como true, RestartContainerOnUnhealthyDockerHealthStatus está definido como false e TreatContainerUnhealthyStatusAsError está definido como false.
Se RestartContainerOnUnhealthyDockerHealthStatus estiver definido como true, um contentor que se reporte repetidamente como não íntegro será reiniciado (possivelmente noutros nós).
Se TreatContainerUnhealthyStatusAsError estiver definido como true, os relatórios de integridade ERROR aparecerão quando o health_status do contêiner não estiver íntegro.
Se desejar desabilitar a integração HEALTHCHECK para todo o cluster do Service Fabric, será necessário definir EnableDockerHealthCheckIntegration como false.
Implantar o aplicativo
Depois que o aplicativo for criado, você poderá implantá-lo no cluster local usando a CLI do Service Fabric.
Ligue ao cluster do Service Fabric local.
sfctl cluster select --endpoint http://localhost:19080
Use o script de instalação fornecido nos modelos em https://github.com/Azure-Samples/service-fabric-containers/ para copiar o pacote do aplicativo para o armazenamento de imagens do cluster, registrar o tipo de aplicativo e criar uma instância do aplicativo.
./install.sh
Abra um navegador e navegue até Service Fabric Explorer em http://localhost:19080/Explorer (substitua localhost pelo IP privado da VM se estiver usando o Vagrant no Mac OS X). Expanda o nó Aplicativos e observe que agora há uma entrada para o tipo de aplicativo e outra para a primeira instância desse tipo.
Conecte-se ao contêiner em execução. Abra um navegador da Web apontando para o endereço IP retornado na porta 4000, por exemplo "http://localhost:4000". Você deve ver o título "Olá Mundo!" exibido no navegador.
Limpeza
Use o script de desinstalação fornecido no modelo para excluir a instância do aplicativo do cluster de desenvolvimento local e cancelar o registro do tipo de aplicativo.
./uninstall.sh
Depois de enviar a imagem para o registro do contêiner, você pode excluir a imagem local do computador de desenvolvimento:
docker rmi helloworldapp
docker rmi myregistry.azurecr.io/samples/helloworldapp
Exemplo completo de aplicação e manifestos de serviço do Service Fabric
Aqui estão os manifestos completos de serviço e aplicativo usados neste artigo.
ServiceManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="myservicePkg"
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="myserviceType" 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 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="VariableName" Value="VariableValue"/>
-->
</EnvironmentVariables>
</CodePackage>
<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="myServiceTypeEndpoint" UriScheme="http" Port="4000" Protocol="http"/>
</Endpoints>
</Resources>
</ServiceManifest>
ApplicationManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest ApplicationTypeName="mycontainerType"
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">
<!-- 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="myservicePkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides />
<Policies>
<ContainerHostPolicies CodePackageRef="Code">
<RepositoryCredentials AccountName="myregistry" Password="=P==/==/=8=/=+u4lyOB=+=nWzEeRfF=" PasswordEncrypted="false"/>
<PortBinding ContainerPort="80" EndpointRef="myServiceTypeEndpoint"/>
</ContainerHostPolicies>
</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="myservice">
<!-- On a local development cluster, set InstanceCount to 1. On a multi-node production
cluster, set InstanceCount to -1 for the container service to run on every node in
the cluster.
-->
<StatelessService ServiceTypeName="myserviceType" InstanceCount="1">
<SingletonPartition />
</StatelessService>
</Service>
</DefaultServices>
</ApplicationManifest>
Adicionar mais serviços a uma aplicação existente
Para adicionar outro serviço de contêiner a um aplicativo já criado usando yeoman, execute as seguintes etapas:
- Altere o diretório para a raiz da aplicação existente. Por exemplo,
cd ~/YeomanSamples/MyApplication, seMyApplicationé a aplicação criada por Yeoman. - Executar
yo azuresfcontainer:AddService
Configurar intervalo de tempo antes que o contêiner seja encerrado à força
Você pode configurar um intervalo de tempo para o tempo de execução aguardar antes que o contêiner seja removido após o início da exclusão do serviço (ou uma mudança para outro nó). A configuração do intervalo de tempo envia o docker stop <time in seconds> comando para o contêiner. Para obter mais detalhes, consulte Docker stop. O intervalo de tempo a aguardar é especificado na Hosting secção . O seguinte trecho de manifesto de cluster mostra como definir o intervalo de espera:
{
"name": "Hosting",
"parameters": [
{
"name": "ContainerDeactivationTimeout",
"value" : "10"
},
...
]
}
O intervalo de tempo padrão é definido como 10 segundos. Como essa configuração é dinâmica, uma atualização somente de configuração no cluster atualiza o tempo limite.
Configurar o tempo de execução para remover imagens de contêiner não utilizadas
Pode ajustar as configurações do cluster do Azure Service Fabric para remover imagens de contentores não utilizadas do nó. Essa configuração permite que o espaço em disco seja recapturado se muitas imagens de contêiner estiverem presentes no nó. Para habilitar esse recurso, atualize a Hosting seção no manifesto do cluster conforme mostrado no seguinte trecho:
{
"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 imagens que não devem ser excluídas, você pode especificá-las sob o ContainerImagesToSkip parâmetro.
Configurar o tempo de download da imagem do contêiner
O tempo de execução do Service Fabric aloca 20 minutos para baixar e extrair 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 é lenta, pode ser necessário aumentar o tempo de espera antes de abortar 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 seguinte trecho:
{
"name": "Hosting",
"parameters": [
{
"name": "ContainerImageDownloadTimeout",
"value": "1200"
}
]
}
Definir a política de retenção de contentores
Para ajudar a diagnosticar falhas no arranque de contentores, o Service Fabric (versão 6.1 ou superior) suporta a retenção de contentores que terminaram ou cujo arranque falhou. Esta política pode ser definida no ficheiro ApplicationManifest.xml, conforme mostrado no fragmento seguinte:
<ContainerHostPolicies CodePackageRef="NodeService.Code" Isolation="process" ContainersRetentionCount="2" RunInteractive="true">
A definição ContainersRetentionCount especifica o número de contentores que vão ser retidos quando falham. Se for especificado um valor negativo, todos os contentores com falhas serão mantidos. Se o atributo ContainersRetentionCount não for especificado, não serão retidos contentores. O atributo ContainersRetentionCount também suporta Parâmetros de Aplicação, para que os utilizadores possam especificar valores diferentes para clusters de teste e produção. Utilize restrições de posicionamento para segmentar o serviço de contentores para um nó particular ao utilizar esta funcionalidade para impedir a passagem do serviço de contentores para outros nós. Quaisquer contentores retidos por esta funcionalidade têm de ser removidos manualmente.
Inicie o daemon do Docker com argumentos personalizados
Com a versão 6.2 do tempo de execução do Service Fabric e superior, você pode iniciar o daemon do Docker com argumentos personalizados. Quando os argumentos personalizados são especificados, o Service Fabric não passa nenhum outro argumento para o mecanismo do docker, exceto o --pidfile argumento. Por isso, --pidfile não deve ser passado como argumento. Além disso, o argumento deve continuar a fazer com que o daemon docker ouça no pipe de nome padrão no Windows (ou soquete de domínio unix no Linux) para que o Service Fabric se comunique com o daemon. Os argumentos personalizados são especificados no manifesto do cluster na seção Hospedagem em ContainerServiceArguments. Um exemplo é mostrado no seguinte trecho:
{
"name": "Hosting",
"parameters": [
{
"name": "ContainerServiceArguments",
"value": "-H localhost:1234 -H unix:///var/run/docker.sock"
}
]
}
Próximos passos
- Saiba mais sobre como executar contêineres no Service Fabric.
- Leia o tutorial Implantar um aplicativo .NET em um contêiner .
- Saiba mais sobre o ciclo de vida do aplicativo Service Fabric.
- Consulte os exemplos de código de contentor do Service Fabric no GitHub.