Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

consul-template: Add fault tolerant defaults #13041

Merged
merged 9 commits into from
Jun 8, 2022
3 changes: 3 additions & 0 deletions .changelog/13041.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
client: added more fault tolerant defaults for template configuration
```
18 changes: 15 additions & 3 deletions client/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ var (
"/run/systemd/resolve": "/run/systemd/resolve",
}

DefaultTemplateMaxStale = 5 * time.Second
DefaultTemplateMaxStale = 87600 * time.Hour

DefaultTemplateFunctionDenylist = []string{"plugin", "writeToFile"}
)
Expand Down Expand Up @@ -717,8 +717,20 @@ func DefaultConfig() *Config {
NoHostUUID: true,
DisableRemoteExec: false,
TemplateConfig: &ClientTemplateConfig{
tgross marked this conversation as resolved.
Show resolved Hide resolved
FunctionDenylist: DefaultTemplateFunctionDenylist,
DisableSandbox: false,
FunctionDenylist: DefaultTemplateFunctionDenylist,
DisableSandbox: false,
BlockQueryWaitTime: helper.TimeToPtr(5 * time.Minute), // match Consul default
MaxStale: helper.TimeToPtr(DefaultTemplateMaxStale), // match Consul default
Wait: &WaitConfig{
Min: helper.TimeToPtr(5 * time.Second),
Max: helper.TimeToPtr(4 * time.Minute),
},
ConsulRetry: &RetryConfig{
Attempts: helper.IntToPtr(0), // unlimited
},
VaultRetry: &RetryConfig{
Attempts: helper.IntToPtr(0), // unlimited
},
},
RPCHoldTimeout: 5 * time.Second,
CNIPath: "/opt/cni/bin",
Expand Down
50 changes: 29 additions & 21 deletions website/content/docs/configuration/client.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -217,27 +217,35 @@ chroot as doing so would cause infinite recursion.
files on the client host via the `file` function. By default, templates can
access files only within the [task working directory].

- `max_stale` `(string: "")` - # This is the maximum interval to allow "stale"
- `max_stale` `(string: "87600h")` - This is the maximum interval to allow "stale"
data. By default, only the Consul leader will respond to queries. Requests to
DerekStrickland marked this conversation as resolved.
Show resolved Hide resolved
a follower will forward to the leader. In large clusters with many requests,
this is not as scalable. This option allows any follower to respond to a query,
so long as the last-replicated data is within this bound. Higher values result
in less cluster load, but are more likely to have outdated data.

- `wait` `(Code: nil)` - Defines the minimum and maximum amount of time to wait
for the Consul cluster to reach a consistent state before rendering a template.
This is useful to enable in systems where network connectivity to Consul is degraded,
because it will reduce the number of times a template is rendered. This configuration is
also exposed in the _task template stanza_ to allow overrides per task.
- `wait` `(map: { min = "5s" max = "4m" })` - Defines the minimum and maximum amount
of time to wait before attempting to re-render a template. By default, Consul Template
will loop continually and re-render. If this value is set, Nomad will configure Consul
Comment on lines +228 to +229
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By default, Consul Template

Aren't 5s/4m the defaults?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are. I thought our convention was to put the defaults in these code snippet sections. Is that not the case?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh hm, maybe I just misread this sentence. I think when I see:

By default X. If this value is set, Y.

I assume that the value in question is not set by default. The phrasing definitely isn't explicitly saying that, so maybe it's just my poor reading comprehension at work. 😅

The preceding and following sentences clear it all up, but maybe these 2 could be rephrased a bit:

Consul Template re-renders templates whenever rendered variables from Consul, Nomad, or Vault change. However in order to minimize how often tasks are restarted or reloaded, Nomad will configure .

My main point being is that I think the By default... in the first sentence makes users think this parameter changes that behavior when it doesn't. Re-rendering in a loop is just how Consul Template works and these parameters just tweak some timings.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok. That makes sense. I'll stage a new PR with these doc changes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't 5s/4m the defaults?

They are not. Default max in consul-template 4 times of Minimum value not 4 Minutes

Template with a backoff timer that will tick on an interval equal to the specified `min`
value. Consul Template will always wait at least the as long as the `min` value specified.
If the underlying data has not changed between two tick intervals, Consul Template will
re-render. If the underlying data has changed, Consul Template will delay re-rendering
until the underlying data stabilizes for at least one tick interval, or the configured
`max` duration has elapsed. Once the `max` duration has elapsed, Consul Template will
re-render the template with the data available at the time. This is useful to enable in
systems where Consul is in a degraded state, or the referenced data values are changing
rapidly, because it will reduce the number of times a template is rendered. This
configuration is also exposed in the _task template stanza_ to allow overrides per task.

```hcl
wait {
min = "5s"
max = "10s"
max = "4m"
}
```

- `wait_bounds` `(Code: nil)` - Defines client level lower and upper bounds for
- `wait_bounds` `(map: nil)` - Defines client level lower and upper bounds for
per-template `wait` configuration. If the individual template configuration has
a `min` lower than `wait_bounds.min` or a `max` greater than the `wait_bounds.max`,
the bounds will be enforced, and the template `wait` will be adjusted before being
Expand All @@ -250,23 +258,23 @@ chroot as doing so would cause infinite recursion.
}
```

