mirror of https://github.com/hashicorp/consul
docs: Backport for DNS Forwarding/Application leader election docs (#21673)
* CE-655 - Moving DNS forwading tutorial to docs (#21348) * First commit * Add page to navigation * test new doc page * Update website/content/docs/services/discovery/dns-forwarding.mdx * Update website/content/docs/services/discovery/dns-forwarding.mdx * fix push build atttempt * Draft * Draft * empty line * Draft * empty lines * Draft * First draft * Create documentation for Argo Rollouts Plugin. (#20680) * Create documentation for Argo Rollouts Plugin. * Create documentation for Argo Rollouts Plugin. * Apply suggestions from code review Co-authored-by: David Yu <dyu@hashicorp.com> * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update docs based on feedback * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/k8s/deployment-configurations/argo-rollouts-configuration.mdx * Update website/content/docs/k8s/deployment-configurations/argo-rollouts-configuration.mdx --------- Co-authored-by: David Yu <dyu@hashicorp.com> Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Co-authored-by: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> * Split content and add images * Fix navigation * Add links and context * Restructure changes * Fix enable documentation * Fix enable documentation * Fix index documentation * Add troubleshooting and fix codeblocks * Add troubleshooting and fix codeblocks * Typos and last checks * Apply suggestions from code review Co-authored-by: Aimee Ukasick <aimee.ukasick@hashicorp.com> * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Update website/content/docs/services/discovery/dns-forwarding/enable.mdx * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Add dark mode images * Add dark mode images * Apply suggestions from code review --------- Co-authored-by: boruszak <jeffrey.boruszak@hashicorp.com> Co-authored-by: Ashwin Venkatesh <ashwin@hashicorp.com> Co-authored-by: David Yu <dyu@hashicorp.com> Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Co-authored-by: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Co-authored-by: Aimee Ukasick <aimee.ukasick@hashicorp.com> * CE-657 - Move Application leader election tutorial to docs (#21366) * First commit * Fix navigation * Add some commands * Structure draft * Complete usage doc structure * Fix link * Apply suggestions from code review Co-authored-by: Aimee Ukasick <aimee.ukasick@hashicorp.com> * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> * Apply suggestions from code review * Replace tutorial path * Apply suggestions from code review Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> --------- Co-authored-by: Aimee Ukasick <aimee.ukasick@hashicorp.com> Co-authored-by: Jeff Boruszak <104028618+boruszak@users.noreply.github.com> Co-authored-by: boruszak <jeffrey.boruszak@hashicorp.com> --------- Co-authored-by: danielehc <40759828+danielehc@users.noreply.github.com> Co-authored-by: Ashwin Venkatesh <ashwin@hashicorp.com> Co-authored-by: David Yu <dyu@hashicorp.com> Co-authored-by: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Co-authored-by: Aimee Ukasick <aimee.ukasick@hashicorp.com>pull/21679/head
parent
7eb7305c63
commit
d2319be85e
|
@ -212,7 +212,7 @@ The corresponding CLI command is [`consul kv put`](/consul/commands/kv/put).
|
||||||
session has locked the key.**
|
session has locked the key.**
|
||||||
|
|
||||||
For an example of how to use the lock feature, check the
|
For an example of how to use the lock feature, check the
|
||||||
[Leader Election tutorial](/consul/tutorials/developer-configuration/application-leader-elections).
|
[Leader Election tutorial](/consul/docs/dynamic-app-config/sessions/application-leader-election).
|
||||||
|
|
||||||
- `release` `(string: "")` - Supply a session ID to use in a release operation. This is
|
- `release` `(string: "")` - Supply a session ID to use in a release operation. This is
|
||||||
useful when paired with `?acquire=` as it allows clients to yield a lock. This
|
useful when paired with `?acquire=` as it allows clients to yield a lock. This
|
||||||
|
|
|
@ -77,7 +77,7 @@ The table below shows this endpoint's support for
|
||||||
86400s). If provided, the session is invalidated if it is not renewed before
|
86400s). If provided, the session is invalidated if it is not renewed before
|
||||||
the TTL expires. The lowest practical TTL should be used to keep the number of
|
the TTL expires. The lowest practical TTL should be used to keep the number of
|
||||||
managed sessions low. When locks are forcibly expired, such as when following
|
managed sessions low. When locks are forcibly expired, such as when following
|
||||||
the [leader election pattern](/consul/tutorials/developer-configuration/application-leader-elections) in an application,
|
the [leader election pattern](/consul/docs/dynamic-app-config/sessions/application-leader-election) in an application,
|
||||||
sessions may not be reaped for up to double this TTL, so long TTL
|
sessions may not be reaped for up to double this TTL, so long TTL
|
||||||
values (> 1 hour) should be avoided. Valid time units include "s", "m" and "h".
|
values (> 1 hour) should be avoided. Valid time units include "s", "m" and "h".
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ communication is disrupted, the child process is terminated.
|
||||||
|
|
||||||
The number of lock holders is configurable with the `-n` flag. By default,
|
The number of lock holders is configurable with the `-n` flag. By default,
|
||||||
a single holder is allowed, and a lock is used for mutual exclusion. This
|
a single holder is allowed, and a lock is used for mutual exclusion. This
|
||||||
uses the [leader election algorithm](/consul/tutorials/developer-configuration/application-leader-elections).
|
uses the [leader election algorithm](/consul/docs/dynamic-app-config/sessions/application-leader-election).
|
||||||
|
|
||||||
If the lock holder count is more than one, then a semaphore is used instead.
|
If the lock holder count is more than one, then a semaphore is used instead.
|
||||||
A semaphore allows more than a single holder, but this is less efficient than
|
A semaphore allows more than a single holder, but this is less efficient than
|
||||||
|
|
|
@ -111,7 +111,7 @@ increment to the `LockIndex` and the session value is updated to reflect the
|
||||||
session holding the lock. Review the session documentation for more information
|
session holding the lock. Review the session documentation for more information
|
||||||
on the [integration](/consul/docs/dynamic-app-config/sessions#k-v-integration).
|
on the [integration](/consul/docs/dynamic-app-config/sessions#k-v-integration).
|
||||||
|
|
||||||
Review the following tutorials to learn how to use Consul sessions for [application leader election](/consul/tutorials/developer-configuration/application-leader-elections) and
|
Review the following tutorials to learn how to use Consul sessions for [application leader election](/consul/docs/dynamic-app-config/sessions/application-leader-election) and
|
||||||
to [build distributed semaphores](/consul/tutorials/developer-configuration/distributed-semaphore).
|
to [build distributed semaphores](/consul/tutorials/developer-configuration/distributed-semaphore).
|
||||||
|
|
||||||
### Vault
|
### Vault
|
||||||
|
|
|
@ -0,0 +1,396 @@
|
||||||
|
---
|
||||||
|
layout: docs
|
||||||
|
page_title: Application leader election
|
||||||
|
description: >-
|
||||||
|
Learn how to perform client-side leader elections using sessions and Consul key/value (KV) store.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Application leader election
|
||||||
|
|
||||||
|
This topic describes the process for building client-side leader elections for service instances using Consul's [session mechanism for building distributed locks](/consul/docs/dynamic-app-config/sessions) and the [Consul key/value store](/consul/docs/dynamic-app-config/kv), which is Consul's key/value datastore.
|
||||||
|
|
||||||
|
This topic is not related to Consul's leader election. For more information about the Raft leader election used internally by Consul, refer to
|
||||||
|
[consensus protocol](/consul/docs/architecture/consensus) documentation.
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
Some distributed applications, like HDFS or ActiveMQ, require setting up one instance as a leader to ensure application data is current and stable.
|
||||||
|
|
||||||
|
Consul's support for [sessions](/consul/docs/dynamic-app-config/sessions) and [watches](/consul/docs/dynamic-app-config/watches) allows you to build a client-side leader election process where clients use a lock on a key in the KV datastore to ensure mutual exclusion and to gracefully handle failures.
|
||||||
|
|
||||||
|
All service instances that are participating should coordinate on a key format. We recommend the following pattern:
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
service/<service name>/leader
|
||||||
|
```
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- A running Consul server
|
||||||
|
- A path in the Consul KV datastore to acquire locks and to store information about the leader. The instructions on this page use the following key: `service/leader`.
|
||||||
|
- If ACLs are enabled, a token with the following permissions:
|
||||||
|
- `session:write` permissions over the service session name
|
||||||
|
- `key:write` permissions over the key
|
||||||
|
- The `curl` command
|
||||||
|
|
||||||
|
Expose the token using the `CONSUL_HTTP_TOKEN` environment variable.
|
||||||
|
|
||||||
|
## Client-side leader election procedure
|
||||||
|
|
||||||
|
The workflow for building a client-side leader election process has the following steps:
|
||||||
|
|
||||||
|
- For each client trying to acquire the lock:
|
||||||
|
1. [Create a session](#create-a-new-session) associated with the client node.
|
||||||
|
1. [Acquire the lock](#acquire-the-lock) on the designated key in the KV store using the `acquire` parameter.
|
||||||
|
1. [Watch the KV key](#watch-the-kv-key-for-locks) to verify if the lock was released. If no lock is present, try to acquire a lock.
|
||||||
|
|
||||||
|
- For the client that acquires the lock:
|
||||||
|
1. Periodically, [renew the session](#renew-a-session) to avoid expiration.
|
||||||
|
1. Optionally, [release the lock](#release-a-lock).
|
||||||
|
|
||||||
|
- For other services:
|
||||||
|
1. [Watch the KV key](#watch-the-kv-key-for-locks) to verify there is at least one process holding the lock.
|
||||||
|
1. Use the values written under the KV path to identify the leader and update configurations accordingly.
|
||||||
|
|
||||||
|
## Create a new session
|
||||||
|
|
||||||
|
Create a configuration for the session.
|
||||||
|
The minimum viable configuration requires that you specify the session name. The following example demonstrates this configuration.
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Name": "session_name"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
Create a session using the [`/session` Consul HTTP API](/consul/api-docs/session) endpoint. In the following example, the node's `hostname` is the session name.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ curl --silent \
|
||||||
|
--header "X-Consul-Token: $CONSUL_HTTP_TOKEN" \
|
||||||
|
--data '{"Name": "'`hostname`'"}' \
|
||||||
|
--request PUT \
|
||||||
|
http://127.0.0.1:8500/v1/session/create | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
The command returns a JSON object containing the ID of the newly created session.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ID": "d21d60ad-c2d2-b32a-7432-ca4048a4a7d6"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verify session
|
||||||
|
|
||||||
|
Use the `/v1/session/list` endpoint to retrieve existing sessions.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ curl --silent \
|
||||||
|
--header "X-Consul-Token: $CONSUL_HTTP_TOKEN" \
|
||||||
|
--request GET \
|
||||||
|
http://127.0.0.1:8500/v1/session/list | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
The command returns a JSON array containing all available sessions in the system.
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard>
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"ID": "d21d60ad-c2d2-b32a-7432-ca4048a4a7d6",
|
||||||
|
"Name": "hashicups-db-0",
|
||||||
|
"Node": "hashicups-db-0",
|
||||||
|
"LockDelay": 15000000000,
|
||||||
|
"Behavior": "release",
|
||||||
|
"TTL": "",
|
||||||
|
"NodeChecks": [
|
||||||
|
"serfHealth"
|
||||||
|
],
|
||||||
|
"ServiceChecks": null,
|
||||||
|
"CreateIndex": 11956,
|
||||||
|
"ModifyIndex": 11956
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
You can verify from the output that the session is associated with the `hashicups-db-0` node, which is the client agent where the API request was made.
|
||||||
|
|
||||||
|
With the exception of the `Name`, all parameters are set to their default values. The session is created without a `TTL` value, which means that it never expires and requires you to delete it explicitly.
|
||||||
|
|
||||||
|
Depending on your needs you can create sessions specifying more parameters such as:
|
||||||
|
|
||||||
|
- `TTL` - If provided, the session is invalidated and deleted if it is not renewed before the TTL expires.
|
||||||
|
- `ServiceChecks` - Specifies a list of service checks to monitor. The session is invalidated if the checks return a critical state.
|
||||||
|
|
||||||
|
By setting these extra parameters, you can create a client-side leader election workflow that automatically releases the lock after a specified amount of time since the last renew, or that automatically releases locks when the service holding them fails.
|
||||||
|
|
||||||
|
For a full list of parameters available refer to the [`/session/create` endpoint documentation](/consul/api-docs/session#create-session).
|
||||||
|
|
||||||
|
## Acquire the lock
|
||||||
|
|
||||||
|
Create the data object to associate to the lock request.
|
||||||
|
|
||||||
|
The data of the request should be a JSON object representing the local instance. This value is opaque to Consul, but it should contain whatever information clients require to communicate with your application. For example, it could be a JSON object that contains the node's name and the application's port.
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Node": "node-name",
|
||||||
|
"Port": "8080"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
<Tab heading="API" group="api">
|
||||||
|
|
||||||
|
Acquire a lock for a given key using the PUT method on a [KV entry](/consul/api-docs/kv) with the
|
||||||
|
`?acquire=<session>` query parameter.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ curl --silent \
|
||||||
|
--header "X-Consul-Token: $CONSUL_HTTP_TOKEN" \
|
||||||
|
--data '{"Node": "'`hostname`'"}' \
|
||||||
|
--request PUT \
|
||||||
|
http://localhost:8500/v1/kv/service/leader?acquire=d21d60ad-c2d2-b32a-7432-ca4048a4a7d6 | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
This request returns either `true` or `false`. If `true`, the lock was acquired and
|
||||||
|
the local service instance is now the leader. If `false`, a different node acquired
|
||||||
|
the lock.
|
||||||
|
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
<Tab heading="CLI" group="cli">
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ consul kv put -acquire -session=d21d60ad-c2d2-b32a-7432-ca4048a4a7d6 /service/leader '{"Node": "'`hostname`'"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
In case of success, the command exits with exit code `0` and outputs the following message.
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard>
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
Success! Lock acquired on: service/leader
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
If the lock was already acquired by another node, the command exits with exit code `1` and outputs the following message.
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard>
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
Error! Did not acquire lock
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
This example used the node's `hostname` as the key data. This data can be used by the other services to create configuration files.
|
||||||
|
|
||||||
|
Be aware that this locking system has no enforcement mechanism that requires clients to acquire a lock before they perform an operation. Any client can read, write, and delete a key without owning the corresponding lock.
|
||||||
|
|
||||||
|
## Watch the KV key for locks
|
||||||
|
|
||||||
|
Existing locks need to be monitored by all nodes involved in the client-side leader elections, as well as by the other nodes that need to know the identity of the leader.
|
||||||
|
|
||||||
|
- Lock holders need to monitor the lock because the session might get invalidated by an operator.
|
||||||
|
- Other services that want to acquire the lock need to monitor it to check if the lock is released so they can try acquire the lock.
|
||||||
|
- Other nodes need to monitor the lock to see if the value of the key changed and update their configuration accordingly.
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
<Tab heading="API" group="api">
|
||||||
|
|
||||||
|
Monitor the lock using the GET method on a [KV entry](/consul/api-docs/kv) with the blocking query enabled.
|
||||||
|
|
||||||
|
First, verify the latest index for the current value.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ curl --silent \
|
||||||
|
--header "X-Consul-Token: $CONSUL_HTTP_TOKEN" \
|
||||||
|
--request GET \
|
||||||
|
http://127.0.0.1:8500/v1/kv/service/leader?index=1 | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
The command outputs the key data, including the `ModifyIndex` for the object.
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard highlight="9">
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"LockIndex": 0,
|
||||||
|
"Key": "service/leader",
|
||||||
|
"Flags": 0,
|
||||||
|
"Value": "eyJOb2RlIjogImhhc2hpY3Vwcy1kYi0wIn0=",
|
||||||
|
"Session": "d21d60ad-c2d2-b32a-7432-ca4048a4a7d6",
|
||||||
|
"CreateIndex": 12399,
|
||||||
|
"ModifyIndex": 13061
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
Using the value of the `ModifyIndex`, run a [blocking query](/consul/api-docs/features/blocking) against the lock.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ curl --silent \
|
||||||
|
--header "X-Consul-Token: $CONSUL_HTTP_TOKEN" \
|
||||||
|
--request GET \
|
||||||
|
http://127.0.0.1:8500/v1/kv/service/leader?index=13061 | jq
|
||||||
|
```
|
||||||
|
The command hangs until a change is made on the KV path and after that the path data prints on the console.
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard highlight="9">
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"LockIndex": 0,
|
||||||
|
"Key": "service/leader",
|
||||||
|
"Flags": 0,
|
||||||
|
"Value": "eyJOb2RlIjogImhhc2hpY3Vwcy1kYi0xIn0=",
|
||||||
|
"Session": "d21d60ad-c2d2-b32a-7432-ca4048a4a7d6",
|
||||||
|
"CreateIndex": 12399,
|
||||||
|
"ModifyIndex": 13329
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
For automation purposes, add logic to the blocking query mechanism to trigger a command every time a change is returned.
|
||||||
|
A better approach is to use the CLI command `consul watch`.
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
<Tab heading="CLI" group="cli">
|
||||||
|
|
||||||
|
Monitor the lock using the [`consul watch`](/consul/commands/watch) command.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ consul watch -type=key -key=service/leader cat | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example, the command output prints to the shell. However, it is possible to pass more complex option to the command as well as a script that contains more complex logic to react to the lock data change.
|
||||||
|
|
||||||
|
An example output for the command is:
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Key": "service/leader",
|
||||||
|
"CreateIndex": 12399,
|
||||||
|
"ModifyIndex": 13061,
|
||||||
|
"LockIndex": 0,
|
||||||
|
"Flags": 0,
|
||||||
|
"Value": "eyJOb2RlIjogImhhc2hpY3Vwcy1kYi0wIn0=",
|
||||||
|
"Session": "d21d60ad-c2d2-b32a-7432-ca4048a4a7d6"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
The `consul watch` command polls the KV path for changes and runs the specified command on the output when a change is made.
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
From the output, notice that once the lock is acquired, the `Session` parameter contains the ID of the session that holds the lock.
|
||||||
|
|
||||||
|
## Renew a session
|
||||||
|
|
||||||
|
If a session is created with a `TTL` value set, you need to renew the session before the TTL expires.
|
||||||
|
|
||||||
|
Use the [`/v1/session/renew`](/consul/api-docs/session#renew-session) endpoint to renew existing sessions.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ curl --silent \
|
||||||
|
--header "X-Consul-Token: $CONSUL_HTTP_TOKEN" \
|
||||||
|
--request PUT \
|
||||||
|
http://127.0.0.1:8500/v1/session/renew/f027470f-2759-6b53-542d-066ae4185e67 | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
If the command succeeds, the session information in JSON format is printed.
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard>
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"ID": "f027470f-2759-6b53-542d-066ae4185e67",
|
||||||
|
"Name": "test",
|
||||||
|
"Node": "consul-server-0",
|
||||||
|
"LockDelay": 15000000000,
|
||||||
|
"Behavior": "release",
|
||||||
|
"TTL": "30s",
|
||||||
|
"NodeChecks": [
|
||||||
|
"serfHealth"
|
||||||
|
],
|
||||||
|
"ServiceChecks": null,
|
||||||
|
"CreateIndex": 11842,
|
||||||
|
"ModifyIndex": 11842
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
## Release a lock
|
||||||
|
|
||||||
|
A lock associated with a session with no `TTL` value set might never be released, even when the service holding it fails.
|
||||||
|
|
||||||
|
In such cases, you need to manually release the lock.
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
<Tab heading="API" group="api">
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ curl --silent \
|
||||||
|
--header "X-Consul-Token: $CONSUL_HTTP_TOKEN" \
|
||||||
|
--data '{"Node": "'`hostname`'"}' \
|
||||||
|
--request PUT \
|
||||||
|
http://localhost:8500/v1/kv/service/leader?release=d21d60ad-c2d2-b32a-7432-ca4048a4a7d6 | jq
|
||||||
|
```
|
||||||
|
|
||||||
|
The command prints `true` on success.
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
<Tab heading="CLI" group="cli">
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ consul kv put -release -session=d21d60ad-c2d2-b32a-7432-ca4048a4a7d6 service/leader '{"Node": "'`hostname`'"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
On success, the command outputs a success message.
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard>
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
Success! Lock released on: service/leader
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
After a lock is released, the key data do not show a value for `Session` in the results.
|
||||||
|
Other clients can use this as a way to coordinate their lock requests.
|
||||||
|
|
|
@ -134,9 +134,9 @@ the goal of Consul to protect against misbehaving clients.
|
||||||
|
|
||||||
## Leader Election
|
## Leader Election
|
||||||
|
|
||||||
The primitives provided by sessions and the locking mechanisms of the KV
|
You can use the primitives provided by sessions and the locking mechanisms of the KV
|
||||||
store can be used to build client-side leader election algorithms.
|
store to build client-side leader election algorithms.
|
||||||
These are covered in more detail in the [Leader Election guide](/consul/tutorials/developer-configuration/application-leader-elections).
|
These are covered in more detail in the [Leader Election guide](/consul/docs/dynamic-app-config/sessions/application-leader-election).
|
||||||
|
|
||||||
## Prepared Query Integration
|
## Prepared Query Integration
|
||||||
|
|
|
@ -0,0 +1,420 @@
|
||||||
|
---
|
||||||
|
layout: docs
|
||||||
|
page_title: Enable DNS forwarding
|
||||||
|
description: ->
|
||||||
|
Learn how to configure different DNS servers to perform DNS forwarding to Consul servers.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Enable DNS forwarding
|
||||||
|
|
||||||
|
This page describes the process to enable DNS forwarding to Consul servers.
|
||||||
|
|
||||||
|
You can apply these operations on every node where a Consul agent is running.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
To enable DNS forwarding, your deployment must have the following:
|
||||||
|
|
||||||
|
- A running Consul server instance
|
||||||
|
- One or more Consul client nodes with registered services in the Consul catalog
|
||||||
|
- The `iptables` command available, or one of the following local DNS servers:
|
||||||
|
- [systemd-resolved](#systemd-resolved)
|
||||||
|
- [BIND](#bind)
|
||||||
|
- [Dnsmasq](#dnsmasq)
|
||||||
|
- [Unbound](#unbound)
|
||||||
|
- [macOS system resolver](#macos)
|
||||||
|
|
||||||
|
### Network address configuration
|
||||||
|
|
||||||
|
The example configurations on this page assumes Consul's DNS server is listening on the loopback interface on the same node of the local DNS server.
|
||||||
|
|
||||||
|
If Consul is not listening on the loopback IP, replace the references to `localhost` and `120.0.0.1` in the configuration and commands with the appropriate IP address for your environment.
|
||||||
|
|
||||||
|
## systemd-resolved
|
||||||
|
|
||||||
|
[`systemd-resolved`](https://www.freedesktop.org/software/systemd/man/latest/systemd-resolved.service.html) is a system service that provides network name resolution to local applications. It is the default local DNS server for many Linux distributions.
|
||||||
|
|
||||||
|
To configure the `systemd-resolved` service so that it sends `.consul` domain queries to Consul, create a `consul.conf` file located in the `/etc/systemd/resolved.conf.d/` directory.
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
<Tab heading="systemd 245 and older">
|
||||||
|
|
||||||
|
Add a `[Resolve]` section to your resolved configuration.
|
||||||
|
|
||||||
|
<CodeBlockConfig filename="/etc/systemd/resolved.conf.d/consul.conf">
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Resolve]
|
||||||
|
DNS=127.0.0.1
|
||||||
|
DNSSEC=false
|
||||||
|
Domains=~consul
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
### Define port for Consul DNS server
|
||||||
|
|
||||||
|
When using systemd 245 and older, you cannot specify port numbers in the `DNS` configuration field. systemd-resolved only uses port `53`, which is a privileged port.
|
||||||
|
|
||||||
|
When you cannot specify ports for the system's configuration, there are two workarounds:
|
||||||
|
- [Configure Consul DNS service to listen on port `53`](/consul/docs/agent/config/config-files#dns_port) instead of `8600`.
|
||||||
|
- Map port `53` to `8600` using `iptables`.
|
||||||
|
|
||||||
|
Binding to port `53` usually requires running Consul as a privileged user or running Linux with the `CAP_NET_BIND_SERVICE` capability.
|
||||||
|
When using the Consul Docker image, add the following to the environment to allow Consul to use the port: `CONSUL_ALLOW_PRIVILEGED_PORTS=yes`.
|
||||||
|
|
||||||
|
To avoid running Consul as a privileged user, the following `iptables` commands are sufficient to map port `53` to `8600` and redirect DNS queries to Consul.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
# iptables --table nat --append OUTPUT --destination localhost --protocol udp --match udp --dport 53 --jump REDIRECT --to-ports 8600 \
|
||||||
|
iptables --table nat --append OUTPUT --destination localhost --protocol tcp --match tcp --dport 53 --jump REDIRECT --to-ports 8600
|
||||||
|
```
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
|
||||||
|
<Tab heading="systemd 246 and newer">
|
||||||
|
|
||||||
|
Systemd 246 and newer allow you to specify the DNS port directly in the `systemd-resolved` configuration file.
|
||||||
|
Previous versions of systemd required iptables rules to direct DNS traffic to Consul.
|
||||||
|
|
||||||
|
Add a `[Resolve]` section to your resolved configuration.
|
||||||
|
|
||||||
|
<CodeBlockConfig filename="/etc/systemd/resolved.conf.d/consul.conf">
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Resolve]
|
||||||
|
DNS=127.0.0.1:8600
|
||||||
|
DNSSEC=false
|
||||||
|
Domains=~consul
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
</Tab>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
PTR record queries are still sent to the other configured resolvers, in addition to Consul.
|
||||||
|
|
||||||
|
After creating the resolved configuration, restart `systemd-resolved`.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
# systemctl restart systemd-resolved
|
||||||
|
```
|
||||||
|
|
||||||
|
The command produces no output.
|
||||||
|
|
||||||
|
### Validate the systemd-resolved configuration
|
||||||
|
|
||||||
|
Validate that `systemd-resolved` is active.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
# systemctl is-active systemd-resolved
|
||||||
|
active
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify that `systemd-resolved` is configured to forward queries for the `consul` domain to Consul.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
# resolvectl domain
|
||||||
|
Global: ~consul
|
||||||
|
Link 2 (eth0):
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify that `systemd-resolved` is able to resolve the Consul server address.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
# resolvectl query consul.service.consul
|
||||||
|
consul.service.consul: 127.0.0.1
|
||||||
|
|
||||||
|
-- Information acquired via protocol DNS in 6.6ms.
|
||||||
|
-- Data is authenticated: no
|
||||||
|
```
|
||||||
|
|
||||||
|
Confirm that `/etc/resolv.conf` points to the `stub-resolv.conf` file managed by `systemd-resolved`.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ ls -l /etc/resolv.conf
|
||||||
|
lrwxrwxrwx 1 root root 37 Jul 14 10:10 /etc/resolv.conf -> /run/systemd/resolve/stub-resolv.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Confirm that the IP address for `systemd-resolved`'s stub resolver is the configured `nameserver`.
|
||||||
|
|
||||||
|
<CodeBlockConfig>
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ cat /etc/resolv.conf
|
||||||
|
## This file is managed by man:systemd-resolved(8). Do not edit.
|
||||||
|
##
|
||||||
|
## This is a dynamic resolv.conf file for connecting local clients to the
|
||||||
|
## internal DNS stub resolver of systemd-resolved. This file lists all
|
||||||
|
## configured search domains.
|
||||||
|
##
|
||||||
|
## Run "resolvectl status" to see details about the uplink DNS servers
|
||||||
|
## currently in use.
|
||||||
|
##
|
||||||
|
## Third party programs must not access this file directly, but only through the
|
||||||
|
## symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
|
||||||
|
## replace this symlink by a static file or a different symlink.
|
||||||
|
##
|
||||||
|
## See man:systemd-resolved.service(8) for details about the supported modes of
|
||||||
|
## operation for /etc/resolv.conf.
|
||||||
|
|
||||||
|
nameserver 127.0.0.53
|
||||||
|
options edns0
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
Ensure that the operating system can resolve DNS queries to the `.consul` domain.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ host consul.service.consul
|
||||||
|
consul.service.consul has address 127.0.0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using any local resolver with systemd
|
||||||
|
|
||||||
|
By default, the local resolver stub in the `resolved.conf` file is configured to listen for UDP and TCP requests at `127.0.0.53:53`. However, you can set the `DNSStubListener` option to `false` so that your system can use any DNS configuration, as long as it loads earlier than `resolved`.
|
||||||
|
|
||||||
|
<CodeBlockConfig filename="/etc/systemd/resolved.conf">
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
DNSStubListener=false
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
## Dnsmasq
|
||||||
|
|
||||||
|
Use [dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html) if you have a small network and need a lightweight DNS solution.
|
||||||
|
|
||||||
|
<Note>
|
||||||
|
|
||||||
|
If your distribution uses systemd, disable `systemd-resolved` before you follow these steps.
|
||||||
|
|
||||||
|
</Note>
|
||||||
|
|
||||||
|
Configure the `dnsmasq.conf` file or a series of files in the `/etc/dnsmasq.d` directory. Add server settings to your configuration file so that requests for the `consul` domain are forwarded to Consul DNS.
|
||||||
|
|
||||||
|
<CodeBlockConfig filename="/etc/dnsmasq.d/10-consul">
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
# Enable forward lookup of the 'consul' domain:
|
||||||
|
server=/consul/127.0.0.1#8600
|
||||||
|
|
||||||
|
# Uncomment and modify as appropriate to enable reverse DNS lookups for
|
||||||
|
# common netblocks found in RFC 1918, 5735, and 6598:
|
||||||
|
#rev-server=0.0.0.0/8,127.0.0.1#8600
|
||||||
|
#rev-server=10.0.0.0/8,127.0.0.1#8600
|
||||||
|
#rev-server=100.64.0.0/10,127.0.0.1#8600
|
||||||
|
#rev-server=127.0.0.1/8,127.0.0.1#8600
|
||||||
|
#rev-server=169.254.0.0/16,127.0.0.1#8600
|
||||||
|
#rev-server=172.16.0.0/12,127.0.0.1#8600
|
||||||
|
#rev-server=192.168.0.0/16,127.0.0.1#8600
|
||||||
|
#rev-server=224.0.0.0/4,127.0.0.1#8600
|
||||||
|
#rev-server=240.0.0.0/4,127.0.0.1#8600
|
||||||
|
# Accept DNS queries only from hosts whose address is on a local subnet.
|
||||||
|
#local-service
|
||||||
|
# Don't poll /etc/resolv.conf for changes.
|
||||||
|
#no-poll
|
||||||
|
# Don't read /etc/resolv.conf. Get upstream servers only from the command
|
||||||
|
# line or the dnsmasq configuration file (see the "server" directive below).
|
||||||
|
#no-resolv
|
||||||
|
# Specify IP address(es) of other DNS servers for queries not handled
|
||||||
|
# directly by consul. There is normally one 'server' entry set for every
|
||||||
|
# 'nameserver' parameter found in '/etc/resolv.conf'. See dnsmasq(8)'s
|
||||||
|
# 'server' configuration option for details.
|
||||||
|
#server=1.2.3.4
|
||||||
|
#server=208.67.222.222
|
||||||
|
#server=8.8.8.8
|
||||||
|
# Set the size of dnsmasq's cache. The default is 150 names. Setting the
|
||||||
|
# cache size to zero disables caching.
|
||||||
|
#cache-size=65536
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
Restart the `dnsmasq` service after creating the configuration.
|
||||||
|
|
||||||
|
Refer to [`dnsmasq(8)`](http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html) for additional configuration settings such as specifying IP addresses for queries not handled directly by Consul.
|
||||||
|
|
||||||
|
|
||||||
|
## BIND
|
||||||
|
|
||||||
|
[BIND](https://www.isc.org/bind/) is a robust DNS system. Its most prominent component, `named`, performs both of the main DNS server roles, acts as an authoritative name server for DNS zones, and is a recursive resolver in the network.
|
||||||
|
|
||||||
|
<Note>
|
||||||
|
|
||||||
|
If your distribution uses systemd, disable `systemd-resolved` before you follow these steps.
|
||||||
|
|
||||||
|
</Note>
|
||||||
|
|
||||||
|
To configure the BIND service to send `.consul` domain queries to Consul:
|
||||||
|
|
||||||
|
1. Create a `named` configuration file with `DNSSEC` disabled.
|
||||||
|
1. Create a zone configuration file to manage the `.consul` domain.
|
||||||
|
|
||||||
|
### Named configuration file
|
||||||
|
|
||||||
|
Edit the `/etc/named.conf` to configure your BIND instance. Remember to disable `DNSSEC` so that Consul and BIND can communicate. Add an `include` section to include the zone file that you create in the next step.
|
||||||
|
|
||||||
|
The following example shows a BIND configuration with `DNSSEC` disabled.
|
||||||
|
|
||||||
|
<CodeBlockConfig filename="/etc/named.conf">
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
options {
|
||||||
|
listen-on port 53 { 127.0.0.1; };
|
||||||
|
listen-on-v6 port 53 { ::1; };
|
||||||
|
directory "/var/named";
|
||||||
|
dump-file "/var/named/data/cache_dump.db";
|
||||||
|
statistics-file "/var/named/data/named_stats.txt";
|
||||||
|
memstatistics-file "/var/named/data/named_mem_stats.txt";
|
||||||
|
allow-query { localhost; };
|
||||||
|
recursion yes;
|
||||||
|
|
||||||
|
dnssec-enable no;
|
||||||
|
dnssec-validation no;
|
||||||
|
|
||||||
|
/* Path to ISC DLV key */
|
||||||
|
bindkeys-file "/etc/named.iscdlv.key";
|
||||||
|
|
||||||
|
managed-keys-directory "/var/named/dynamic";
|
||||||
|
};
|
||||||
|
|
||||||
|
include "/etc/named/consul.conf";
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
### Zone configuration file
|
||||||
|
|
||||||
|
Set up a zone for your Consul-managed records in `consul.conf`.
|
||||||
|
|
||||||
|
<CodeBlockConfig filename="/etc/named/consul.conf">
|
||||||
|
|
||||||
|
```dns-zone-file
|
||||||
|
zone "consul" IN {
|
||||||
|
type forward;
|
||||||
|
forward only;
|
||||||
|
forwarders { 127.0.0.1 port 8600; };
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
## Unbound
|
||||||
|
|
||||||
|
Use [Unbound](https://www.unbound.net/) when you need a fast and lean DNS resolver for Linux and macOS.
|
||||||
|
|
||||||
|
<Note>
|
||||||
|
|
||||||
|
If your distribution uses systemd, disable `systemd-resolved` before you follow these steps.
|
||||||
|
|
||||||
|
</Note>
|
||||||
|
|
||||||
|
|
||||||
|
The following example demonstrates a configuration for the `consul.conf` file in the `/etc/unbound/unbound.conf.d` directory.
|
||||||
|
|
||||||
|
Add `server` and `stub-zone` settings to your Unbound configuration file.
|
||||||
|
|
||||||
|
<CodeBlockConfig filename="/etc/unbound/unbound.conf.d/consul.conf">
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
#Allow insecure queries to local resolvers
|
||||||
|
server:
|
||||||
|
do-not-query-localhost: no
|
||||||
|
domain-insecure: "consul"
|
||||||
|
|
||||||
|
#Add consul as a stub-zone
|
||||||
|
stub-zone:
|
||||||
|
name: "consul"
|
||||||
|
stub-addr: 127.0.0.1@8600
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
You may have to add the following line to the bottom of your `/etc/unbound/unbound.conf` file for the new configuration to be included.
|
||||||
|
|
||||||
|
<CodeBlockConfig filename="/etc/unbound/unbound.conf">
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
include: "/etc/unbound/unbound.conf.d/*.conf"
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
## iptables
|
||||||
|
|
||||||
|
[iptables](https://www.netfilter.org/projects/iptables/index.html) is a generic firewalling software that allows you to define traffic rules for your system.
|
||||||
|
|
||||||
|
If you do not have a local DNS server on the Consul agent node, use `iptables` to forward DNS requests on port `53` to the Consul agent running on the same machine without using a secondary service.
|
||||||
|
|
||||||
|
This configuration realizes full DNS forwarding, which means that all DNS queries for the host are forwarded to Consul, not just the ones for the `.consul` top level domain. Consul's default configuration resolves only the `.consul` top level domain, so you must set the [`recursors`](/consul/docs/agent/config/config-files#recursors) flag if you want your node to be able to resolve other domains when using `iptables` configuration.
|
||||||
|
|
||||||
|
If you use DNS relay hosts in your network, do not place them on the same host as Consul. The redirects may intercept the traffic.
|
||||||
|
|
||||||
|
### Configure Consul recursors
|
||||||
|
|
||||||
|
Add recursors to your Consul configuration.
|
||||||
|
|
||||||
|
<CodeBlockConfig filename="/etc/consul.d/consul.hcl">
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
# DNS recursors
|
||||||
|
recursors = [ "1.1.1.1" ]
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
Recursors should not include the `localhost` address because the `iptables` redirects would intercept the requests.
|
||||||
|
|
||||||
|
You can replace the `1.1.1.1` address in the example with another DNS server address. This is suitable for situations where an external DNS
|
||||||
|
service is already running in your infrastructure and is used as the recursor.
|
||||||
|
|
||||||
|
### Create iptables rules
|
||||||
|
|
||||||
|
After you configure Consul to use a valid recursor, add rules to `iptables` to redirect traffic from port `53` to port `8600`.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
# iptables -t nat -A PREROUTING -p udp -m udp --dport 53 -j REDIRECT --to-ports 8600 \
|
||||||
|
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 8600 \
|
||||||
|
iptables -t nat -A OUTPUT -d localhost -p udp -m udp --dport 53 -j REDIRECT --to-ports 8600 \
|
||||||
|
iptables -t nat -A OUTPUT -d localhost -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 8600
|
||||||
|
```
|
||||||
|
|
||||||
|
## macOS
|
||||||
|
|
||||||
|
On macOS systems, use the macOS system resolver to point all `.consul` requests to Consul.
|
||||||
|
The `man 5 resolver` command describes this feature in more detail.
|
||||||
|
|
||||||
|
The following instructions require `sudo` or root access.
|
||||||
|
|
||||||
|
To configure the macOS system resolver to forward DNS queries to Consul, add a resolver entry in the `/etc/resolver/` directory that points at the Consul agent.
|
||||||
|
|
||||||
|
If you do not have this folder, create it.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
# mkdir -p /etc/resolver
|
||||||
|
```
|
||||||
|
|
||||||
|
Create a new file `/etc/resolver/consul` with `nameserver` and `port` entries.
|
||||||
|
|
||||||
|
<CodeBlockConfig filename="/etc/resolver/consul">
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
nameserver 127.0.0.1
|
||||||
|
port 8600
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
The configuration informs the macOS resolver daemon to forward all `.consul` TLD requests to `127.0.0.1` on port `8600`.
|
||||||
|
|
||||||
|
## Next steps
|
||||||
|
|
||||||
|
This instructions on this page helped you configure your node to forward DNS requests to Consul.
|
||||||
|
|
||||||
|
To learn more on how to query Consul DNS once forwarding is enabled, refer to [DNS forwarding workflow](/consul/docs/services/discovery/dns-forwarding#workflow).
|
||||||
|
|
||||||
|
For more information on other DNS features and configurations available in Consul, refer to [DNS usage overview](/consul/docs/services/discovery/dns-overview).
|
|
@ -0,0 +1,186 @@
|
||||||
|
---
|
||||||
|
layout: docs
|
||||||
|
page_title: DNS forwarding
|
||||||
|
description: ->
|
||||||
|
Learn how to configure your local DNS servers to perform DNS forwarding to Consul servers.
|
||||||
|
---
|
||||||
|
|
||||||
|
# DNS forwarding
|
||||||
|
|
||||||
|
This topic describes the process to configure different DNS servers to enable DNS forwarding to Consul servers.
|
||||||
|
|
||||||
|
You can apply these operations on every node where a Consul agent is running.
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
You deployed a Consul datacenter and want to use Consul DNS interface for name resolution.
|
||||||
|
|
||||||
|
When configured with default values, Consul exposes the DNS interface on port `8600`. By default, DNS is served from port `53`. On most operating systems, this requires elevated privileges. It is also common, for most operating systems, to have a local DNS server already running on port `53`.
|
||||||
|
|
||||||
|
Instead of running Consul with an administrative or root account, you can forward appropriate queries to Consul, running on an unprivileged port, from another DNS server or using port redirect.
|
||||||
|
|
||||||
|
There are two configurations for a node's DNS forwarding behavior:
|
||||||
|
- **Conditional DNS forwarding**: the local DNS servers are configured to forward to Consul only queries relative to the `.consul` zone. All other queries are still served via the default DNS server in the node.
|
||||||
|
- **Full DNS forwarding**: Consul serves all DNS queries and forwards to a remote DNS server the ones outside `.consul` domain.
|
||||||
|
|
||||||
|
### Conditional DNS forwarding
|
||||||
|
|
||||||
|
We recommend the conditional DNS forwarding approach. This configuration lowers the Consul agent's resource consumption by limiting the number of DNS requests it handles.
|
||||||
|
|
||||||
|
![Consul DNS conditional forwarding - Only .consul requests are routed to Consul](/img/consul-dns-conditional-forwarding.png#light-theme-only)
|
||||||
|
![Consul DNS conditional forwarding - Only .consul requests are routed to Consul](/img/consul-dns-conditional-forwarding-dark.png#dark-theme-only)
|
||||||
|
|
||||||
|
In this configuration, Consul only serves queries relative to the `.consul` domain. There is no unnecessary load on Consul servers to serve queries from different domains.
|
||||||
|
|
||||||
|
This behavior is not enabled by default.
|
||||||
|
|
||||||
|
### Full DNS forwarding
|
||||||
|
|
||||||
|
This approach can be useful in scenarios where the Consul agent's node is allocated limited resources and you want to avoid the overhead of running a local DNS server. In this configuration, Consul serves all DNS queries for all domains and forwards the ones outside the `.consul` domain to one or more configured forwarder servers.
|
||||||
|
|
||||||
|
![Consul DNS forwarding - All requests are routed to Consul](/img/consul-dns-forwarding.png#light-theme-only)
|
||||||
|
![Consul DNS forwarding - All requests are routed to Consul](/img/consul-dns-forwarding-dark.png#dark-theme-only)
|
||||||
|
|
||||||
|
This behavior is not enabled by default. Consul standard configuration only resolves DNS records inside the `.consul` zone. To enable DNS forwarding, you need to set the [recursors](/consul/docs/agent/config/config-files#recursors) option in your Consul configuration.
|
||||||
|
|
||||||
|
In this scenario, if a Consul DNS reply includes a `CNAME` record pointing outside the `.consul` top level domain, then the DNS reply only includes `CNAME` records by default.
|
||||||
|
|
||||||
|
When `recursors` is set and the upstream resolver is functioning correctly, Consul tries to resolve CNAMEs and include any records (for example, A, AAAA, PTR) for them in its DNS reply. In these scenarios, Consul is used for full DNS forwarding and is able to serve queries for all domains.
|
||||||
|
|
||||||
|
## Workflow
|
||||||
|
|
||||||
|
To use DNS forwarding in Consul deployments, complete the following steps:
|
||||||
|
|
||||||
|
1. Configure the local DNS service to enable DNS forwarding to Consul. Follow the instructions for one of the following services:
|
||||||
|
|
||||||
|
- [systemd-resolved](/consul/docs/services/discovery/dns-forwarding/enable#systemd-resolved)
|
||||||
|
- [BIND](/consul/docs/services/discovery/dns-forwarding/enable#bind)
|
||||||
|
- [Dnsmasq](/consul/docs/services/discovery/dns-forwarding/enable#dnsmasq)
|
||||||
|
- [Unbound](/consul/docs/services/discovery/dns-forwarding/enable#unbound)
|
||||||
|
- [iptables](/consul/docs/services/discovery/dns-forwarding/enable#iptables)
|
||||||
|
- [macOS system resolver](/consul/docs/services/discovery/dns-forwarding/enable#macOS)
|
||||||
|
|
||||||
|
1. Query the Consul DNS to confirm that DNS forwarding functions correctly.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ dig consul.service.consul A
|
||||||
|
|
||||||
|
; <<>> DiG 9.16.48-Debian <<>> consul.service.consul A
|
||||||
|
;; global options: +cmd
|
||||||
|
;; Got answer:
|
||||||
|
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51736
|
||||||
|
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
|
||||||
|
|
||||||
|
;; OPT PSEUDOSECTION:
|
||||||
|
; EDNS: version: 0, flags:; udp: 65494
|
||||||
|
;; QUESTION SECTION:
|
||||||
|
;consul.service.consul. IN A
|
||||||
|
|
||||||
|
;; ANSWER SECTION:
|
||||||
|
consul.service.consul. 0 IN A 10.0.4.140
|
||||||
|
consul.service.consul. 0 IN A 10.0.4.121
|
||||||
|
consul.service.consul. 0 IN A 10.0.4.9
|
||||||
|
|
||||||
|
;; Query time: 4 msec
|
||||||
|
;; SERVER: 127.0.0.53#53(127.0.0.53)
|
||||||
|
;; WHEN: Wed Jun 26 20:47:05 UTC 2024
|
||||||
|
;; MSG SIZE rcvd: 98
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Optionally, verify reverse DNS.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ dig 140.4.0.10.in-addr.arpa. PTR
|
||||||
|
|
||||||
|
; <<>> DiG 9.16.48-Debian <<>> 140.4.0.10.in-addr.arpa. PTR
|
||||||
|
;; global options: +cmd
|
||||||
|
;; Got answer:
|
||||||
|
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35085
|
||||||
|
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
|
||||||
|
|
||||||
|
;; OPT PSEUDOSECTION:
|
||||||
|
; EDNS: version: 0, flags:; udp: 65494
|
||||||
|
;; QUESTION SECTION:
|
||||||
|
;140.4.0.10.in-addr.arpa. IN PTR
|
||||||
|
|
||||||
|
;; ANSWER SECTION:
|
||||||
|
140.4.0.10.in-addr.arpa. 0 IN PTR consul-server-0.node.dc1.consul.
|
||||||
|
|
||||||
|
;; Query time: 0 msec
|
||||||
|
;; SERVER: 127.0.0.53#53(127.0.0.53)
|
||||||
|
;; WHEN: Wed Jun 26 20:47:57 UTC 2024
|
||||||
|
;; MSG SIZE rcvd: 97
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use the `short` option for `dig` to only get the node name instead of the full output.
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ dig +short -x 10.0.4.140
|
||||||
|
consul-server-0.node.dc1.consul.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
If your DNS server does not respond but you do get an answer from Consul, turn on your DNS server's query log to check for errors.
|
||||||
|
|
||||||
|
### systemd-resolved
|
||||||
|
|
||||||
|
Enable query logging for `systemd-resolved`:
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
# resolvectl log-level debug
|
||||||
|
```
|
||||||
|
|
||||||
|
Check query log:
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
# journalctl -r -u systemd-resolved
|
||||||
|
```
|
||||||
|
|
||||||
|
Disable query logging:
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
# resolvectl log-level info
|
||||||
|
```
|
||||||
|
|
||||||
|
DNS forwarding may fail if you use the default `systemd-resolved` configuration and attempt to bind to `0.0.0.0`. The default configuration uses a DNS stub that listens for UDP and TCP requests at `127.0.0.53`. As a result, attempting to bind to `127.0.0.53` conflicts with the running stub. You can disable the stub as described in the [Using any local resolver with systemd](/consul/docs/services/discovery/dns-forwarding/enable#using-any-local-resolver-with-systemd) section to troubleshoot this problem.
|
||||||
|
|
||||||
|
### Dnsmasq
|
||||||
|
|
||||||
|
To enable query log refer to [Dnsmasq documentation](https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html).
|
||||||
|
|
||||||
|
In particular, look for the `log-queries` and `log-facility` configuration option.
|
||||||
|
|
||||||
|
When query log is enabled, it is possible to force Dnsmasq to emit a full cache dump using the `SIGUSR1` signal.
|
||||||
|
|
||||||
|
### BIND
|
||||||
|
|
||||||
|
Enable query log:
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ rndc querylog
|
||||||
|
```
|
||||||
|
|
||||||
|
Check logs:
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ tail -f /var/log/messages
|
||||||
|
```
|
||||||
|
|
||||||
|
The log may show errors like this:
|
||||||
|
|
||||||
|
<CodeBlockConfig hideClipboard>
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
error (no valid RRSIG) resolving
|
||||||
|
error (no valid DS) resolving
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeBlockConfig>
|
||||||
|
|
||||||
|
This error indicates that `DNSSEC` is not disabled properly.
|
||||||
|
|
||||||
|
If you receive errors about network connections, verify that there are no firewall
|
||||||
|
or routing problems between the servers running BIND and Consul.
|
|
@ -30,6 +30,12 @@ If you are using Consul for service mesh on VMs, you can use upstreams or DNS. W
|
||||||
|
|
||||||
If you are using Consul on Kubernetes, refer to [the upstreams annotation documentation](/consul/docs/k8s/annotations-and-labels#consul-hashicorp-com-connect-service-upstreams) for additional information.
|
If you are using Consul on Kubernetes, refer to [the upstreams annotation documentation](/consul/docs/k8s/annotations-and-labels#consul-hashicorp-com-connect-service-upstreams) for additional information.
|
||||||
|
|
||||||
|
## DNS forwarding
|
||||||
|
|
||||||
|
You can configure your local DNS servers to use Consul.
|
||||||
|
|
||||||
|
Refer to [DNS Forwarding](/consul/docs/services/discovery/dns-forwarding) for additional information.
|
||||||
|
|
||||||
## Static queries
|
## Static queries
|
||||||
Node lookups and service lookups are the fundamental types of static queries. Depending on your use case, you may need to use different query methods and syntaxes to query the DNS for services and nodes.
|
Node lookups and service lookups are the fundamental types of static queries. Depending on your use case, you may need to use different query methods and syntaxes to query the DNS for services and nodes.
|
||||||
|
|
||||||
|
|
|
@ -389,6 +389,19 @@
|
||||||
"title": "Configure DNS behavior",
|
"title": "Configure DNS behavior",
|
||||||
"path": "services/discovery/dns-configuration"
|
"path": "services/discovery/dns-configuration"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"title": "DNS forwarding",
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"title": "Overview",
|
||||||
|
"path": "services/discovery/dns-forwarding"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Enable DNS forwarding",
|
||||||
|
"path": "services/discovery/dns-forwarding/enable"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": "Perform static DNS lookups",
|
"title": "Perform static DNS lookups",
|
||||||
"path": "services/discovery/dns-static-lookups"
|
"path": "services/discovery/dns-static-lookups"
|
||||||
|
@ -1041,7 +1054,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Sessions",
|
"title": "Sessions",
|
||||||
"path": "dynamic-app-config/sessions"
|
"routes": [
|
||||||
|
{
|
||||||
|
"title": "Overview",
|
||||||
|
"path": "dynamic-app-config/sessions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Application leader election",
|
||||||
|
"path": "dynamic-app-config/sessions/application-leader-election"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "Watches",
|
"title": "Watches",
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 109 KiB |
Binary file not shown.
After Width: | Height: | Size: 109 KiB |
Binary file not shown.
After Width: | Height: | Size: 97 KiB |
Binary file not shown.
After Width: | Height: | Size: 96 KiB |
Loading…
Reference in New Issue