Skip to content

Commit

Permalink
Add support for an Advertised Host other than PodIP when using Kubern…
Browse files Browse the repository at this point in the history
…etes cluster provider (asynkron#2097)

* Add Host to k8s pod labels

* Removed logging of k8s workload kind

* Added new Public API to get K8s Pod FQDN

hardened GetKubeNamespace() so it will not read in more data then kuberneties allows for a namespace, it will also now throw a with a descriptive error exception message vs FileNotFound.
  • Loading branch information
AdamCLarsen authored Feb 6, 2024
1 parent 824c0cc commit af1a612
Show file tree
Hide file tree
Showing 27 changed files with 796 additions and 19 deletions.
70 changes: 70 additions & 0 deletions ProtoActor.sln
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,34 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Proto.Cluster.SeedNode.Mong
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GossipDecoder", "benchmarks\GossipDecoder\GossipDecoder.csproj", "{FC144547-78F5-4C0B-B886-B7BC1563893B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ClusterK8sGrains", "ClusterK8sGrains", "{ADE7A14E-FFE9-4137-AC25-E2F2A82B0A8C}"
ProjectSection(SolutionItems) = preProject
examples\ClusterK8sGrains\readme.md = examples\ClusterK8sGrains\readme.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Messages", "examples\ClusterK8sGrains\Messages\Messages.csproj", "{44B8EBA7-5A47-4D20-B62F-48413B676473}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Node1", "examples\ClusterK8sGrains\Node1\Node1.csproj", "{80DC28A1-D361-4A25-AC5D-8F5B6DCE276A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Node2", "examples\ClusterK8sGrains\Node2\Node2.csproj", "{B196FBFE-0DAA-4533-9A56-BB5826A57923}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "chart", "chart", "{CDCE3D4C-1BDD-460F-93B8-75123A258183}"
ProjectSection(SolutionItems) = preProject
examples\ClusterK8sGrains\chart\Chart.yaml = examples\ClusterK8sGrains\chart\Chart.yaml
examples\ClusterK8sGrains\chart\values.yaml = examples\ClusterK8sGrains\chart\values.yaml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "template", "template", "{087E5441-1582-4D55-8233-014C0FB06FF0}"
ProjectSection(SolutionItems) = preProject
examples\ClusterK8sGrains\chart\templates\namespace.yaml = examples\ClusterK8sGrains\chart\templates\namespace.yaml
examples\ClusterK8sGrains\chart\templates\node1-deployment.yaml = examples\ClusterK8sGrains\chart\templates\node1-deployment.yaml
examples\ClusterK8sGrains\chart\templates\node2-deployment.yaml = examples\ClusterK8sGrains\chart\templates\node2-deployment.yaml
examples\ClusterK8sGrains\chart\templates\protoactor-k8s-cluster-port-service.yaml = examples\ClusterK8sGrains\chart\templates\protoactor-k8s-cluster-port-service.yaml
examples\ClusterK8sGrains\chart\templates\protoactor-k8s-grains-role.yaml = examples\ClusterK8sGrains\chart\templates\protoactor-k8s-grains-role.yaml
examples\ClusterK8sGrains\chart\templates\protoactor-k8s-grains-rolebinding.yaml = examples\ClusterK8sGrains\chart\templates\protoactor-k8s-grains-rolebinding.yaml
examples\ClusterK8sGrains\chart\templates\protoactor-k8s-grains-serviceaccount.yaml = examples\ClusterK8sGrains\chart\templates\protoactor-k8s-grains-serviceaccount.yaml
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -1416,6 +1444,42 @@ Global
{FC144547-78F5-4C0B-B886-B7BC1563893B}.Release|x64.Build.0 = Release|Any CPU
{FC144547-78F5-4C0B-B886-B7BC1563893B}.Release|x86.ActiveCfg = Release|Any CPU
{FC144547-78F5-4C0B-B886-B7BC1563893B}.Release|x86.Build.0 = Release|Any CPU
{44B8EBA7-5A47-4D20-B62F-48413B676473}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44B8EBA7-5A47-4D20-B62F-48413B676473}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44B8EBA7-5A47-4D20-B62F-48413B676473}.Debug|x64.ActiveCfg = Debug|Any CPU
{44B8EBA7-5A47-4D20-B62F-48413B676473}.Debug|x64.Build.0 = Debug|Any CPU
{44B8EBA7-5A47-4D20-B62F-48413B676473}.Debug|x86.ActiveCfg = Debug|Any CPU
{44B8EBA7-5A47-4D20-B62F-48413B676473}.Debug|x86.Build.0 = Debug|Any CPU
{44B8EBA7-5A47-4D20-B62F-48413B676473}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44B8EBA7-5A47-4D20-B62F-48413B676473}.Release|Any CPU.Build.0 = Release|Any CPU
{44B8EBA7-5A47-4D20-B62F-48413B676473}.Release|x64.ActiveCfg = Release|Any CPU
{44B8EBA7-5A47-4D20-B62F-48413B676473}.Release|x64.Build.0 = Release|Any CPU
{44B8EBA7-5A47-4D20-B62F-48413B676473}.Release|x86.ActiveCfg = Release|Any CPU
{44B8EBA7-5A47-4D20-B62F-48413B676473}.Release|x86.Build.0 = Release|Any CPU
{80DC28A1-D361-4A25-AC5D-8F5B6DCE276A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{80DC28A1-D361-4A25-AC5D-8F5B6DCE276A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{80DC28A1-D361-4A25-AC5D-8F5B6DCE276A}.Debug|x64.ActiveCfg = Debug|Any CPU
{80DC28A1-D361-4A25-AC5D-8F5B6DCE276A}.Debug|x64.Build.0 = Debug|Any CPU
{80DC28A1-D361-4A25-AC5D-8F5B6DCE276A}.Debug|x86.ActiveCfg = Debug|Any CPU
{80DC28A1-D361-4A25-AC5D-8F5B6DCE276A}.Debug|x86.Build.0 = Debug|Any CPU
{80DC28A1-D361-4A25-AC5D-8F5B6DCE276A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{80DC28A1-D361-4A25-AC5D-8F5B6DCE276A}.Release|Any CPU.Build.0 = Release|Any CPU
{80DC28A1-D361-4A25-AC5D-8F5B6DCE276A}.Release|x64.ActiveCfg = Release|Any CPU
{80DC28A1-D361-4A25-AC5D-8F5B6DCE276A}.Release|x64.Build.0 = Release|Any CPU
{80DC28A1-D361-4A25-AC5D-8F5B6DCE276A}.Release|x86.ActiveCfg = Release|Any CPU
{80DC28A1-D361-4A25-AC5D-8F5B6DCE276A}.Release|x86.Build.0 = Release|Any CPU
{B196FBFE-0DAA-4533-9A56-BB5826A57923}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B196FBFE-0DAA-4533-9A56-BB5826A57923}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B196FBFE-0DAA-4533-9A56-BB5826A57923}.Debug|x64.ActiveCfg = Debug|Any CPU
{B196FBFE-0DAA-4533-9A56-BB5826A57923}.Debug|x64.Build.0 = Debug|Any CPU
{B196FBFE-0DAA-4533-9A56-BB5826A57923}.Debug|x86.ActiveCfg = Debug|Any CPU
{B196FBFE-0DAA-4533-9A56-BB5826A57923}.Debug|x86.Build.0 = Debug|Any CPU
{B196FBFE-0DAA-4533-9A56-BB5826A57923}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B196FBFE-0DAA-4533-9A56-BB5826A57923}.Release|Any CPU.Build.0 = Release|Any CPU
{B196FBFE-0DAA-4533-9A56-BB5826A57923}.Release|x64.ActiveCfg = Release|Any CPU
{B196FBFE-0DAA-4533-9A56-BB5826A57923}.Release|x64.Build.0 = Release|Any CPU
{B196FBFE-0DAA-4533-9A56-BB5826A57923}.Release|x86.ActiveCfg = Release|Any CPU
{B196FBFE-0DAA-4533-9A56-BB5826A57923}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1545,6 +1609,12 @@ Global
{5FECD1A8-A873-4927-81C3-E5C5A37D80C5} = {0F3AB331-C042-4371-A2F0-0AFDFA13DC9F}
{6611DA4A-6471-45CE-A288-45BC7BF00B52} = {3D12F5E5-9774-4D7E-8A5B-B1F64544925B}
{FC144547-78F5-4C0B-B886-B7BC1563893B} = {0F3AB331-C042-4371-A2F0-0AFDFA13DC9F}
{ADE7A14E-FFE9-4137-AC25-E2F2A82B0A8C} = {59DCCC96-DDAF-469F-9E8E-9BC733285082}
{44B8EBA7-5A47-4D20-B62F-48413B676473} = {ADE7A14E-FFE9-4137-AC25-E2F2A82B0A8C}
{80DC28A1-D361-4A25-AC5D-8F5B6DCE276A} = {ADE7A14E-FFE9-4137-AC25-E2F2A82B0A8C}
{B196FBFE-0DAA-4533-9A56-BB5826A57923} = {ADE7A14E-FFE9-4137-AC25-E2F2A82B0A8C}
{CDCE3D4C-1BDD-460F-93B8-75123A258183} = {ADE7A14E-FFE9-4137-AC25-E2F2A82B0A8C}
{087E5441-1582-4D55-8233-014C0FB06FF0} = {CDCE3D4C-1BDD-460F-93B8-75123A258183}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CD0D1E44-8118-4682-8793-6B20ABFA824C}
Expand Down
28 changes: 28 additions & 0 deletions examples/ClusterK8sGrains/Clusterk8sGrains.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Messages", "Messages\Messages.csproj", "{A5E3B3E1-5517-4E08-9E50-50EF17215AB5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Node2", "Node2\Node2.csproj", "{95685292-A5C9-48DA-871A-EB00A78A39A5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Node1", "Node1\Node1.csproj", "{B8D93ECE-0203-41C2-B845-7BBDDBA222DE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A5E3B3E1-5517-4E08-9E50-50EF17215AB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A5E3B3E1-5517-4E08-9E50-50EF17215AB5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5E3B3E1-5517-4E08-9E50-50EF17215AB5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A5E3B3E1-5517-4E08-9E50-50EF17215AB5}.Release|Any CPU.Build.0 = Release|Any CPU
{95685292-A5C9-48DA-871A-EB00A78A39A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{95685292-A5C9-48DA-871A-EB00A78A39A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{95685292-A5C9-48DA-871A-EB00A78A39A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95685292-A5C9-48DA-871A-EB00A78A39A5}.Release|Any CPU.Build.0 = Release|Any CPU
{B8D93ECE-0203-41C2-B845-7BBDDBA222DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B8D93ECE-0203-41C2-B845-7BBDDBA222DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B8D93ECE-0203-41C2-B845-7BBDDBA222DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B8D93ECE-0203-41C2-B845-7BBDDBA222DE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
22 changes: 22 additions & 0 deletions examples/ClusterK8sGrains/Messages/Messages.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<LangVersion>11</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.22.0" />
<PackageReference Include="Grpc.Tools" Version="2.51.0" PrivateAssets="All" />
<PackageReference Include="Proto.Cluster.CodeGen" Version="1.0.0-rc3.17" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="Protos.proto" />
</ItemGroup>
<ItemGroup>
<ProtoGrain Include="Protos.proto" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Proto.Cluster\Proto.Cluster.csproj" />
</ItemGroup>

</Project>
12 changes: 12 additions & 0 deletions examples/ClusterK8sGrains/Messages/Protos.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
syntax = "proto3";
package HelloHelloWorld;
option csharp_namespace = "ClusterHelloWorld.Messages";

message HelloRequest {}
message HelloResponse {
string Message=1;
}

service HelloGrain {
rpc SayHello(HelloRequest) returns (HelloResponse) {}
}
27 changes: 27 additions & 0 deletions examples/ClusterK8sGrains/Node1/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["examples/ClusterK8sGrains/Node1/Node1.csproj", "examples/ClusterK8sGrains/Node1/"]
COPY ["examples/ClusterK8sGrains/Node2/Node2.csproj", "examples/ClusterK8sGrains/Node2/"]
COPY ["src/Proto.Cluster.Kubernetes/Proto.Cluster.Kubernetes.csproj", "src/Proto.Cluster.Kubernetes/"]
COPY ["src/Proto.Cluster/Proto.Cluster.csproj", "src/Proto.Cluster/"]
COPY ["src/Proto.Remote/Proto.Remote.csproj", "src/Proto.Remote/"]
COPY ["src/Proto.Actor/Proto.Actor.csproj", "src/Proto.Actor/"]
COPY ["examples/ClusterK8sGrains/Messages/Messages.csproj", "examples/ClusterK8sGrains/Messages/"]
RUN dotnet restore "examples/ClusterK8sGrains/Node1/Node1.csproj"
RUN dotnet restore "examples/ClusterK8sGrains/Node2/Node2.csproj"
COPY . .
WORKDIR "/src/examples/ClusterK8sGrains/Node1"
RUN dotnet build "Node1.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "Node1.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false --no-restore

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Node1.dll"]
22 changes: 22 additions & 0 deletions examples/ClusterK8sGrains/Node1/Node1.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ServerGarbageCollection>true</ServerGarbageCollection>
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>
<LangVersion>10</LangVersion>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<Company>proto.actor example</Company>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Proto.Cluster.Kubernetes\Proto.Cluster.Kubernetes.csproj" />
<ProjectReference Include="..\..\..\src\Proto.Cluster\Proto.Cluster.csproj"/>
<ProjectReference Include="..\..\..\src\Proto.Remote\Proto.Remote.csproj"/>
<ProjectReference Include="..\Messages\Messages.csproj"/>
</ItemGroup>
<ItemGroup>
<Content Include="..\..\..\.dockerignore">
<Link>.dockerignore</Link>
</Content>
</ItemGroup>
</Project>
88 changes: 88 additions & 0 deletions examples/ClusterK8sGrains/Node1/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// -----------------------------------------------------------------------
// <copyright file="Program.cs" company="Asynkron AB">
// Copyright (C) 2015-2022 Asynkron AB All rights reserved
// </copyright>
// -----------------------------------------------------------------------

using System;
using System.Threading;
using System.Threading.Tasks;
using ClusterHelloWorld.Messages;
using Microsoft.Extensions.Logging;
using Proto;
using Proto.Cluster;
using Proto.Cluster.Kubernetes;
using Proto.Cluster.PartitionActivator;
using Proto.Remote;
using Proto.Remote.GrpcNet;
using static Proto.CancellationTokens;
using ProtosReflection = ClusterHelloWorld.Messages.ProtosReflection;
using System.Runtime.Loader;
using Microsoft.Extensions.Configuration;
using Extensions = Proto.Remote.GrpcNet.Extensions;

// Hook SIGTERM to a cancel token to know when k8s is shutting us down
// hostBuilder should be used in production
var cts = new CancellationTokenSource();
AssemblyLoadContext.Default.Unloading += ctx => cts.Cancel();

Log.SetLoggerFactory(
LoggerFactory.Create(l => l.AddConsole(options =>
{
//options.FormatterName = "json"; // Use the JSON formatter
}).SetMinimumLevel(LogLevel.Debug)
.AddFilter("Proto.Cluster.Gossip", LogLevel.Information)
.AddFilter("Proto.Context.ActorContext", LogLevel.Information)));

// Required to allow unencrypted GrpcNet connections
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

var kubernetesProvider = new KubernetesProvider();
var advertisedHost = await kubernetesProvider.GetPodFqdn();

var system = new ActorSystem()
.WithRemote(GrpcNetRemoteConfig
.BindToAllInterfaces(advertisedHost: advertisedHost, port: 4020)
.WithProtoMessages(ProtosReflection.Descriptor))
.WithCluster(ClusterConfig
.Setup("MyCluster",
kubernetesProvider,
new PartitionActivatorLookup())
);

system.EventStream.Subscribe<ClusterTopology>(
e => { Console.WriteLine($"{DateTime.Now:O} My members {e.TopologyHash}"); }
);

await system
.Cluster()
.StartMemberAsync();

Console.WriteLine("Started");

try
{
var helloGrain = system.Cluster().GetHelloGrain("MyGrain");

var res = await helloGrain.SayHello(new HelloRequest(), FromSeconds(15));
Console.WriteLine(res?.Message ?? "RES IS NULL");

res = await helloGrain.SayHello(new HelloRequest(), FromSeconds(5));
Console.WriteLine(res?.Message ?? "RES IS NULL");
}
catch (Exception e)
{
Log.CreateLogger("Program").LogError(e, "Error sending messages");
}

Console.WriteLine("Press CTRL-C to exit");
Console.CancelKeyPress += (_, e) =>
{
e.Cancel = true; // prevent the process from terminating.
cts.Cancel();
};

await Task.Delay(Timeout.Infinite, cts.Token);

Console.WriteLine("Shutting Down...");
await system.Cluster().ShutdownAsync();
27 changes: 27 additions & 0 deletions examples/ClusterK8sGrains/Node2/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["examples/ClusterK8sGrains/Node1/Node1.csproj", "examples/ClusterK8sGrains/Node1/"]
COPY ["examples/ClusterK8sGrains/Node2/Node2.csproj", "examples/ClusterK8sGrains/Node2/"]
COPY ["src/Proto.Cluster.Kubernetes/Proto.Cluster.Kubernetes.csproj", "src/Proto.Cluster.Kubernetes/"]
COPY ["src/Proto.Cluster/Proto.Cluster.csproj", "src/Proto.Cluster/"]
COPY ["src/Proto.Remote/Proto.Remote.csproj", "src/Proto.Remote/"]
COPY ["src/Proto.Actor/Proto.Actor.csproj", "src/Proto.Actor/"]
COPY ["examples/ClusterK8sGrains/Messages/Messages.csproj", "examples/ClusterK8sGrains/Messages/"]
RUN dotnet restore "examples/ClusterK8sGrains/Node1/Node1.csproj"
RUN dotnet restore "examples/ClusterK8sGrains/Node2/Node2.csproj"
COPY . .
WORKDIR "/src/examples/ClusterK8sGrains/Node2"
RUN dotnet build "Node2.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "Node2.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false --no-restore

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Node2.dll"]
22 changes: 22 additions & 0 deletions examples/ClusterK8sGrains/Node2/Node2.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ServerGarbageCollection>true</ServerGarbageCollection>
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>
<LangVersion>11</LangVersion>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<Company>proto.actor example</Company>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Proto.Cluster.Kubernetes\Proto.Cluster.Kubernetes.csproj" />
<ProjectReference Include="..\..\..\src\Proto.Cluster\Proto.Cluster.csproj"/>
<ProjectReference Include="..\..\..\src\Proto.Remote\Proto.Remote.csproj"/>
<ProjectReference Include="..\Messages\Messages.csproj"/>
</ItemGroup>
<ItemGroup>
<Content Include="..\..\..\.dockerignore">
<Link>.dockerignore</Link>
</Content>
</ItemGroup>
</Project>
Loading

0 comments on commit af1a612

Please sign in to comment.