<p>I think you are conflating a few concepts here, let me try to separate them in your mind.</p>
<p>First, separate availability of the platform, from the availability of your applications:</p>
<p>Nomad, like many other distributed systems, uses the <a href="https://developer.hashicorp.com/nomad/docs/concepts/consensus" rel="nofollow noreferrer">raft consensus algorithm</a> to determine who is the leader of the server cluster. This is different to older high-availability strategies which provide multiple endpoints served by a load balancer for example.</p>
<p>If you have two servers, it's impossible to elect a leader since none of the servers has a winning vote. For this reason, there is zero fault tolerance with two servers -- see <a href="https://developer.hashicorp.com/nomad/docs/concepts/consensus#deployment-table" rel="nofollow noreferrer">https://developer.hashicorp.com/nomad/docs/concepts/consensus#deployment-table</a>. If the active server goes down, requests cannot be processed.</p>
<p>So, if you want <strong>fault tolerance</strong>, put another Nomad server in the cluster, and bring it to 3. Else having 1 or 2 servers won't increase fault tolerance. The state is replicated across servers, so you be able to perform read actions, but you won't be able  to change the state until a quorum is re-established and a new leader is elected.</p>
<hr />
<p>Now, for you application:</p>
<p>You have Nomad clients defined on two machines, which means that you can submit jobs with <em>services</em> and <em>tasks</em> to those resources.</p>
<blockquote>
<p>What we'd like to do is have our services installed on both the servers but only run these services on failover when the main server goes down.</p>
</blockquote>
<p>What you are looking for here is the <code>migrate</code> stanza of the job - when Nomad determines that a node on which a job is running has failed, it (Nomad server) will migrate the job to a node which is up. However, as discussed before, if the <em>server</em> is unavailable because it has lost consensus, this won't be possible... So either you have an extremely reliable single machine running Nomad server, or you have a fault-tolerant 3-node cluster running Nomad server, with unreliable clients.</p>
<p>In terms of your VAService and client jobs -- you should write a Nomad job description which defines these tasks. They can expose services and Nomad's service discovery will connect them, so that they can run on different machines, <em>etc</em>.</p>
<blockquote>
<p>We don't want these services to be running on failover server when the main server is up since it will cause streams to be processed twice i.e produce duplicate events.</p>
</blockquote>
<p>Nomad is the orchestrator, therefore it determines where to place the job. Unless you have a <code>count</code> in the group which the task is running in greater than 1 (ie, more than one instance of the application placed in a group), then Nomad will schedule only one instance of it and you won't have to worry about double-processing streams. In terms of availability , you should choose a different strategy than the traditional HA passive-active :</p>
<ul>
<li><a href="https://developer.hashicorp.com/nomad/docs/job-specification/reschedule" rel="nofollow noreferrer"><code>reschedule</code></a> -- reschedule the group or job if a task fails or dies</li>
<li><a href="https://developer.hashicorp.com/nomad/docs/job-specification/restart" rel="nofollow noreferrer"><code>restart</code></a> -- similar to reschedule, but just restarting in place -- see also <a href="https://developer.hashicorp.com/nomad/docs/job-specification/check_restart" rel="nofollow noreferrer"><code>check_restart</code></a></li>
<li><a href="https://developer.hashicorp.com/nomad/docs/job-specification/migrate" rel="nofollow noreferrer"><code>migrate</code></a> -- move the job to a different node if the client is marked for draining</li>
</ul>
<p>These are definitions of how Nomad should treat failures in the operational lifecycle of the application.</p>
<hr />
<p>Take a scenario where you have one server and clients enabled on it and the other machine. You write a Nomad job description with:</p>
<ol>
<li>2 groups -- one for the server, one for the client</li>
<li>each group has a <code>reschedule</code>, <code>restart</code> and <code>check_restart</code> stanza to deal with failures.</li>
</ol>
<p>You deploy this job description to Nomad. The <em>application server</em> group gets placed on the same node where the Nomad server is running and the application client gets placed on the other machine. Everything works fine.</p>
<p>Now:</p>
<p>Failure scenario 1: the machine running only the client dies</p>
<ul>
<li>Nomad will reschedule see that the node is down and reschedule the group on the remaining machine.</li>
<li>you have resilience, but there is a disruption in availability.</li>
</ul>
<p>Failure scenario 2: the machine running the Nomad server dies</p>
<ul>
<li>Nomad cannot reschedule the job because quorum has been lost</li>
<li>Application server is lost, but application client keeps running</li>
</ul>
<p>Clearly neither of these is a good situation, so:</p>
<p>I would go with a resilience scenario such as: Use Nomad servers in a different failure domain to the Nomad clients.</p>
<p>If you are able to add a third node to the cluster, you will have fault tolerance at the cluster level. By using the built-in mechanisms of Nomad for rescheduling, restarting, <em>etc</em> job as discussed above, you will have a resilient application. You cannot eliminate downtime however without changing the application itself, either by making the server idempotent (ie, multiple processing requests against the same event do not change the event result), or by including some mechanism for the server itself to elect a leader of that tier of the application. There are several approaches here, but I think they'd fall outside of the scope of the question.</p>
<p>Finally, I would suggest opening this topic at the <a href="https://discuss.hashicorp.com/c/nomad/28" rel="nofollow noreferrer">Hashicorp discussion forum</a> so that you can get some deeper context and better feedback :)</p>

