Sdílet prostřednictvím


Nasazení Dockeru

Tip

I když jste obeznámeni s Dockerem nebo Orleans, doporučujeme, abyste si tento článek přečetli na konci, abyste se vyhnuli problémům, se kterými se můžete setkat s alternativními řešeními.

Tento článek a její ukázka představují probíhající práci. Vítá vás jakákoli zpětná vazba, žádost o přijetí změn nebo návrh.

Nasazení Orleans řešení do Dockeru

Orleans Nasazení do Dockeru může být složité vzhledem k tomu, jak byly navrženy orchestrátory Dockeru a zásobníky clusteringu. Nejkomplikovanější je porozumět konceptu překryvné sítě z síťového modelu Docker Swarm a Kubernetes.

Kontejnery a síťové modely Dockeru byly navrženy tak, aby spouštěly převážně bezstavové a neměnné kontejnery. Takže je velmi snadné roztáčet cluster se spuštěnými node.js nebo aplikacemi Nginx. Pokud se ale pokusíte použít něco složitějšího, jako je skutečná clusterovaná nebo distribuovaná aplikace (například Orleanszaložené na nich), budete mít nakonec potíže s nastavením. Je to možné, ale ne tak jednoduché jako webové aplikace.

Clustering Dockeru se skládá z vytvoření více hostitelů pro práci jako jeden fond prostředků spravovaných pomocí nástroje Container Orchestrator. Docker Inc. poskytnout Swarm jako svou možnost pro orchestraci kontejnerů, zatímco GoogleKubernetes (neboli K8s). Existují další orchestrátory, jako je DC/OS, Mesos, ale v tomto dokumentu budeme mluvit o Swarm a K8s, protože jsou široce používány.

Stejná rozhraní a implementace, která běží kdekoli Orleans , se už podporují i v kontejnerech Dockeru. Abyste mohli aplikaci spouštět v kontejnerech Dockeru, není potřeba brát v úvahu žádné zvláštní aspekty.

Zde probírané koncepty se dají použít na variantách Orleans .NET Core i .NET 4.6.1, ale pro ilustraci multiplatformní povahy Dockeru a .NET Core se zaměříme na příklad, který uvažujete o tom, že používáte .NET Core. Podrobnosti specifické pro platformu (Windows/Linux/OSX) můžou být uvedeny v tomto článku.

Požadavky

Tento článek předpokládá, že máte nainstalované následující požadavky:

  • Docker – Docker4X má snadno použitelný instalační program pro hlavní podporované platformy. Obsahuje modul Dockeru a také Docker Swarm.
  • Kubernetes (K8s) – nabídka Googlu pro Orchestraci kontejnerů Obsahuje pokyny k instalaci Minikube (místní nasazení K8s) a kubectl spolu se všemi jeho závislostmi.
  • .NET – multiplatformní varianta rozhraní .NET
  • Visual Studio Code (VSCode) – můžete použít libovolné prostředí IDE, které chcete. VSCode je multiplatformní, takže ho používáme k zajištění toho, aby fungoval na všech platformách. Po instalaci VSCode nainstalujte rozšíření C#.

Důležité

Pokud ho nebudete používat, nemusíte mít nainstalovaný Kubernetes. Instalační program Docker4X už obsahuje Swarm, takže k jeho použití není nutná žádná další instalace.

Poznámka:

Instalační program Dockeru ve Windows povolí Hyper-V v procesu instalace. Protože tento článek a jeho příklady používají .NET Core, použité image kontejnerů jsou založené na Windows Serveru NanoServer. Pokud nechcete používat .NET Core a budete cílit na úplnou architekturu .NET 4.6.1, měla by použitá image být Windows Server Core a verze Orleans 1.4 nebo novější (která podporuje pouze úplné rozhraní .NET).

Vytvořit řešení Orleans

Následující pokyny ukazují, jak vytvořit běžné Orleans řešení pomocí nového dotnet nástroje.

Přizpůsobte si příkazy podle toho, co je ve vaší platformě vhodné. Adresářová struktura je také jen návrh. Přizpůsobte si ho svým potřebám.

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

Zatím jsme použili jen často používaný kód pro vytvoření struktury řešení a projektů a přidání odkazů mezi projekty. Nic jiného než běžný Orleans projekt.

V době, kdy byl tento článek napsán, Orleans 2.0 (což je jediná verze podporující .NET Core a multiplatformní verze) je ve verzi Technology Preview, takže jeho balíčky NuGet jsou hostované v informačním kanálu MyGet a nepublikují se do Nuget.org oficiálního informačního kanálu. K instalaci balíčků NuGet ve verzi Preview použijeme dotnet rozhraní příkazového řádku, které vynutí zdrojový kanál a verzi z MyGetu:

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, teď máte všechny základní závislosti pro spuštění jednoduché Orleans aplikace. Všimněte si, že zatím se z běžné Orleans aplikace nic nezměnilo. Teď přidáme nějaký kód, abychom s ním mohli něco udělat.

