Open orcnz opened 1 year ago
I do have a workaround in place, however I am not sure this is how silo ports are (should be) handled in a more dynamic scale in/out environment like a working cluster.
The workaround I have involves passing a unique gateway port in to each silo container via environment variables, and also setting a passthrough port mapping in the docker-compose.yml file.
The docker-compose.yml file now looks like this:
version: "3.8"
services:
redis:
image: redis:7.0
ports:
- "6379:6379"
silo1:
build: .
ports:
- "8080:8080"
- "30000:30000"
environment:
- Redis:ConnectionString=redis:6379
- Orleans:GatewayPort=30000
depends_on:
- redis
silo2:
build: .
ports:
- "8081:8080"
- "30001:30001"
environment:
- Redis:ConnectionString=redis:6379
- Orleans:GatewayPort=30001
depends_on:
- redis
silo3:
build: .
ports:
- "8082:8080"
- "30002:30002"
environment:
- Redis:ConnectionString=redis:6379
- Orleans:GatewayPort=30002
depends_on:
- redis
(note the gateway port mappings for all the silos are passthrough i.e. "30000:30000"
, "30001:30001"
and "30002:30002"
and the ports are static and passed in via the environment
section.)
The server code now looks like this:
using Orleans.Configuration;
await Host.CreateDefaultBuilder(args)
.UseOrleans((context, silo) =>
{
silo.UseRedisClustering(context.Configuration["Redis:ConnectionString"] ?? "localhost")
.UseDashboard()
.Configure<EndpointOptions>(options =>
{
options.GatewayPort = int.Parse(context.Configuration["Orleans:GatewayPort"] ?? "30000");
})
.ConfigureLogging(logger => logger.AddConsole());
})
.RunConsoleAsync();
And now I can connect the client application using all three silos:
var host = Host.CreateDefaultBuilder(args)
.UseOrleansClient(client =>
{
client.UseStaticClustering(
new IPEndPoint(IPAddress.Loopback, 30000),
new IPEndPoint(IPAddress.Loopback, 30001),
new IPEndPoint(IPAddress.Loopback, 30002));
})
.ConfigureLogging(logging => logging.AddConsole())
.Build();
Is there a better way to do this that doesn't involve having to set different configuration for each silo?
I have a sample repository that I am working with to understand how Orleans clusters behave, using docker compose to experiment locally. However, I am unable to successfully use docker's port mapping to allow my client application to connect to all of the silo containers in the cluster. It might be that my mental model of how this works is not correct, or some quirk of the configuration/setup.
I am using docker compose to start a Redis container and three Orleans Silo containers.
I am expecting to be able to leave the default ports configured in the containers and use dockers port mapping to map a unique port to the default gateway port in each silo container. However this is not currently working in this sample.
Some more details:
The
docker-compose.yml
file(note the internal ports on all three silo containers are the same, only the external ports are different)
The server code
The client code (snip)
I am able to connect the client application to the silo cluster, but only
silo1
on the exposed port30000
.If I try and connect the client to
silo2
on the exposed port30001
that maps to port30000
in the container, I get the following errors on the client:And on the server I see this errors:
What am I missing? Why does the docker port mapping appear not to be working for the gateway ports? It is working in the same file for the Orleans dashboard that I am exposing on each silo container, ports
8080
forsilo1
,8081
forsilo2
and8082
forsilo3
.