CC BY-SA 4.0
2023-05-04T10:08:23.153Z
2023-05-04T10:08:23.153Z
Bruce Becker
<p>I am just learning about orchestrators and it's my first time using any orchestrator (<code>Nomad</code> in this case).</p>
<p>Our software (video stream processing related) is installed on user premises, currently we have been using <code>docker compose</code> to deploy our software (bunch of services as docker container).</p>
<p>Now we have a client who needs failover and has provided us two physical server, one is to be used as a main server and other as failover. What we'd like to do is have our services installed on both the servers but only run these services on failover when the main server goes down.</p>
<p>We won't like to make any changes to our code. we have one services which process the video streams and raise events (<code>VA service</code>) and another service which handles database, users, events etc. (<code>Client Service</code>). The <code>client service</code> knows about this <code>VA service</code> and it assigns work to it. <em>We don't want these services to be running on failover server when the main server is up since it will cause streams to be processed twice i.e produce duplicate events.</em></p>
<p>We are configuring our database in master-master mode so that data is available on failover when main fails ( trying it on postgres (current database), had previously done it on Mysql ).</p>
<p>I have set up nomad on both machines with nomad server and client both on each machine and tried configuring them such that if the machine with nomad leader server and its client shuts down, nomad server on failover should take charge and run tasks on its client, but i am unable to achieve this. If i shutdown the main server nothing happens on failover machine.</p>
<pre><code># Leader config file
datacenter = &quot;dc1&quot;
data_dir   = &quot;/opt/nomad/data&quot;
bind_addr  = &quot;192.168.1.38&quot;
name = &quot;server1&quot;

server {
  enabled          = true
  bootstrap_expect = 2
  server_join {
    retry_join = [
      &quot;192.168.1.38&quot;,
      &quot;192.168.1.20&quot;,
    ]
    retry_max      = 0
    retry_interval = &quot;15s&quot;
  }
}

client {
  enabled = true
  servers = [
    &quot;192.168.1.38&quot;,
    &quot;192.168.1.20&quot;,
  ]
}


# Follower config file
datacenter = &quot;dc1&quot;
data_dir   = &quot;/opt/nomad/data&quot;
bind_addr  = &quot;192.168.1.20&quot;
name = &quot;server2&quot;

server {
  enabled          = true
  bootstrap_expect = 2
  server_join {
    retry_join = [
      &quot;192.168.1.38&quot;,
      &quot;192.168.1.20&quot;,
    ]
    retry_max      = 0
    retry_interval = &quot;15s&quot;
  }
}

client {
  enabled = true
  servers = [
    &quot;192.168.1.38&quot;,
    &quot;192.168.1.20&quot;,
  ]
}

</code></pre>
<ol>
<li>Is nomad even the right tool for this situation ?</li>
<li>How can i achieve what i am trying using nomad ?</li>
</ol>

<orchestration>
Two server failover in nomad
Pawan
# Two server failover in nomad

(Asked by: username_0 on 2023-04-27)

I am just learning about orchestrators and it's my first time using any orchestrator (Nomad in this case).
Our software (video stream processing related) is installed on user premises, currently we have been using docker compose to deploy our software (bunch of services as docker container).
Now we have a client who needs failover and has provided us two physical server, one is to be used as a main server and other as failover. What we'd like to do is have our services installed on both the servers but only run these services on failover when the main server goes down.
We won't like to make any changes to our code. we have one services which process the video streams and raise events (VA service) and another service which handles database, users, events etc. (Client Service). The client service knows about this VA service and it assigns work to it. We don't want these services to be running on failover server when the main server is up since it will cause streams to be processed twice i.e produce duplicate events.
We are configuring our database in master-master mode so that data is available on failover when main fails ( trying it on postgres (current database), had previously done it on Mysql ).
I have set up nomad on both machines with nomad server and client both on each machine and tried configuring them such that if the machine with nomad leader server and its client shuts down, nomad server on failover should take charge and run tasks on its client, but i am unable to achieve this. If i shutdown the main server nothing happens on failover machine.
# Leader config file
datacenter = "dc1"
data_dir   = "/opt/nomad/data"
bind_addr  = "192.168.1.38"
name = "server1"

server {
  enabled          = true
  bootstrap_expect = 2
  server_join {
    retry_join = [
      "192.168.1.38",
      "192.168.1.20",
    ]
    retry_max      = 0
    retry_interval = "15s"
  }
}

client {
  enabled = true
  servers = [
    "192.168.1.38",
    "192.168.1.20",
  ]
}