Implementace aplikace Orleans

Za předpokladu, že používáte VSCode, z adresáře řešení spusťte code .. Tím otevřete adresář ve VSCode a načtete řešení.

Toto je struktura řešení, kterou jsme právě vytvořili dříve.

Visual Studio Code: Průzkumník s vybranou Program.cs.

Do rozhraní a odstupňovaných projektů jsme také přidali soubory Program.cs, OrleansHostWrapper.cs, IGreetingGrain.cs a GreetingGrain.cs a tady je kód pro tyto soubory:

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 (sil):

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 (klient):

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);
            }
        }
    }
}

Podrobnosti o implementaci podrobností zde neprocházíme, protože je mimo rozsah tohoto článku. Zkontrolujte další dokumenty, které s ním souvisejí. Tyto soubory jsou v podstatě minimální Orleans aplikací a začneme od ní pokračovat se zbývající částí tohoto článku.

V tomto článku používáme OrleansAzureUtils poskytovatele členství, ale můžete použít jakékoli jiné již podporované Orleans.

Soubor Dockerfile

K vytvoření kontejneru používá Docker image. Další podrobnosti o tom, jak vytvořit vlastní, najdete v dokumentaci k Dockeru. V tomto článku budeme používat oficiální image Microsoftu. Na základě cílových a vývojových platforem je potřeba vybrat odpovídající image. V tomto článku používáme microsoft/dotnet:1.1.2-sdk image založenou na Linuxu. Můžete například použít microsoft/dotnet:1.1.2-sdk-nanoserver pro Windows. Vyberte si ten, který vyhovuje vašim potřebám.

Poznámka pro uživatele Windows: Jak jsme již zmínili, abychom byli multiplatformní, používáme .NET Core a Orleans Technical Preview 2.0 v tomto článku. Pokud chcete používat Docker ve Windows s plně vydanými Orleans verzemi 1.4 nebo novější, musíte použít image založené na jádru Windows Serveru, protože image NanoServer a Linux podporují pouze .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"]

Tento soubor Dockerfile v podstatě stáhne a nainstaluje ladicí program VSdbg a spustí prázdný kontejner, takže ho nebudeme muset vyrušovat/up při ladění.

V produkčním prostředí je teď image menší, protože obsahuje pouze modul runtime .NET Core, nikoli celou sadu SDK, a soubor Dockerfile je trochu jednodušší:

Soubor Dockerfile:

FROM microsoft/dotnet:1.1.2-runtime
WORKDIR /app
ENTRYPOINT ["dotnet", "OrleansSilo.dll"]
COPY . /app

Soubor docker-compose

Soubor docker-compose.yml v podstatě definuje (v rámci projektu) sadu služeb a její závislosti na úrovni služby. Každá služba obsahuje jednu nebo více instancí daného kontejneru, která je založená na imagích, které jste vybrali v souboru Dockerfile. Další podrobnosti o této docker-compose dokumentaci najdete v dokumentaci k docker-compose.

Orleans U nasazení je běžným případem docker-compose.yml použití mít dvě služby. Jeden pro Orleans sila a druhý pro Orleans klienta. Klient by měl závislost na silu, což znamená, že se spustí až po spuštění služby sila. Dalším případem je přidání služby úložiště, databázové služby nebo kontejneru, jako je například SQL Server, který by se měl spustit jako první před klientem a silem, takže obě služby by na něm měly záviset.

Poznámka:

Než se pustíte do dalšího čtení, mějte na paměti, že vsouborech záleží na docker-compose odsazení. Takže věnujte pozornost tomu, pokud máte nějaké problémy.

Tady je postup, jak popíšeme naše služby pro tento článek:

docker-compose.override.yml (ladění):

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 (produkční):

version: '3.1'

services:
  orleans-client:
    image: orleans-client
    depends_on:
      - orleans-silo
  orleans-silo:
    image: orleans-silo

V produkčním prostředí nenamapujeme místní adresář ani akci build: . Důvodem je, že v produkčním prostředí by se image měly sestavit a odeslat do vlastního registru Dockeru.

Spojte všechno dohromady

Teď máme všechny pohyblivé části potřebné ke spuštění vaší Orleans aplikace, vytvoříme ho dohromady, abychom mohli naše řešení spustit Orleans uvnitř Dockeru (Nakonec!).

Důležité

Následující příkazy by se měly provádět z adresáře řešení.

Nejprve se ujistěme, že obnovíme všechny balíčky NuGet z našeho řešení. Stačí to udělat jen jednou. Pokud změníte jakoukoli závislost balíčku na projektu, budete ji muset provést znovu.

dotnet restore

Teď sestavíme naše řešení pomocí dotnet rozhraní příkazového řádku jako obvykle a publikujeme ho do výstupního adresáře:

dotnet publish -o ./bin/PublishOutput

Tip

Používáme publish zde místo sestavení, abychom se vyhnuli problémům s dynamicky načtenými sestaveními v Orleans. Stále hledáme lepší řešení.