- `block_query_wait` `(string: "60s")` - This is amount of time in seconds to wait
- `block_query_wait` `(string: "5m")` - This is amount of time in seconds to wait
for the results of a blocking query. Many endpoints in Consul support a feature known as
"blocking queries". A blocking query is used to wait for a potential change
using long polling.

- `consul_retry` `(Code: nil)` - This controls the retry behavior when an error is
returned from Consul. Consul Template is highly fault tolerant, meaning it does
not exit in the face of failure. Instead, it uses exponential back-off and retry
functions to wait for the cluster to become available, as is customary in distributed
systems.
- `consul_retry` `(map: { attempts = 0 backoff = "250ms" max_backoff = "1m" })`-
This controls the retry behavior when an error is returned from Consul. The template
runner will not exit in the face of failure. Instead, it uses exponential back-off
and retry functions to wait for the Consul cluster to become available, as is
customary in distributed systems.

```hcl
consul_retry {
# This specifies the number of attempts to make before giving up. Each
# attempt adds the exponential backoff sleep time. Setting this to
# zero will implement an unlimited number of retries.
attempts = 12
attempts = 0
# This is the base amount of time to sleep between retry attempts. Each
# retry sleeps for an exponent of 2 longer than this base. For 5 retries,
# the sleep times would be: 250ms, 500ms, 1s, 2s, then 4s.
Expand All @@ -280,18 +288,18 @@ chroot as doing so would cause infinite recursion.
}
```

- `vault_retry` `(Code: nil)` - This controls the retry behavior when an error is
returned from Vault. Consul Template is highly fault tolerant, meaning it does
not exit in the face of failure. Instead, it uses exponential back-off and retry
functions to wait for the cluster to become available, as is customary in distributed
systems.
- `vault_retry` `(map: { attempts = 0 backoff = "250ms" max_backoff = "1m" })` -
This controls the retry behavior when an error is returned from Vault. Consul
Template is highly fault tolerant, meaning it does not exit in the face of failure.
Instead, it uses exponential back-off and retry functions to wait for the cluster
to become available, as is customary in distributed systems.

```hcl
vault_retry {
# This specifies the number of attempts to make before giving up. Each
# attempt adds the exponential backoff sleep time. Setting this to
# zero will implement an unlimited number of retries.
attempts = 12
attempts = 0
# This is the base amount of time to sleep between retry attempts. Each
# retry sleeps for an exponent of 2 longer than this base. For 5 retries,
# the sleep times would be: 250ms, 500ms, 1s, 2s, then 4s.
Expand Down