# Follower config file
datacenter = "dc1"
data_dir   = "/opt/nomad/data"
bind_addr  = "192.168.1.20"
name = "server2"

server {
  enabled          = true
  bootstrap_expect = 2
  server_join {
    retry_join = [
      "192.168.1.38",
      "192.168.1.20",
    ]
    retry_max      = 0
    retry_interval = "15s"
  }
}

client {
  enabled = true
  servers = [
    "192.168.1.38",
    "192.168.1.20",
  ]
}



Is nomad even the right tool for this situation ?
How can i achieve what i am trying using nomad ?

**Tags:** orchestration


---

## 1 answers

### Answer by username_1 on 2023-05-04. Score: 2

I think you are conflating a few concepts here, let me try to separate them in your mind.

First, separate availability of the platform, from the availability of your applications:

Nomad, like many other distributed systems, uses the [raft consensus algorithm](https://developer.hashicorp.com/nomad/docs/concepts/consensus) to determine who is the leader of the server cluster. This is different to older high-availability strategies which provide multiple endpoints served by a load balancer for example.

If you have two servers, it's impossible to elect a leader since none of the servers has a winning vote. For this reason, there is zero fault tolerance with two servers -- see <https://developer.hashicorp.com/nomad/docs/concepts/consensus#deployment-table>. If the active server goes down, requests cannot be processed.

So, if you want **fault tolerance**, put another Nomad server in the cluster, and bring it to 3. Else having 1 or 2 servers won't increase fault tolerance. The state is replicated across servers, so you be able to perform read actions, but you won't be able to change the state until a quorum is re-established and a new leader is elected.

---

Now, for you application:

You have Nomad clients defined on two machines, which means that you can submit jobs with *services* and *tasks* to those resources.

> What we'd like to do is have our services installed on both the servers but only run these services on failover when the main server goes down.

What you are looking for here is the `migrate` stanza of the job - when Nomad determines that a node on which a job is running has failed, it (Nomad server) will migrate the job to a node which is up. However, as discussed before, if the *server* is unavailable because it has lost consensus, this won't be possible... So either you have an extremely reliable single machine running Nomad server, or you have a fault-tolerant 3-node cluster running Nomad server, with unreliable clients.

In terms of your VAService and client jobs -- you should write a Nomad job description which defines these tasks. They can expose services and Nomad's service discovery will connect them, so that they can run on different machines, *etc*.

> We don't want these services to be running on failover server when the main server is up since it will cause streams to be processed twice i.e produce duplicate events.

Nomad is the orchestrator, therefore it determines where to place the job. Unless you have a `count` in the group which the task is running in greater than 1 (ie, more than one instance of the application placed in a group), then Nomad will schedule only one instance of it and you won't have to worry about double-processing streams. In terms of availability , you should choose a different strategy than the traditional HA passive-active :

* [`reschedule`](https://developer.hashicorp.com/nomad/docs/job-specification/reschedule) -- reschedule the group or job if a task fails or dies
* [`restart`](https://developer.hashicorp.com/nomad/docs/job-specification/restart) -- similar to reschedule, but just restarting in place -- see also [`check_restart`](https://developer.hashicorp.com/nomad/docs/job-specification/check_restart)
* [`migrate`](https://developer.hashicorp.com/nomad/docs/job-specification/migrate) -- move the job to a different node if the client is marked for draining

These are definitions of how Nomad should treat failures in the operational lifecycle of the application.

---

Take a scenario where you have one server and clients enabled on it and the other machine. You write a Nomad job description with:

1. 2 groups -- one for the server, one for the client
2. each group has a `reschedule`, `restart` and `check_restart` stanza to deal with failures.

You deploy this job description to Nomad. The *application server* group gets placed on the same node where the Nomad server is running and the application client gets placed on the other machine. Everything works fine.

Now:

Failure scenario 1: the machine running only the client dies

* Nomad will reschedule see that the node is down and reschedule the group on the remaining machine.
* you have resilience, but there is a disruption in availability.

Failure scenario 2: the machine running the Nomad server dies

* Nomad cannot reschedule the job because quorum has been lost
* Application server is lost, but application client keeps running

Clearly neither of these is a good situation, so:

I would go with a resilience scenario such as: Use Nomad servers in a different failure domain to the Nomad clients.

If you are able to add a third node to the cluster, you will have fault tolerance at the cluster level. By using the built-in mechanisms of Nomad for rescheduling, restarting, *etc* job as discussed above, you will have a resilient application. You cannot eliminate downtime however without changing the application itself, either by making the server idempotent (ie, multiple processing requests against the same event do not change the event result), or by including some mechanism for the server itself to elect a leader of that tier of the application. There are several approaches here, but I think they'd fall outside of the scope of the question.

Finally, I would suggest opening this topic at the [Hashicorp discussion forum](https://discuss.hashicorp.com/c/nomad/28) so that you can get some deeper context and better feedback :)


---