Když je aplikace vytvořená a publikovaná, musíte vytvořit image souboru Dockerfile. Tento krok je potřeba provést pouze jednou pro každý projekt a měl by se provést pouze v případě, že změníte soubor Dockerfile, docker-compose nebo z jakéhokoli důvodu vyčistíte místní registr imagí.

docker-compose build

Všechny image použité v obou Dockerfiledocker-compose.yml imagích se natahují z registru a ukládají se do mezipaměti na vašem vývojovém počítači. Vaše image jsou sestavené a všechny jsou nastavené tak, aby běžely.

Teď to pojďme spustit!

# 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
#

Když teď spustíte příkaz docker-compose ps, zobrazí se 2 kontejnery spuštěné pro orleansdocker projekt:

# 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

Poznámka:

Pokud používáte Windows a kontejner používá jako základ image Windows, zobrazí se ve sloupci Command relativní příkaz PowerShellu k systémům tail *NIX, aby kontejner zůstal stejný.

Teď, když máte kontejnery vzhůru, nemusíte ho zastavovat pokaždé, když chcete aplikaci spustit Orleans . Stačí integrovat integrované vývojové prostředí (IDE) pro ladění aplikace uvnitř kontejneru, který byl dříve namapován ve vašem docker-compose.ymlprostředí .

Škálování

Jakmile máte spuštěný projekt pro psaní, můžete snadno vertikálně navýšit nebo snížit kapacitu aplikace pomocí docker-compose scale příkazu:

# 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

Po několikasekundch

# 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

Důležité

Sloupec Command v těchto příkladech zobrazuje tail příkaz jenom proto, že používáme kontejner ladicího programu. Kdybysme byli v produkčním prostředí, bylo by to dotnet OrleansSilo.dll vidět například.

Docker swarm

Zásobník clusteringu Dockeru se nazývá Swarm, další informace najdete v DockerU Swarm.

Pokud chcete tento článek spustit v clusteru Swarm , nemáte žádnou další práci. Při spuštění docker-compose up -d v Swarm uzlu naplánuje kontejnery na základě nakonfigurovaných pravidel. Totéž platí pro ostatní služby založené na Swarm, jako je Azure ACS (v režimu Swarm) a AWS ECS Container Service. Stačí jen nasadit Swarm cluster před nasazením dockerizovanéOrleans aplikace.

Poznámka:

Pokud používáte modul Dockeru s režimem Swarm, který již podporuje stack, deploya compose v3, lepší přístup k nasazení vašeho řešení je docker stack deploy -c docker-compose.yml <name>. Mějte na paměti, že k podpoře vašeho modulu Dockeru vyžaduje soubor v3 compose a většina hostovaných služeb, jako je Azure a AWS, stále používají moduly v2 a starší.

Google Kubernetes (K8s)

Pokud plánujete používat Kubernetes k hostováníOrleans, je k dispozici poskytovatel clusteringu spravovaný komunitou na Orleanswebu Contrib\Orleans. Clustering.Kubernetes. Tady najdete dokumentaci a ukázky týkající se bezproblémového hostování Orleans v Kubernetes pomocí poskytovatele.

Ladění Orleans uvnitř kontejnerů

Teď, když víte, jak spustit Orleans v kontejneru úplně od začátku, je dobré využít jeden z nejdůležitějších principů v Dockeru. Kontejnery jsou neměnné. A měly by mít (téměř) stejnou image, závislosti a modul runtime ve vývoji jako v produkčním prostředí. Tím se zajistí dobrý starý výrok "Funguje na mém počítači!" nikdy se nestane znovu. Aby to bylo možné, musíte mít způsob, jak vyvíjet uvnitř kontejneru a který zahrnuje připojení ladicího programu k aplikaci uvnitř kontejneru.

Existuje několik způsobů, jak toho dosáhnout pomocí více nástrojů. Po vyhodnocení několika, v době, kdy jsem napsal tento článek, skončil jsem výběr, který vypadá jednodušeji a je méně rušivý v aplikaci.

Jak jsme zmínili dříve v tomto článku, používáme VSCode k vývoji ukázky, takže tady je postup, jak do kontejneru Orleans připojit ladicí program.

Nejprve v řešení změňte .vscode dva soubory v adresáři:

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"
        }
    ]
}

Tento soubor v podstatě říká VSCode , že pokaždé, když projekt sestavíte, spustí publish příkaz, jak jsme to udělali ručně.

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"
                ]
            }
        }
    ]
}

Teď můžete jednoduše sestavit řešení VSCode (které se publikuje) a spustit sila i klienta. docker exec Odešle příkaz do spuštěné docker-compose instance služby nebo kontejneru, který spustí ladicí program do aplikace, a to je to. Máte k kontejneru připojený ladicí program a používáte ho, jako by šlo o místně spuštěnou Orleans aplikaci. Rozdíl je v tom, že je uvnitř kontejneru a jakmile budete hotovi, můžete kontejner publikovat do registru a načíst ho na hostitele Dockeru v produkčním prostředí.