Bagikan melalui


Penyebaran Docker

Tip

Bahkan jika Anda terbiasa dengan Docker atau Orleans, disarankan Anda untuk membaca artikel ini sampai akhir untuk menghindari masalah yang mungkin Anda hadapi yang memiliki solusi.

Artikel ini dan sampelnya sedang berlangsung. Setiap umpan balik, PR, atau saran dipersilakan.

Menyebarkan Orleans solusi ke Docker

Menyebarkan Orleans ke Docker dapat sulit mengingat cara orkestrator Docker dan tumpukan pengklusteran dirancang. Hal yang paling rumit adalah memahami konsep Overlay Network dari model jaringan Docker Swarm dan Kubernetes.

Kontainer Docker dan model jaringan dirancang untuk menjalankan sebagian besar kontainer tanpa status dan tidak dapat diubah. Jadi, memutar kluster yang menjalankan aplikasi node.js atau Nginx cukup mudah. Namun, jika Anda mencoba menggunakan sesuatu yang lebih menguraikan, seperti aplikasi terkluster atau terdistribusi nyata (seperti Orleansyang berbasis) Anda akhirnya akan kesulitan menyiapkannya. Hal ini dimungkinkan, tetapi tidak sesering aplikasi berbasis web.

Pengklusteran Docker terdiri dari menyusun beberapa host untuk bekerja sebagai satu kumpulan sumber daya, dikelola menggunakan Container Orchestrator. Docker Inc. menyediakan Swarm sebagai opsi mereka untuk Container Orchestration sementara Google memiliki Kubernetes (alias K8s). Ada Orkestrator lain seperti DC/OS, Mesos, tetapi dalam dokumen ini, kita akan berbicara tentang Swarm dan K8 karena mereka lebih banyak digunakan.

Antarmuka dan implementasi biji-bijian yang sama yang berjalan di mana saja Orleans sudah didukung juga akan berjalan pada kontainer Docker. Tidak ada pertimbangan khusus yang diperlukan untuk dapat menjalankan aplikasi Anda dalam kontainer Docker.

Konsep yang dibahas di sini dapat digunakan pada rasa Orleans .NET Core dan .NET 4.6.1 tetapi untuk menggambarkan sifat lintas platform Docker dan .NET Core, kami akan fokus pada contoh mengingat Anda menggunakan .NET Core. Detail khusus platform (Windows/Linux/OSX) dapat disediakan dalam artikel ini.

Prasyarat

Artikel ini mengasumsikan bahwa Anda telah menginstal prasyarat berikut:

  • Docker - Docker4X memiliki alat penginstal yang mudah digunakan untuk platform utama yang didukung. Ini berisi mesin Docker dan juga Docker Swarm.
  • Kubernetes (K8s) - Penawaran Google untuk Container Orchestration. Ini berisi panduan untuk menginstal Minikube (penyebaran lokal K8s) dan kubectl bersama dengan semua dependensinya.
  • .NET - Rasa lintas platform .NET
  • Visual Studio Code (VSCode) - Anda dapat menggunakan IDE apa pun yang Anda inginkan. VSCode adalah lintas platform sehingga kami menggunakannya untuk memastikannya berfungsi di semua platform. Setelah Anda menginstal VSCode, instal ekstensi C#.

Penting

Anda tidak diharuskan menginstal Kubernetes jika anda tidak akan menggunakannya. Alat penginstal Docker4X sudah menyertakan Swarm sehingga tidak ada penginstalan tambahan yang diperlukan untuk menggunakannya.

Catatan

Di Windows, alat penginstal Docker akan mengaktifkan Hyper-V pada proses penginstalan. Karena artikel ini dan contohnya menggunakan .NET Core, gambar kontainer yang digunakan didasarkan pada Windows Server NanoServer. Jika Anda tidak berencana untuk menggunakan .NET Core dan akan menargetkan kerangka kerja penuh .NET 4.6.1, gambar yang digunakan harus Windows Server Core dan versi Orleans 1.4+ (yang hanya mendukung kerangka kerja penuh .NET).

Membuat Orleans solusi

Instruksi berikut menunjukkan cara membuat solusi reguler Orleans menggunakan alat baru dotnet .

