Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Dica
Mesmo se estiver familiarizado com o Docker ou Orleans, ler este artigo até o final é recomendável para evitar possíveis problemas com soluções alternativas conhecidas.
Este artigo e seu exemplo são um trabalho em andamento. Comentários, PRs ou sugestões são bem-vindos.
Implantar soluções do Orleans no Docker
A implantação de Orleans no Docker pode ser complicada devido ao design de orquestradores do Docker e pilhas de agrupamento. A parte mais complicada é entender o conceito de Rede de Sobreposição do Docker Swarm e do modelo de rede do Kubernetes.
Os contêineres do Docker e os modelos de rede foram projetados principalmente para executar contêineres sem estado e imutáveis. Iniciar um cluster que executa aplicativos Node.js ou Nginx é relativamente fácil. No entanto, usar algo mais elaborado, como um aplicativo verdadeiramente clusterizado ou distribuído (como um baseado em Orleans), pode apresentar dificuldades de instalação. É possível, mas não tão simples quanto implantar aplicativos baseados na Web.
O clustering do Docker envolve o agrupamento de vários hosts para funcionar como um único pool de recursos, gerenciado usando um Orquestrador de Contêineres. Docker Inc. fornece Swarm como sua opção, enquanto o Google oferece Kubernetes (também conhecido como K8s). Existem outros orquestradores como DC/OS e Mesos , mas este documento se concentra em Swarm e K8s, pois eles são mais amplamente usados.
As mesmas interfaces e implementações de grains que funcionam em qualquer lugar Orleans também funcionam em contêineres do Docker. Não são necessárias considerações especiais para executar um Orleans aplicativo em contêineres do Docker.
Os conceitos discutidos aqui se aplicam às versões do .NET Core e do .NET Framework 4.6.1.Orleans No entanto, para ilustrar a natureza multiplataforma do Docker e do .NET Core, há ênfase nos exemplos que utilizam o .NET Core. Detalhes específicos da plataforma (Windows/Linux/macOS) podem ser fornecidos quando necessário.
Pré-requisitos
Este artigo pressupõe que os seguintes pré-requisitos estão instalados:
- Docker: O Docker4X tem um instalador fácil de usar para as principais plataformas com suporte. Ele contém o mecanismo do Docker e o Docker Swarm.
- Kubernetes (K8s): oferta de orquestração de contêineres do Google. Ele inclui diretrizes para instalar o Minikube (uma implantação local do K8s) e o kubectl junto com as dependências.
- .NET: versão multiplataforma do .NET.
- Visual Studio Code (VSCode): qualquer IDE preferencial pode ser usado. O VSCode é usado aqui porque é multiplataforma, garantindo que os exemplos funcionem em todas as plataformas. Depois de instalar o VSCode, instale a extensão C#.
Importante
A instalação do Kubernetes não será necessária se não a estiver usando. O instalador do Docker4X já inclui o Swarm, portanto, nenhuma instalação extra é necessária para o Swarm.
Observação
No Windows, o instalador do Docker habilita Hyper-V durante a instalação. Como este artigo e seus exemplos usam o .NET Core, as imagens de contêiner usadas são baseadas no NanoServer do Windows Server. Se estiver planejando usar o .NET Framework 4.6.1 em vez disso, use imagens baseadas no Windows Server Core e Orleans na versão 1.4+ (que dá suporte apenas ao .NET Framework).
Criar uma Orleans solução
As instruções a seguir mostram como criar uma solução padrão Orleans usando as dotnet
ferramentas.
Adapte os comandos conforme apropriado para a plataforma. A estrutura do diretório é apenas uma sugestão; adaptá-lo conforme necessário.
mkdir Orleans-Docker
cd Orleans-Docker
dotnet new sln
mkdir -p src/OrleansSilo
mkdir -p src/OrleansClient
mkdir -p src/OrleansGrains
mkdir -p src/OrleansGrainInterfaces
dotnet new console -o src/OrleansSilo --framework netcoreapp1.1
dotnet new console -o src/OrleansClient --framework netcoreapp1.1
dotnet new classlib -o src/OrleansGrains --framework netstandard1.5
dotnet new classlib -o src/OrleansGrainInterfaces --framework netstandard1.5
dotnet sln add src/OrleansSilo/OrleansSilo.csproj
dotnet sln add src/OrleansClient/OrleansClient.csproj
dotnet sln add src/OrleansGrains/OrleansGrains.csproj
dotnet sln add src/OrleansGrainInterfaces/OrleansGrainInterfaces.csproj
dotnet add src/OrleansClient/OrleansClient.csproj reference src/OrleansGrainInterfaces/OrleansGrainInterfaces.csproj
dotnet add src/OrleansSilo/OrleansSilo.csproj reference src/OrleansGrainInterfaces/OrleansGrainInterfaces.csproj
dotnet add src/OrleansGrains/OrleansGrains.csproj reference src/OrleansGrainInterfaces/OrleansGrainInterfaces.csproj
dotnet add src/OrleansSilo/OrleansSilo.csproj reference src/OrleansGrains/OrleansGrains.csproj
Até agora, apenas o código padrão para a estrutura da solução e dos projetos foi criado, e as referências foram adicionadas entre eles. Isso não é diferente da configuração de um projeto regular Orleans .
No momento em que este artigo foi escrito, Orleans o 2.0 (que dá suporte ao .NET Core e ao desenvolvimento multiplataforma) estava no Technology Preview. Seus pacotes NuGet foram hospedados em um feed do MyGet, não no feed de NuGet.org oficial. Para instalar os pacotes NuGet de visualização, use a dotnet
CLI, especificando o feed de origem e a versão a partir do MyGet:
dotnet add src/OrleansClient/OrleansClient.csproj package Microsoft.Orleans.Core -s https://dotnet.myget.org/F/orleans-prerelease/api/v3/index.json -v 2.0.0-preview2-201705020000
dotnet add src/OrleansGrainInterfaces/OrleansGrainInterfaces.csproj package Microsoft.Orleans.Core -s https://dotnet.myget.org/F/orleans-prerelease/api/v3/index.json -v 2.0.0-preview2-201705020000
dotnet add src/OrleansGrains/OrleansGrains.csproj package Microsoft.Orleans.Core -s https://dotnet.myget.org/F/orleans-prerelease/api/v3/index.json -v 2.0.0-preview2-201705020000
dotnet add src/OrleansSilo/OrleansSilo.csproj package Microsoft.Orleans.Core -s https://dotnet.myget.org/F/orleans-prerelease/api/v3/index.json -v 2.0.0-preview2-201705020000
dotnet add src/OrleansSilo/OrleansSilo.csproj package Microsoft.Orleans.OrleansRuntime -s https://dotnet.myget.org/F/orleans-prerelease/api/v3/index.json -v 2.0.0-preview2-201705020000
dotnet restore
Ok, todas as dependências básicas para executar um aplicativo simples Orleans agora estão prontas. Observe que nada mudou de uma configuração regular Orleans de aplicativo até este ponto. Agora, vamos adicionar algum código para torná-lo funcional.
Implementar o Orleans aplicativo
Supondo que o VSCode seja usado, execute code .
no diretório da solução. Esse comando abre o diretório no VSCode e carrega a solução.
Essa é a estrutura de solução criada anteriormente.
Program.cs, OrleansHostWrapper.cs, IGreetingGrain.cs e arquivos GreetingGrain.cs também foram adicionados às interfaces e projetos de granulação, respectivamente. Este é o código para esses arquivos:
IGreetingGrain.cs:
using System;
using System.Threading.Tasks;
using Orleans;
namespace OrleansGrainInterfaces
{
public interface IGreetingGrain : IGrainWithGuidKey
{
Task<string> SayHello(string name);
}
}
GreetingGrain.cs:
using System;
using System.Threading.Tasks;
using OrleansGrainInterfaces;
namespace OrleansGrains
{
public class GreetingGrain : Grain, IGreetingGrain
{
public Task<string> SayHello(string name)
{
return Task.FromResult($"Hello from Orleans, {name}");
}
}
}
OrleansHostWrapper.cs:
using System;
using System.NET;
using Orleans.Runtime;
using Orleans.Runtime.Configuration;
using Orleans.Runtime.Host;
namespace OrleansSilo;
public class OrleansHostWrapper
{
private readonly SiloHost _siloHost;
public OrleansHostWrapper(ClusterConfiguration config)
{
_siloHost = new SiloHost(Dns.GetHostName(), config);
_siloHost.LoadOrleansConfig();
}
public int Run()
{
if (_siloHost is null)
{
return 1;
}
try
{
_siloHost.InitializeOrleansSilo();
if (_siloHost.StartOrleansSilo())
{
Console.WriteLine(
$"Successfully started Orleans silo '{_siloHost.Name}' as a {_siloHost.Type} node.");
return 0;
}
else
{
throw new OrleansException(
$"Failed to start Orleans silo '{_siloHost.Name}' as a {_siloHost.Type} node.");
}
}
catch (Exception exc)
{
_siloHost.ReportStartupError(exc);
Console.Error.WriteLine(exc);
return 1;
}
}
public int Stop()
{
if (_siloHost is not null)
{
try
{
_siloHost.StopOrleansSilo();
_siloHost.Dispose();
Console.WriteLine($"Orleans silo '{_siloHost.Name}' shutdown.");
}
catch (Exception exc)
{
siloHost.ReportStartupError(exc);
Console.Error.WriteLine(exc);
return 1;
}
}
return 0;
}
}
Program.cs (Silo):
using System;
using System.Collections.Generic;
using System.Linq;
using System.NET;
using System.Threading.Tasks;
using Orleans.Runtime.Configuration;
namespace OrleansSilo
{
public class Program
{
private static OrleansHostWrapper s_hostWrapper;
static async Task<int> Main(string[] args)
{
int exitCode = await InitializeOrleansAsync();
Console.WriteLine("Press Enter to terminate...");
Console.ReadLine();
exitCode += ShutdownSilo();
return exitCode;
}
private static int InitializeOrleansAsync()
{
var config = new ClusterConfiguration();
config.Globals.DataConnectionString =
"[AZURE STORAGE CONNECTION STRING HERE]";
config.Globals.DeploymentId = "Orleans-Docker";
config.Globals.LivenessType =
GlobalConfiguration.LivenessProviderType.AzureTable;
config.Globals.ReminderServiceType =
GlobalConfiguration.ReminderServiceProviderType.AzureTable;
config.Defaults.PropagateActivityId = true;
config.Defaults.ProxyGatewayEndpoint =
new IPEndPoint(IPAddress.Any, 10400);
config.Defaults.Port = 10300;
var ips = await Dns.GetHostAddressesAsync(Dns.GetHostName());
config.Defaults.HostNameOrIPAddress =
ips.FirstOrDefault()?.ToString();
s_hostWrapper = new OrleansHostWrapper(config);
return hostWrapper.Run();
}
static int ShutdownSilo() =>
s_hostWrapper?.Stop() ?? 0;
}
}
Program.cs (cliente):
using System;
using System.NET;
using System.Threading;
using System.Threading.Tasks;
using Orleans;
using Orleans.Runtime.Configuration;
using OrleansGrainInterfaces;
namespace OrleansClient
{
class Program
{
private static IClusterClient s_client;
private static bool s_running;
static async Task Main(string[] args)
{
await InitializeOrleansAsync();
Console.ReadLine();
s_running = false;
}
static async Task InitializeOrleansAsync()
{
var config = new ClientConfiguration
{
DeploymentId = "Orleans-Docker";
PropagateActivityId = true;
};
var hostEntry =
await Dns.GetHostEntryAsync("orleans-silo");
var ip = hostEntry.AddressList[0];
config.Gateways.Add(new IPEndPoint(ip, 10400));
Console.WriteLine("Initializing...");
using client = new ClientBuilder().UseConfiguration(config).Build();
await client.Connect();
s_running = true;
Console.WriteLine("Initialized!");
var grain = client.GetGrain<IGreetingGrain>(Guid.Empty);
while (s_running)
{
var response = await grain.SayHello("Gutemberg");
Console.WriteLine($"[{DateTime.UtcNow}] - {response}");
await Task.Delay(1000);
}
}
}
}
Os detalhes da implementação de grãos não são abordados aqui, pois estão fora do escopo deste artigo. Consulte outros documentos relevantes para obter mais informações. Esses arquivos representam um aplicativo mínimo Orleans , servindo como ponto de partida para o restante deste artigo.
Este artigo usa o OrleansAzureUtils
provedor de associação, mas qualquer outro Orleansprovedor com suporte pode ser usado.
O Dockerfile
O Docker usa imagens para criar contêineres. Para obter mais detalhes sobre como criar imagens personalizadas, verifique a documentação do Docker. Este artigo usa imagens oficiais da Microsoft. Com base nas plataformas de destino e desenvolvimento, escolha a imagem apropriada.
microsoft/dotnet:1.1.2-sdk
, uma imagem baseada em Linux, é usada aqui. Para o Windows, microsoft/dotnet:1.1.2-sdk-nanoserver
pode ser usado, por exemplo. Escolha aquele que atenda às necessidades.
Observação para usuários do Windows: conforme mencionado anteriormente, para manter a compatibilidade entre plataformas, o .NET Core e Orleans o Technical Preview 2.0 são usados neste artigo. Para usar o Docker no Windows com a versão 1.4+ totalmente lançada Orleans, use imagens do Windows Server Core, já que as imagens do NanoServer e do Linux dão suporte apenas ao .NET Core.
Dockerfile.debug:
FROM microsoft/dotnet:1.1.2-sdk
ENV NUGET_XMLDOC_MODE skip
WORKDIR /vsdbg
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
unzip \
&& rm -rf /var/lib/apt/lists/* \
&& curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -v latest -l /vsdbg
WORKDIR /app
ENTRYPOINT ["tail", "-f", "/dev/null"]
Esse Dockerfile essencialmente faz o download e instala o depurador VSdbg, inicia um contêiner vazio e mantém-no ativo indefinidamente, para que ele não precise ser interrompido e iniciado repetidamente durante a depuração.
Agora, para produção, a imagem é menor porque contém apenas o runtime do .NET Core, não todo o SDK. O Dockerfile também é mais simples:
Dockerfile:
FROM microsoft/dotnet:1.1.2-runtime
WORKDIR /app
ENTRYPOINT ["dotnet", "OrleansSilo.dll"]
COPY . /app
O arquivo docker-compose
O docker-compose.yml
arquivo define um conjunto de serviços e suas dependências em um projeto no nível de serviço. Cada serviço contém uma ou mais instâncias de um determinado contêiner, com base nas imagens selecionadas no Dockerfile. Encontre mais detalhes sobre docker-compose
na documentação do docker-compose.
Para uma implantação Orleans , um caso de uso comum envolve um docker-compose.yml
arquivo que contém dois serviços: um para o Orleans Silo e outro para o Orleans Cliente. O serviço Cliente depende do serviço Silo, o que significa que ele só é iniciado após a execução do serviço Silo. Outro cenário pode envolver a adição de um serviço/contêiner de banco de dados ou de armazenamento (como o SQL Server), que deve começar antes do cliente e do silo. Nesse caso, os serviços de cliente e silo dependeriam do serviço de banco de dados.
Observação
Antes de continuar lendo, observe que indentaçãoé importante nos docker-compose
arquivos. Preste atenção a ele se surgirem problemas.
Veja como os serviços são descritos para este artigo:
docker-compose.override.yml (Depuração):
version: '3.1'
services:
orleans-client:
image: orleans-client:debug
build:
context: ./src/OrleansClient/bin/PublishOutput/
dockerfile: Dockerfile.Debug
volumes:
- ./src/OrleansClient/bin/PublishOutput/:/app
- ~/.nuget/packages:/root/.nuget/packages:ro
depends_on:
- orleans-silo
orleans-silo:
image: orleans-silo:debug
build:
context: ./src/OrleansSilo/bin/PublishOutput/
dockerfile: Dockerfile.Debug
volumes:
- ./src/OrleansSilo/bin/PublishOutput/:/app
- ~/.nuget/packages:/root/.nuget/packages:ro
docker-compose.yml (produção):
version: '3.1'
services:
orleans-client:
image: orleans-client
depends_on:
- orleans-silo
orleans-silo:
image: orleans-silo
Na produção, o diretório local não é mapeado nem a ação build:
está incluída. O motivo é que, em um ambiente de produção, as imagens devem ser criadas e enviadas por push para um Registro privado do Docker.
Colocar tudo em conjunto
Agora que todos os componentes necessários estão prontos, vamos colocá-los juntos para executar a solução dentro do Orleans Docker.
Importante
Os comandos a seguir devem ser executados no diretório da solução.
Primeiro, verifique se todos os pacotes NuGet para a solução foram restaurados. Isso normalmente precisa ser feito apenas uma vez, a menos que as dependências do pacote mudem.
dotnet restore
Agora, crie a solução usando a dotnet
CLI como de costume e publique-a em um diretório de saída:
dotnet publish -o ./bin/PublishOutput
Dica
publish
é usado aqui em vez de build
para evitar problemas com assemblies carregados dinamicamente em Orleans. Uma solução melhor ainda está sendo procurada.
Com o aplicativo criado e publicado, crie as imagens do Docker usando os Dockerfiles. Essa etapa normalmente precisa ser executada apenas uma vez por projeto. Ele só deverá ser necessário novamente se o arquivo Dockerfile ou docker-compose for alterado ou se o registro de imagem local for limpo por qualquer motivo.
docker-compose build
Todas as imagens base usadas em ambos Dockerfile
e docker-compose.yml
são extraídas do registro e armazenadas em cache no computador de desenvolvimento. As imagens do aplicativo são criadas e tudo está pronto para ser executado.
Agora, vamos executar o aplicativo!
# docker-compose up -d
Creating network "orleansdocker_default" with the default driver
Creating orleansdocker_orleans-silo_1 ...
Creating orleansdocker_orleans-silo_1 ... done
Creating orleansdocker_orleans-client_1 ...
Creating orleansdocker_orleans-client_1 ... done
#
Agora, executar docker-compose ps
mostra dois contêineres em execução para o projeto orleansdocker
.
# docker-compose ps
Name Command State Ports
------------------------------------------------------------------
orleansdocker_orleans-client_1 tail -f /dev/null Up
orleansdocker_orleans-silo_1 tail -f /dev/null Up
Observação
Se estiver no Windows e o contêiner usar uma imagem base do Windows, a coluna Comando mostrará o comando equivalente do PowerShell nos sistemas do tipo UNIX, mantendo o contêiner em execução de forma semelhante.
Agora que os contêineres estão em execução, não é necessário pará-los toda vez que o aplicativo Orleans precisa ser iniciado. Basta integrar a IDE para depurar o aplicativo dentro do contêiner, que foi anteriormente mapeado no docker-compose.yml
.
Escalonamento
Depois que o projeto de redação for executado, dimensione o aplicativo facilmente para cima ou para baixo usando o docker-compose scale
comando:
# docker-compose scale orleans-silo=15
Starting orleansdocker_orleans-silo_1 ... done
Creating orleansdocker_orleans-silo_2 ...
Creating orleansdocker_orleans-silo_3 ...
Creating orleansdocker_orleans-silo_4 ...
Creating orleansdocker_orleans-silo_5 ...
Creating orleansdocker_orleans-silo_6 ...
Creating orleansdocker_orleans-silo_7 ...
Creating orleansdocker_orleans-silo_8 ...
Creating orleansdocker_orleans-silo_9 ...
Creating orleansdocker_orleans-silo_10 ...
Creating orleansdocker_orleans-silo_11 ...
Creating orleansdocker_orleans-silo_12 ...
Creating orleansdocker_orleans-silo_13 ...
Creating orleansdocker_orleans-silo_14 ...
Creating orleansdocker_orleans-silo_15 ...
Creating orleansdocker_orleans-silo_6
Creating orleansdocker_orleans-silo_5
Creating orleansdocker_orleans-silo_3
Creating orleansdocker_orleans-silo_2
Creating orleansdocker_orleans-silo_4
Creating orleansdocker_orleans-silo_9
Creating orleansdocker_orleans-silo_7
Creating orleansdocker_orleans-silo_8
Creating orleansdocker_orleans-silo_10
Creating orleansdocker_orleans-silo_11
Creating orleansdocker_orleans-silo_15
Creating orleansdocker_orleans-silo_12
Creating orleansdocker_orleans-silo_14
Creating orleansdocker_orleans-silo_13
Após alguns segundos, os serviços são dimensionados para o número específico de instâncias solicitadas.
# docker-compose ps
Name Command State Ports
------------------------------------------------------------------
orleansdocker_orleans-client_1 tail -f /dev/null Up
orleansdocker_orleans-silo_1 tail -f /dev/null Up
orleansdocker_orleans-silo_10 tail -f /dev/null Up
orleansdocker_orleans-silo_11 tail -f /dev/null Up
orleansdocker_orleans-silo_12 tail -f /dev/null Up
orleansdocker_orleans-silo_13 tail -f /dev/null Up
orleansdocker_orleans-silo_14 tail -f /dev/null Up
orleansdocker_orleans-silo_15 tail -f /dev/null Up
orleansdocker_orleans-silo_2 tail -f /dev/null Up
orleansdocker_orleans-silo_3 tail -f /dev/null Up
orleansdocker_orleans-silo_4 tail -f /dev/null Up
orleansdocker_orleans-silo_5 tail -f /dev/null Up
orleansdocker_orleans-silo_6 tail -f /dev/null Up
orleansdocker_orleans-silo_7 tail -f /dev/null Up
orleansdocker_orleans-silo_8 tail -f /dev/null Up
orleansdocker_orleans-silo_9 tail -f /dev/null Up
Importante
A coluna Command
neste exemplo mostra o comando tail
porque o contêiner do depurador é usado. Na produção, mostraria dotnet OrleansSilo.dll
, por exemplo.
Docker Swarm
A pilha de clustering do Docker é chamada Swarm. Para obter mais informações, consulte Docker Swarm.
Para executar o aplicativo descrito neste artigo em um Swarm
cluster, nenhum trabalho extra é necessário. A execução docker-compose up -d
em um Swarm
nó agenda contêineres com base em regras configuradas. O mesmo se aplica a outros serviços baseados em Swarm, como o AKS (Serviço de Kubernetes do Azure) (no modo Swarm) e o ECS (Serviço de Contêiner Elástico) do AWS. Basta implantar o Swarm
cluster antes de implantar o aplicativo dockerizadoOrleans .
Observação
Se você estiver usando um mecanismo do Docker com suporte ao modo Swarm, stack
, deploy
e compose
v3, uma abordagem melhor para implantar a solução será docker stack deploy -c docker-compose.yml <name>
. Tenha em mente que isso requer um arquivo de composição v3 compatível com o mecanismo do Docker. Muitos serviços hospedados, como o Azure e o AWS, ainda usam mecanismos v2 e mais antigos.
Google Kubernetes (K8s)
Se estiver planejando usar o Kubernetes para hospedar Orleans, um provedor de clustering mantido pela comunidade estará disponível em OrleansContrib\Orleans. Clustering.Kubernetes. Lá, localize a documentação e os exemplos de hospedagem Orleans no Kubernetes diretamente usando o provedor.
Depurar o Orleans dentro de contêineres
Agora que a execução Orleans em um contêiner do zero é compreendida, é benéfico aproveitar um dos princípios mais importantes do Docker: a imutabilidade. Os contêineres devem ter (quase) a mesma imagem, dependências e tempo de execução em desenvolvimento como em produção. Essa prática ajuda a evitar o problema clássico "Funciona no meu computador!" . Para tornar isso possível, é necessária uma maneira de desenvolver dentro do contêiner, incluindo anexar um depurador ao aplicativo em execução dentro dele.
Existem várias maneiras de conseguir isso usando várias ferramentas. Depois de avaliar várias opções no momento da redação, foi escolhida uma que parece mais simples e menos intrusiva para o aplicativo.
Conforme mencionado anteriormente, VSCode
é usado para desenvolver o exemplo. Veja como anexar o depurador ao aplicativo Orleans dentro do contêiner.
Primeiro, modifique dois arquivos dentro do .vscode
diretório na solução:
tasks.json:
{
"version": "0.1.0",
"command": "dotnet",
"isShellCommand": true,
"args": [],
"tasks": [
{
"taskName": "publish",
"args": [
"${workspaceRoot}/Orleans-Docker.sln", "-c", "Debug", "-o", "./bin/PublishOutput"
],
"isBuildCommand": true,
"problemMatcher": "$msCompile"
}
]
}
Esse arquivo essencialmente informa VSCode
que sempre que o projeto é compilado, ele executa o publish
comando, semelhante a como ele foi feito manualmente anteriormente.
launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Silo",
"type": "coreclr",
"request": "launch",
"cwd": "/app",
"program": "/app/OrleansSilo.dll",
"sourceFileMap": {
"/app": "${workspaceRoot}/src/OrleansSilo"
},
"pipeTransport": {
"debuggerPath": "/vsdbg/vsdbg",
"pipeProgram": "/bin/bash",
"pipeCwd": "${workspaceRoot}",
"pipeArgs": [
"-c",
"docker exec -i orleansdocker_orleans-silo_1 /vsdbg/vsdbg --interpreter=vscode"
]
}
},
{
"name": "Client",
"type": "coreclr",
"request": "launch",
"cwd": "/app",
"program": "/app/OrleansClient.dll",
"sourceFileMap": {
"/app": "${workspaceRoot}/src/OrleansClient"
},
"pipeTransport": {
"debuggerPath": "/vsdbg/vsdbg",
"pipeProgram": "/bin/bash",
"pipeCwd": "${workspaceRoot}",
"pipeArgs": [
"-c",
"docker exec -i orleansdocker_orleans-client_1 /vsdbg/vsdbg --interpreter=vscode"
]
}
}
]
}
Agora, construa a solução a partir de VSCode
, que também publica, e inicie as configurações do Silo e do cliente. O VSCode envia um docker exec
comando para a instância/contêiner de serviço em execução docker-compose
para iniciar o depurador anexado ao aplicativo. É isso! O depurador é anexado ao contêiner e pode ser usado exatamente como depurar um aplicativo em execução Orleans localmente. A principal diferença é que o aplicativo é executado dentro do contêiner. Depois que o desenvolvimento for concluído, publique a imagem do contêiner no registro e efetue pull dela nos hosts do Docker em produção.