Request for examples for service configurations

I was looking at Ziti Services | OpenZiti and having a little bit of hard time visualizing these patterns in config. Could I request for some service configurations for the 3 patterns - Router HA, Application HA failover, Application HA horizontal scale.

TIA

Hi @av-dev,

We did a couple of ZitiTV episodes on this topic, viewable here:

See also this response here: Best Way for Providing HA Access

It has a lot of the same information, but covers some additional/different facets.

I’ll do a quick post for each of the three, starting with Router HA. This is the simplest, it means we have some client application and it should bind to multiple routers when it is hosting the service.

Looking at the Go SDK as an example, you ca bind a service by calling the ListenWithOptions method on a ziti.Context

	ListenWithOptions(serviceName string, options *ListenOptions) (edge.Listener, error)

The ListenOptions type looks as follows:

type ListenOptions struct {
	Cost                  uint16
	Precedence            Precedence
	ConnectTimeout        time.Duration
	MaxConnections        int
	Identity              string
	BindUsingEdgeIdentity bool
	ManualStart           bool
}

MaxConnections controls the number of terminators we’ll try to create. This will depend on how many edge routers we have access to, which will be determined by some combination of the total number of edge routers and which one we can use, determined by edge router policies.

MaxConnections defaults to 3, but if we only have access to 2 edge routers, then we’ll only try and create 2 terminators. If this number of available edge routers changes, either because of new edge routers coming on-line or because of policy changes, we’ll notice when our session refreshes and we may scale up in response.

So to recap, at least for Go SDK hosted services, each hosting process will try to create a terminator on three different edge routers, causing incoming traffic to be load balanced across those three routers. That number can be affected by the number of running edge routers, edge router policy and configuration in the ListenOptions.

Finally you generally want Router HA for all your hosting services, to avoid single points of failure in the Ziti network. So whether you’ve got a single hosting process or multiple hosting process running either in a failure mode or horizontally scaled mode, you want to make sure that traffic for that service isn’t being bottle-necked at a single router.

Let me know if that makes sense,
Paul

1 Like

Here’s an failover example configuration. There are three basic variations on failover setup, depending on whether you’re using SDK hosted, router/tunneler hosted or standalone tunneler hosted.

If you are SDK hosted, you generally won’t need a config. The application itself can control its precedence (whether it’s the primary, a fallback or has failed), and generally comes with a built in health check (i.e. if the application is disconnected, the terminator is removed and traffic will fail-over).

This config is for router/tunneler hosted:

{
    "terminators" : [
        {
            "address" : "localhost",
            "port" : 1234,
            "protocol" : "tcp",
            "portChecks" : [
                {
                     "address" : "localhost:2234",
                     "interval" : "1s",
                     "timeout" : "100ms",
                     "actions" : [
                         { "trigger" : "fail", "action" : "mark unhealthy" },
                         { "trigger" : "pass", "action" : "mark healthy" }
                     ]
                }
           ],
           "listenOptions" : {
                "precedence" : "required"
           }
        },
        {
            "address" : "localhost",
            "port" : 1235,
            "protocol" : "tcp",
            "portChecks" : [
                {
                     "address" : "localhost:2235",
                     "interval" : "1s",
                     "timeout" : "100ms",
                     "actions" : [
                         { "trigger" : "fail", "action" : "mark unhealthy" },
                         { "trigger" : "pass", "action" : "mark healthy" }
                     ]
                }
           ],
           "listenOptions" : {
                "precedence" : "default"
           }
        }
    ]
}

We have two terminators defined, each going to a different port. One is defined as required, so this is the primary. The other is defined as default, so this will be used if the primary precedence drops to failed. The precedence will be affected by the health checks. As configured when the health check fails the precedence will be set to failed and when it passes the precedence will be set to it’s original value.

This example is from the videos posted above, and is also part of the ziti demo command.

Let me know if you have questions.
Paul

1 Like

Finally, here’s an example for horizontal scale. Again, setup will be different if you’re sdk hosted, router/tunneler hosted or standalone tunneler hosted.

This is again for router/tunneler hosted:

{
    "terminators" : [
        {
            "address" : "localhost",
            "port" : 1234,
            "protocol" : "tcp",
            "portChecks" : [
                {
                     "address" : "localhost:2234",
                     "interval" : "1s",
                     "timeout" : "100ms",
                     "actions" : [
                         { "trigger" : "fail", "action" : "mark unhealthy" },
                         { "trigger" : "pass", "action" : "mark healthy" }
                     ]
                }
           ]
        },
        {
            "address" : "localhost",
            "port" : 1235,
            "protocol" : "tcp",
            "portChecks" : [
                {
                     "address" : "localhost:2235",
                     "interval" : "1s",
                     "timeout" : "100ms",
                     "actions" : [
                         { "trigger" : "fail", "action" : "mark unhealthy" },
                         { "trigger" : "pass", "action" : "mark healthy" }
                     ]
                }
           ]
        }
    ]
}

It’s looks almost exactly the same as the failover setup, the only difference being that everything is at the same precedence instead of one at required and one at default.

Cheers,
Paul

1 Like

Thank you @plorenz Really appreciate the detailed information.