Silakan sesuaikan perintah dengan apa pun yang sesuai di platform Anda. Selain itu, struktur direktori hanyalah saran. Silakan sesuaikan dengan kebutuhan Anda.

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

Apa yang kami lakukan sejauh ini hanya kode boilerplate untuk membuat struktur solusi dan proyek, dan menambahkan referensi antar proyek. Tidak ada yang berbeda dari proyek biasa Orleans .

Pada saat artikel ini ditulis, Orleans 2.0 (yang merupakan satu-satunya versi yang mendukung .NET Core dan lintas platform) ada di Pratinjau Teknologi sehingga paket NuGet-nya dihosting di umpan MyGet dan tidak diterbitkan ke umpan resmi Nuget.org. Untuk menginstal paket NuGet pratinjau, kita akan menggunakan dotnet CLI yang memaksa umpan sumber dan versi dari 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, sekarang Anda memiliki semua dependensi dasar untuk menjalankan aplikasi sederhana Orleans . Perhatikan bahwa sejauh ini, tidak ada yang berubah dari aplikasi reguler Orleans Anda. Sekarang, mari kita tambahkan beberapa kode sehingga kita dapat melakukan sesuatu dengannya.

Menerapkan aplikasi Anda Orleans

Dengan asumsi Bahwa Anda menggunakan VSCode, dari direktori solusi, jalankan code .. Itu akan membuka direktori di VSCode dan memuat solusi.

Ini adalah struktur solusi yang baru saja kita buat sebelumnya.

Visual Studio Code: Explorer dengan Program.cs dipilih.

Kami juga menambahkan file Program.cs, OrleansHostWrapper.cs, IGreetingGrain.cs, dan GreetingGrain.cs ke antarmuka dan proyek biji-bijian masing-masing, dan berikut adalah kode untuk file-file tersebut:

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

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

Kami tidak akan masuk ke detail tentang implementasi biji-bijian di sini karena berada di luar cakupan artikel ini. Silakan periksa dokumen lain yang terkait dengannya. File-file tersebut pada dasarnya adalah aplikasi minimal Orleans dan kami akan mulai darinya untuk bergerak maju dengan sisa artikel ini.

Dalam artikel ini, kami menggunakan OrleansAzureUtils penyedia keanggotaan tetapi Anda dapat menggunakan yang lain yang sudah didukung oleh Orleans.

Dockerfile

Untuk membuat kontainer Anda, Docker menggunakan gambar. Untuk detail selengkapnya tentang cara membuat sendiri, Anda dapat memeriksa dokumentasi Docker. Dalam artikel ini, kita akan menggunakan gambar Microsoft resmi. Berdasarkan platform target dan pengembangan, Anda perlu memilih gambar yang sesuai. Dalam artikel ini, kami menggunakan microsoft/dotnet:1.1.2-sdk yang merupakan gambar berbasis Linux. Anda dapat menggunakan microsoft/dotnet:1.1.2-sdk-nanoserver untuk Windows misalnya. Pilih salah satu yang sesuai dengan kebutuhan Anda.

Catatan untuk pengguna Windows: Seperti yang disebutkan sebelumnya, untuk menjadi lintas platform, kami menggunakan .NET Core dan Orleans Pratinjau teknis 2.0 dalam artikel ini. Jika Anda ingin menggunakan Docker di Windows dengan Orleans 1.4+, Anda perlu menggunakan gambar yang didasarkan pada Windows Server Core karena NanoServer dan gambar berbasis Linux, hanya mendukung .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"]

Dockerfile ini pada dasarnya mengunduh dan menginstal debugger VSdbg dan memulai kontainer kosong, menjaganya tetap hidup selamanya sehingga kita tidak perlu merobek/naik saat debugging.

Sekarang, untuk produksi, gambar lebih kecil karena hanya berisi runtime .NET Core dan bukan seluruh SDK, dan dockerfile sedikit lebih sederhana:

Dockerfile:

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

File docker-compose

File, docker-compose.yml pada dasarnya mendefinisikan (dalam proyek) serangkaian layanan dan dependensinya di tingkat layanan. Setiap layanan berisi satu atau beberapa instans kontainer tertentu, yang didasarkan pada gambar yang Anda pilih di Dockerfile Anda. Detail selengkapnya tentang docker-compose dapat ditemukan pada dokumentasi docker-compose.

Orleans Untuk penyebaran, kasus penggunaan umum adalah memiliki docker-compose.yml yang berisi dua layanan. Satu untuk Orleans Silo, dan yang lainnya untuk Orleans Klien. Klien akan memiliki dependensi pada Silo dan itu berarti, itu hanya akan dimulai setelah layanan Silo habis. Kasus lain adalah menambahkan layanan/kontainer penyimpanan/database, seperti misalnya SQL Server, yang harus dimulai terlebih dahulu sebelum klien dan silo, sehingga kedua layanan harus mengambil dependensi padanya.

Catatan

Sebelum Anda membaca lebih lanjut, harap dicatat bahwa indentasipenting dalam docker-compose file. Jadi perhatikanlah jika Anda memiliki masalah.

Berikut adalah cara kami akan menjelaskan layanan kami untuk artikel ini:

docker-compose.override.yml (Debug):

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

version: '3.1'

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

Dalam produksi, kami tidak memetakan direktori lokal, dan kami juga tidak memiliki build: tindakan. Alasannya adalah bahwa dalam produksi, gambar harus dibangun dan didorong ke Docker Registry Anda sendiri.

Menyatukan semuanya

Sekarang kita memiliki semua bagian bergerak yang diperlukan untuk menjalankan Aplikasi Anda Orleans , kita akan menyatukannya sehingga kita dapat menjalankan solusi kita Orleans di dalam Docker (Akhirnya!).

Penting

Perintah berikut harus dilakukan dari direktori solusi.

Pertama, mari kita pastikan kita memulihkan semua paket NuGet dari solusi kita. Anda hanya perlu melakukannya sekali. Anda hanya diharuskan melakukannya lagi jika Anda mengubah dependensi paket apa pun pada proyek Anda.

dotnet restore

Sekarang, mari kita bangun solusi kita menggunakan dotnet CLI seperti biasa dan menerbitkannya ke direktori output:

dotnet publish -o ./bin/PublishOutput

Tip

Kami menggunakan publish di sini alih-alih membangun, untuk menghindari masalah dengan rakitan kami yang dimuat secara dinamis di Orleans. Kami masih mencari solusi yang lebih baik untuk itu.

Dengan aplikasi yang dibuat dan diterbitkan, Anda perlu membuat gambar Dockerfile Anda. Langkah ini hanya diperlukan untuk dilakukan sekali per proyek dan hanya boleh dilakukan lagi jika Anda mengubah Dockerfile, docker-compose, atau karena alasan apa pun Anda membersihkan registri gambar lokal Anda.

docker-compose build

Semua gambar yang digunakan di keduanya Dockerfile dan docker-compose.yml ditarik dari registri dan di-cache pada komputer pengembangan Anda. Gambar Anda dibuat, dan Anda semua diatur untuk dijalankan.

Sekarang, mari kita jalankan!

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

Sekarang jika Anda menjalankan docker-compose ps, Anda akan melihat 2 kontainer yang orleansdocker berjalan untuk proyek:

# 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

Catatan

Jika Anda berada di Windows, dan kontainer Anda menggunakan gambar Windows sebagai dasar, kolom Perintah akan menunjukkan perintah relatif PowerShell ke tail pada sistem *NIX sehingga kontainer akan mengikuti cara yang sama.

Setelah kontainer aktif, Anda tidak perlu menghentikannya setiap kali Anda ingin memulai aplikasi Anda Orleans . Yang Anda butuhkan adalah mengintegrasikan IDE Anda untuk men-debug aplikasi di dalam kontainer yang sebelumnya dipetakan di Anda docker-compose.yml.

Penskalaan

Setelah proyek tulis berjalan, Anda dapat dengan mudah meningkatkan atau menurunkan skala aplikasi Anda menggunakan docker-compose scale perintah:

# 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

Setelah beberapa detik, Anda akan melihat layanan diskalakan ke jumlah instans tertentu yang Anda minta.

# 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

Penting

Kolom Command pada contoh tersebut tail menunjukkan perintah hanya karena kita menggunakan kontainer debugger. Jika kita dalam produksi, itu akan ditampilkan dotnet OrleansSilo.dll misalnya.

Kawanan Docker

Tumpukan pengklusteran Docker disebut Swarm, untuk informasi selengkapnya lihat, Docker Swarm.

Untuk menjalankan artikel ini dalam Swarm kluster, Anda tidak memiliki pekerjaan tambahan. Saat Anda menjalankan docker-compose up -d dalam simpul Swarm , itu akan menjadwalkan kontainer berdasarkan aturan yang dikonfigurasi. Hal yang sama berlaku untuk layanan berbasis Swarm lainnya seperti Azure ACS (dalam mode Swarm) dan AWS ECS Container Service. Yang perlu Anda lakukan adalah menyebarkan kluster Anda Swarm sebelum menyebarkan aplikasi yang di-docker.Orleans

Catatan

Jika Anda menggunakan mesin Docker dengan mode Swarm yang sudah memiliki dukungan untuk stack, , deploydan compose v3, pendekatan yang lebih baik untuk menyebarkan solusi Anda adalah docker stack deploy -c docker-compose.yml <name>. Perlu diingat bahwa diperlukan file kompos v3 untuk mendukung mesin Docker Anda, dan sebagian besar layanan yang dihosting seperti Azure dan AWS masih menggunakan mesin v2 dan yang lebih lama.

Google Kubernetes (K8s)

Jika Anda berencana menggunakan Kubernetes untuk menghosting Orleans, ada penyedia pengklusteran yang dikelola komunitas yang tersedia di OrleansContrib\Orleans. Clustering.Kubernetes. Di sana Anda dapat menemukan dokumentasi dan sampel tentang cara menghosting Orleans di Kubernetes dengan mulus menggunakan penyedia.

Debug Orleans di dalam kontainer

Sekarang setelah Anda tahu cara menjalankan Orleans dalam kontainer dari awal, ada baiknya untuk memanfaatkan salah satu prinsip terpenting dalam Docker. Kontainer tidak dapat diubah. Dan mereka harus memiliki (hampir) gambar, dependensi, dan runtime yang sama dalam pengembangan seperti dalam produksi. Ini memastikan pernyataan lama yang baik "Ini berfungsi pada komputer saya!" tidak pernah terjadi lagi. Untuk memungkinkan hal itu, Anda harus memiliki cara untuk mengembangkan di dalam kontainer dan itu termasuk memiliki debugger yang terpasang pada aplikasi Anda di dalam kontainer.

Ada beberapa cara untuk mencapainya menggunakan beberapa alat. Setelah mengevaluasi beberapa, pada saat saya menulis artikel ini, saya akhirnya memilih salah satu yang terlihat lebih sederhana dan kurang mengganggu dalam aplikasi.

Seperti disebutkan sebelumnya dalam artikel ini, kami menggunakan VSCode untuk mengembangkan sampel, jadi berikut adalah cara melekat debugger ke Aplikasi Anda Orleans di dalam kontainer.

Pertama, ubah dua file di dalam direktori Anda .vscode dalam solusi Anda:

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

File ini pada dasarnya memberi tahu VSCode bahwa setiap kali Anda membangun proyek, file tersebut akan menjalankan publish perintah seperti yang kami lakukan secara manual sebelumnya.

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

Sekarang Anda hanya dapat membangun solusi dari VSCode (yang akan menerbitkan) dan memulai Silo dan Klien. Ini akan mengirim docker exec perintah ke instans/kontainer layanan yang sedang berjalan docker-compose untuk memulai debugger ke aplikasi dan hanya itu. Anda memiliki debugger yang terpasang pada kontainer dan menggunakannya seolah-olah itu adalah aplikasi yang berjalan Orleans secara lokal. Perbedaannya sekarang adalah bahwa itu ada di dalam kontainer, dan setelah Selesai, Anda hanya dapat menerbitkan kontainer ke registri Anda dan menariknya pada host Docker Anda dalam produksi.