dnsdist
Dnsdist is a highly DNS, DoS and abuse-aware loadbalancer that brings out the best possible performance in any DNS deployment.
Configuration Reference
Instance Sets
Sets of instances of dnsdist can be defined under the root node dnsdists
. Each instance set should be a key-value pair, with:
- key: Name of the instance set
- value: Dictionary holding the configuration of the instance set
Parameters which can be used to configure dnsdist instances for a specific instance set are shown in the below table.
Parameter | Type | Default | Description |
---|---|---|---|
aclAdd |
List of string |
List of netmasks allowed to access dnsdist, in addition to the loopback, RFC1918 and other local addresses. Only used if aclAllowAll: false |
|
aclAllowAll |
boolean |
true |
Allow all inbound traffic to dnsdist, regardless of source IP |
additionalServices |
List of AdditionalService | List of additional Do53 services to be created, with the dnsdist pods as targets | |
affinity |
k8s: Affinity |
Pod affinity (Kubernetes docs: Affinity and anti-affinity). If unset, a default anti-affinity is applied using antiAffinityPreset to spread pods across nodes |
|
agentLogLevel |
string |
"info" |
Verbosity of logging for the agent container. Available options: "debug" "info" "warn" "error" |
agentLogFormat |
string |
"text" |
Format of logging for the agent container. Available options: "text" "json" |
agentResources |
k8s: Resources |
|
Resources allocated to the 'agent' container if resourceDefaults is true |
antiAffinityPreset |
string |
"preferred" |
Pod anti affinity preset. Available options: "preferred" "required" |
apiKey |
string |
API key used to access the /api endpoint, used to configure a static key (default: generated and stored in a secret) | |
apiKeySecret |
string |
Name of the secret from which to take the API key, used when there is a pre-provisioned secret holding the api key | |
apiKeySecretItem |
string |
Name of the data item within apiKeySecret which holds the API key, used when there is a pre-provisioned secret holding the api key (default: api_key ) |
|
config |
dnsdist Configuration | {} |
dnsdist configuration parameters |
containerSecurityContext |
k8s: SecurityContext |
|
SecurityContext applied to each container |
do53config |
Do53 Configuration | {} |
Do53 configuration parameters |
do53Locals |
integer |
1 |
Default amount of Do53 listen sockets per dnsdist pod |
do53TcpFastOpenQueueSize |
integer |
0 |
Default size of the TCP Fast Open queue on Do53 listen sockets |
do53TcpListenQueueSize |
integer |
Default size of the listen queue on Do53 listen sockets. Default: Derived from SOMAXCONN |
|
doh |
List of DoH Listener | [] |
Configuration of DoH listeners and services |
doh3 |
List of DoH3 Listener | [] |
Configuration of DoH3 listeners and services |
doq |
List of DoQ Listener | [] |
Configuration of DoQ listeners and services |
dot |
List of DoT Listener | [] |
Configuration of DoT listeners and services |
dstoredist |
dstoredist | Settings to configure protobuf message generation and destinations | |
ecs |
ECS Configuration | {} |
ECS configuration parameters |
filtering |
Filtering | Settings to enable and configure filtering | |
hostNetwork |
boolean |
false |
Use host networking for pods |
hpa |
HPA | Horizontal Pod Autoscaling settings | |
initResources |
k8s: Resources |
|
Resources allocated to the 'dnsdist-init' container if resourceDefaults is true |
luaScript |
string |
Lua script to be included in each dnsdist pod | |
nodeSelector |
k8s: NodeSelector |
{} |
Kubernetes pod nodeSelector |
podAnnotations |
k8s: Annotations |
{} |
Annotations to be added to each pod |
podDisruptionBudget |
k8s: PodDisruptionBudgetSpec |
{} |
Spec of PodDisruptionBudget to be applied to deployment |
podLabels |
k8s: Labels |
{} |
Labels to be added to each pod |
podSecurityContext |
k8s: PodSecurityContext |
|
SecurityContext applied to each pod |
pools |
Map of Server Pools | Server pools configuration | |
readiness |
Readiness | Readiness configuration for dnsdist pods | |
recursor |
Embedded Recursor | {} |
Configure embedded Recursor instances for this dnsdist instance |
replicas |
integer |
2 |
Default number of replicas in a Deployment |
resources |
k8s: Resources |
|
Resources allocated to the 'dnsdist' container |
ringBuffers |
Ring Buffers | Ring buffers configuration | |
rpcServerResources |
k8s: Resources |
|
Resources allocated to the 'rpc-server' container |
rulegroups |
List of string |
[] |
List of rulegroups to assign to this set of dnsdist instances. Rule groups are defined via Rulesets |
serverPurgeDelay |
integer |
5 |
Delay (in seconds) after which replaced servers are purged from dnsdist |
service |
Do53 Service |
|
Service configuration for Do53 traffic |
serviceLabels |
k8s: Labels |
{} |
Labels to be added to all services |
stateResources |
k8s: Resources |
|
Resources allocated to the 'dnsdist-state' container |
tolerations |
List of k8s: Tolerations |
[] |
Kubernetes pod Tolerations |
tuning |
Tuning Configuration | Extra options for tuning dnsdist | |
verbose |
boolean |
false |
Extra verbosity in logging |
dnsdist Configuration
You can further configure dnsdist as follows:
In the above example the servFailWhenNoServer
is set to true
. Parameters which can be used to further configure dnsdist:
Parameter | Type | Default | Description |
---|---|---|---|
addEDNSToSelfGeneratedResponses |
boolean |
true |
Whether to add EDNS to self-generated responses, provided that the initial query had EDNS |
allowEmptyResponse |
boolean |
false |
If true, allow empty responses (qdcount=0) with a NoError or NXDomain rcode (default) from backends. dnsdist drops these responses by default because it can’t match them against the initial query since they don’t contain the qname, qtype and qclass, and therefore the risk of collision is much higher than with regular responses |
consistentHashingBalancingFactor |
integer |
1 |
Maximum imbalance between the number of outstanding queries intended for a given server, based on its weight, and the actual number, when using the chashed consistent hashing load-balancing policy. Default is 0, which disables the bounded-load algorithm |
payloadSizeOnSelfGeneratedAnswers |
integer |
1232 |
Set the UDP payload size advertised via EDNS on self-generated responses. In accordance with RFC 6891, values lower than 512 will be treated as equal to 512 |
roundRobinFailOnNoServer |
boolean |
false |
By default the roundrobin load-balancing policy will still try to select a backend even if all backends are currently down. Setting this to true will make the policy fail and return that no server is available instead |
servFailWhenNoServer |
boolean |
false |
If true, return a ServFail when no servers are available, instead of the default behaviour of dropping the query |
verboseHealthChecks |
boolean |
false |
If true, health check errors will be logged |
weightedBalancingFactor |
integer |
1 |
Maximum imbalance between the number of outstanding queries intended for a given server, based on its weight, and the actual number, when using the whashed or wrandom load-balancing policy. Default is 0, which disables the bounded-load algorithm |
Do53 Configuration
You can configure the Do53 listeners in dnsdist as follows:
In the above example the maxConcurrentTCPConnections
is set to 10000
. Parameters which can be used to further configure the Do53 listeners:
Parameter | Type | Default | Description |
---|---|---|---|
enableProxyProtocol |
boolean |
true |
If setProxyProtocolACL() is used, expect a proxy protocol v2 header in front of incoming queries from an address in setProxyProtocolACL() |
maxConcurrentTCPConnections |
integer |
0 |
Maximum number of concurrent incoming TCP connections. Default: 0 (which means unlimited) |
tcpFastOpenQueueSize |
integer |
0 |
Set the TCP Fast Open queue size, enabling TCP Fast Open when available and the value is larger than 0. |
tcpListenQueueSize |
integer |
Default size of the listen queue. Default: Derived from SOMAXCONN |
DoH Listener
DoH listeners can be configured as a list on the doh
parameter of a dnsdist configuration. For example:
Above will create a DoH listener in dnsdist and configure a service of type LoadBalancer to distribute traffic to it.
Parameters which can be used to further configure a DoH listener:
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
config |
DoH Configuration | {} |
Configuration options for the DoH listener in dnsdist | |
name |
string |
yes |
Name of the DoH listener (used for naming the corresponding Service objects, etc) | |
locals |
integer |
1 |
Amount of listen sockets per dnsdist pod | |
headers |
dictionary |
{} |
Dictionary of HeaderName:HeaderValue pairs to add to each response (Omitted on redirect responses) | |
responses |
List of DoH Responses | [] |
Explicitly configured responses to URLs in urls |
|
secrets |
List of string |
List of names of Secrets (Type: kubernetes.io/tls) containing certificates & keys to be used on the DoH listener. Key must be in tls.key node and certificate (+ intermediates if applicable) must be in tls.crt node |
||
service |
Service Generic | Configuration of the service | ||
stekSecret |
string |
Name of a Secret (Type: Opaque) with stek tickets included in the tickets node. This secret is monitored for changes and will be updated in dnsdist whenever a change is detected |
||
urls |
List of string |
["/dns-query"] |
List of URLs to respond to (Default: /dns-query) |
DoH Configuration
You can configure the DoH listener in dnsdist as follows:
In the above example the minimum TLS version is set to tls1.2
. Parameters which can be used to further configure a DoH listener:
Parameter | Type | Default | Description |
---|---|---|---|
ciphers |
string |
The TLS ciphers to use, in OpenSSL format. Ciphers for TLS 1.3 must be specified via ciphersTLS13. | |
ciphersTLS13 |
string |
The TLS ciphers to use for TLS 1.3, in OpenSSL format. | |
enableProxyProtocol |
boolean |
true |
If setProxyProtocolACL() is used, expect a proxy protocol v2 header in front of incoming queries from an address in setProxyProtocolACL() |
enableRenegotiation |
boolean |
false |
Whether secure TLS renegotiation should be enabled |
exactPathMatching |
boolean |
true |
Whether to do exact path matching of the query path against the paths configured in urls (true) or to accepts sub-paths (false) |
idleTimeout |
integer |
30 |
Set the idle timeout, in seconds |
ignoreTLSConfigurationErrors |
boolean |
false |
Ignore TLS configuration errors (such as invalid certificate path) and just issue a warning instead of aborting the whole process |
internalPipeBufferSize |
integer |
1048576 |
Set the size in bytes of the internal buffer of the pipes used internally to pass queries and responses between threads. Default: 1048576 |
keepIncomingHeaders |
boolean |
false |
Whether to retain the incoming headers in memory |
maxConcurrentTCPConnections |
integer |
0 |
Maximum number of concurrent incoming TCP connections. Default: 0 (which means unlimited) |
minTLSVersion |
string |
"tls1.0" |
Minimum version of the TLS protocol to support. Available options: "tls1.0" "tls1.1" "tls1.2" "tls1.3" |
numberOfStoredSessions |
integer |
20480 |
The maximum number of sessions kept in memory at the same time. Setting this value to 0 disables stored session entirely |
preferServerCiphers |
boolean |
true |
Whether to prefer the order of ciphers set by the server instead of the one set by the client. Default is true, meaning that the order of the server is used |
proxyProtocolOutsideTLS |
boolean |
false |
When the use of incoming proxy protocol is enabled, whether the payload is prepended after the start of the TLS session |
releaseBuffers |
boolean |
true |
Whether OpenSSL should release its I/O buffers when a connection goes idle, saving roughly 35 kB of memory per connection |
sendCacheControlHeaders |
boolean |
true |
Whether to parse the response to find the lowest TTL and set a HTTP Cache-Control header accordingly |
serverTokens |
string |
"h2o/dnsdist" |
The content of the Server: HTTP header returned by dnsdist |
sessionTimeout |
integer |
Set the TLS session lifetime in seconds, this is used both for TLS ticket lifetime and for sessions kept in memory | |
sessionTickets |
boolean |
false |
Whether session resumption via session tickets is enabled. Default: true (ie: tickets are enabled) |
tcpFastOpenQueueSize |
integer |
0 |
Set the TCP Fast Open queue size, enabling TCP Fast Open when available and the value is larger than 0. |
tcpListenQueueSize |
integer |
Default size of the listen queue. Default: Derived from SOMAXCONN |
|
trustForwardedForHeader |
boolean |
false |
Whether to parse any existing X-Forwarded-For header in the HTTP query and use the right-most value as the client source address and port, for ACL checks, rules, logging and so on |
DoH Responses
You can configure custom responses on a DoH listener as follows:
dnsdists:
mydnsdist:
doh:
- name: mydoh
urls:
- /test
- /page
responses:
- regex: "^/test$"
status: 302
content: "/page"
- regex: "^/page"
status: 200
content: "welcome!"
headers:
test: "content on /page"
In the above example a request to /test
is answered with a HTTP-302 redirect to /page
. Requests to /page
are answered with a welcome!
message with a header named test
.
Parameters which can be used to further configure a response:
Parameter | Type | Default | Description |
---|---|---|---|
regex |
string |
Regular expression to match the path against | |
status |
integer |
HTTP code to answer with | |
content |
string |
Content of the HTTP response (or a URL in case of a redirect - HTTP-3XX) | |
headers |
dictionary |
Dictionary of HeaderName:HeaderValue pairs to add to each response (Omitted on redirect responses) |
DoH3 Listener
DoH3 listeners can be configured as a list on the doh3
parameter of a dnsdist configuration. For example:
Above will create a DoH3 listener in dnsdist and configure a service of type LoadBalancer to distribute traffic to it.
Parameters which can be used to further configure a DoH3 listener:
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
config |
DoH3 Configuration | {} |
Configuration options for the DoH3 listener in dnsdist | |
name |
string |
yes |
Name of the DoH3 listener (used for naming the corresponding Service objects, etc) | |
locals |
integer |
1 |
Amount of listen sockets per dnsdist pod | |
secrets |
List of string |
List of names of Secrets (Type: kubernetes.io/tls) containing certificates & keys to be used on the DoH3 listener. Key must be in tls.key node and certificate (+ intermediates if applicable) must be in tls.crt node |
||
service |
Service Generic | Configuration of the service |
DoH3 Configuration
You can configure the DoH3 listener in dnsdist as follows:
In the above example the idle timeout is increased from the default value to 10
. Parameters which can be used to further configure a DoH3 listener:
Parameter | Type | Default | Description |
---|---|---|---|
congestionControlAlgo |
string |
"reno" |
The congestion control algorithm. Available options: "reno" "cubic" "bbr" |
idleTimeout |
integer |
5 |
Idle timeout, in seconds |
internalPipeBufferSize |
integer |
1048576 |
Size in bytes of the internal buffer of the pipes used internally to pass queries and responses between threads |
keyLogFile |
string |
Write the TLS keys in the specified file so that an external program can decrypt TLS exchanges | |
maxInFlight |
integer |
0 |
Maximum number of in-flight queries. The default is 0, which disables out-of-order processing |
DoQ Listener
DoQ listeners can be configured as a list on the doq
parameter of a dnsdist configuration. For example:
Above will create a DoQ listener in dnsdist and configure a service of type LoadBalancer to distribute traffic to it.
Parameters which can be used to further configure a DoQ listener:
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
config |
DoQ Configuration | {} |
Configuration options for the DoQ listener in dnsdist | |
name |
string |
yes |
Name of the DoQ listener (used for naming the corresponding Service objects, etc) | |
locals |
integer |
1 |
Amount of listen sockets per dnsdist pod | |
secrets |
List of string |
List of names of Secrets (Type: kubernetes.io/tls) containing certificates & keys to be used on the DoQ listener. Key must be in tls.key node and certificate (+ intermediates if applicable) must be in tls.crt node |
||
service |
Service Generic | Configuration of the service |
DoQ Configuration
You can configure the DoQ listener in dnsdist as follows:
In the above example the idle timeout is increased from the default value to 10
. Parameters which can be used to further configure a DoQ listener:
Parameter | Type | Default | Description |
---|---|---|---|
congestionControlAlgo |
string |
"reno" |
The congestion control algorithm. Available options: "reno" "cubic" "bbr" |
idleTimeout |
integer |
5 |
Idle timeout, in seconds |
internalPipeBufferSize |
integer |
1048576 |
Size in bytes of the internal buffer of the pipes used internally to pass queries and responses between threads |
keyLogFile |
string |
Write the TLS keys in the specified file so that an external program can decrypt TLS exchanges | |
maxInFlight |
integer |
0 |
Maximum number of in-flight queries. The default is 0, which disables out-of-order processing |
DoT Listener
DoT listeners can be configured as a list on the dot
parameter of a dnsdist configuration. For example:
Above will create a DoT listener in dnsdist and configure a service of type LoadBalancer to distribute traffic to it.
Parameters which can be used to further configure a DoT listener:
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
config |
DoT Configuration | {} |
Configuration options for the DoY listener in dnsdist | |
name |
string |
yes |
Name of the DoT listener (used for naming the corresponding Service objects, etc) | |
locals |
integer |
1 |
Amount of listen sockets per dnsdist pod | |
secrets |
List of string |
List of names of Secrets (Type: kubernetes.io/tls) containing certificates & keys to be used on the DoH listener. Key must be in tls.key node and certificate (+ intermediates if applicable) must be in tls.crt node |
||
service |
Service Generic | Configuration of the service | ||
stekSecret |
string |
Name of a Secret (Type: Opaque) with stek tickets included in the tickets node. This secret is monitored for changes and will be updated in dnsdist whenever a change is detected |
DoT Configuration
You can configure the DoT listener in dnsdist as follows:
In the above example the minimum TLS version is set to tls1.2
. Parameters which can be used to further configure a DoT listener:
Parameter | Type | Default | Description |
---|---|---|---|
ciphers |
string |
The TLS ciphers to use, in OpenSSL format. Ciphers for TLS 1.3 must be specified via ciphersTLS13. | |
ciphersTLS13 |
string |
The TLS ciphers to use for TLS 1.3, in OpenSSL format. | |
enableProxyProtocol |
boolean |
true |
If setProxyProtocolACL() is used, expect a proxy protocol v2 header in front of incoming queries from an address in setProxyProtocolACL() |
enableRenegotiation |
boolean |
false |
Whether secure TLS renegotiation should be enabled |
ignoreTLSConfigurationErrors |
boolean |
false |
Ignore TLS configuration errors (such as invalid certificate path) and just issue a warning instead of aborting the whole process |
maxConcurrentTCPConnections |
integer |
0 |
Maximum number of concurrent incoming TCP connections. Default: 0 (which means unlimited) |
minTLSVersion |
string |
"tls1.0" |
Minimum version of the TLS protocol to support. Available options: "tls1.0" "tls1.1" "tls1.2" "tls1.3" |
numberOfStoredSessions |
integer |
20480 |
The maximum number of sessions kept in memory at the same time. Setting this value to 0 disables stored session entirely |
preferServerCiphers |
boolean |
true |
Whether to prefer the order of ciphers set by the server instead of the one set by the client. Default is true, meaning that the order of the server is used |
proxyProtocolOutsideTLS |
boolean |
false |
When the use of incoming proxy protocol is enabled, whether the payload is prepended after the start of the TLS session |
releaseBuffers |
boolean |
true |
Whether OpenSSL should release its I/O buffers when a connection goes idle, saving roughly 35 kB of memory per connection |
sessionTimeout |
integer |
Set the TLS session lifetime in seconds, this is used both for TLS ticket lifetime and for sessions kept in memory | |
sessionTickets |
boolean |
false |
Whether session resumption via session tickets is enabled. Default: true (ie: tickets are enabled) |
tcpFastOpenQueueSize |
integer |
0 |
Set the TCP Fast Open queue size, enabling TCP Fast Open when available and the value is larger than 0. |
tcpListenQueueSize |
integer |
Default size of the listen queue. Default: Derived from SOMAXCONN |
dstoredist
You can configure protobuf message generation and distribution via dstoredist via these options. For example:
dstoredists:
mydstoredist:
<dstoredist configuration>
dnsdists:
mydnsdist:
dstoredist:
dstoredists:
- group: mydstoredist
luaScript: |-
addResponseAction(AllRule(), RemoteLogResponseAction(ccdstoredist))
In the above example, a set of dstoredist instances named mydstoredist
is created, together with a set of dnsdist instances named mydnsdist
. We configure a few things on dnsdist:
- We instruct it to send all protobuf messages to a set of dstoredists named
mydstoredist
- We include a lua script with a rule on responses (
addResponseAction
), to match all (AllRule()
) - We issue a
RemoteLogResponseAction
to instruct dnsdist we want a protobuf message to be generated and referenceccdstoredist
to ensure it is processed by Cloud Control's default dstoredist handling
RemoteLogResponseAction(ccdstoredist)
ccdstoredist
is a static reference available when dnsdist is deployed via Cloud Control. It is a reference to Cloud Control's managed handler of protobuf messages and is required when you want dnsdist's protobuf messages handled by dstoredist
Generating protobuf messages
By default, dnsdist does not generate any protobuf messages. You need to use dnsdist's rules to instruct it to generate protobuf messages for the appropriate traffic
Parameters which can be used to further configure dstoredist for dnsdist:
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
batchBufferSize |
integer |
1048576 |
Size in bytes of the buffer used to handle message batches internally | |
connTimeout |
go: DurationString |
Idle timeout for connections to dstoredist. Only applies if a value is configured explicitly | ||
dstoredists |
dstoredistEndpoints | List of sets of dstoredists to distribute messages to |
Endpoints
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
group |
string |
yes |
Name of set of dstoredist instances | |
append_tags |
List of string |
[] |
List of tags which will be appended each message | |
filters |
Map of filters | {} |
Filters as defined by the format described in the dstore documentation for the filters parameter under routes |
|
tlsconfig |
TLSConfig | {} |
TLS configuration options |
Endpoint TLS Config
Parameters to configure TLS options, these should be child attributes of the tlsconfig
node. For example:
dnsdists:
mydnsdist:
dstoredist:
dstoredists:
- group: mydstoredist
tlsconfig:
insecure_skip_verify: true
Further parameters to configure:
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
ca |
string |
CA in PEM format to use for validation. Use of caSecret is recommended for security reasons |
||
caSecret |
string |
Name of a pre-existing Kubernetes Secret with a data item named ca.crt containing the CA in PEM format to use for validation |
||
insecure_skip_verify |
boolean |
false |
Skip validation of the storage backend's certificate chain and hostname |
ECS Configuration
You can configure ECS in dnsdist as follows:
Parameters which can be used to further configure ECS:
Parameter | Type | Default | Description |
---|---|---|---|
setECSOverride |
boolean |
false |
Whether to override an existing EDNS Client Subnet option present in the query (only effective when the backend server has annotation useClientSubnet = true). (Dnsdist default) |
setECSSourcePrefixV4 |
integer |
Truncate the requestors IPv4 address to this length, in bits (only effective when the backend server has annotation useClientSubnet = true) | |
setECSSourcePrefixV6 |
integer |
Truncate the requestors IPv6 address to this length, in bits (only effective when the backend server has annotation useClientSubnet = true) |
Embedded Recursor
In a high throughput Recursive DNS deployment, you can embed Recursor within the dnsdist pods to avoid the latency caused by the dnsdist to Recursor traffic. To utilize this, configure a recursor inside the dnsdist configuration:
The embedded recursors will automatically be added to the default
pool of dnsdist. To configure these embedded recursors, you can use the same syntax as a standalone recursor: Recursor configuration
Filtering
If you have a filtering set defined under the filterSettings
root node, you can easily apply them to this dnsdist via the following configuration:
filterSettings:
mysettings:
<Filtering settings>
dnsdists:
mydnsdist:
filtering:
enabled: true
settings: mysettings
You need to:
- Set
enabled
totrue
to enable the filtering - Configure
settings
to a named set offilterSettings
There are no other parameters to configure in this section. All the filtering configuration is done in the filterSettings
set itself.
HPA
Horizontal Pod Autoscaling (HPA) can be enabled by configuring the necessary parameters and setting enabled: true
. For example:
dnsdists:
mydnsdist:
hpa:
enabled: true
minReplicas: 2
maxReplicas: 6
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Parameters which can be used to configure HPA:
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
behavior |
k8s HorizontalPodAutoscalerBehavior |
Behavior of the Horizontal Pod Autoscaler | ||
enabled |
boolean |
yes |
false |
If true, enable Horizontal Pod Autoscaling |
maxReplicas |
integer |
4 |
Maximum number of replicas | |
metrics |
List of k8s MetricSpec |
Metric(s) upon which to make decisions regarding scaling | ||
minReplicas |
integer |
2 |
Minimum number of replicas |
Readiness
You can configure the readiness probe configuration for dnsdist as follows:
In the above example the readiness check will be disabled altogether. Parameters which can be used to further configure readiness:
Parameter | Type | Default | Description |
---|---|---|---|
bindInterface |
string |
Name of interface to which the readiness probe will bind. Default to the interface of the pod network | |
disabled |
boolean |
false |
Whether or not to instruct Kubernetes to poll the agent for readiness state |
do53ProbeInterval |
integer |
2 |
How often (in seconds) the agent will judge the health state of dnsdist via tests against the Do53 listeners |
do53QDomain |
string |
"a.root-servers.net" |
Domain used in the query to judge whether the Do53 listeners of a dnsdist container are healthy and ready for traffic |
do53QTimeout |
integer |
1 |
Number of seconds after which the query used to judge whether the Do53 listeners of a dnsdist container are healthy and ready for traffic time out |
do53QType |
string |
"A" |
Type of query used to judge whether the Do53 listeners of a dnsdist container are healthy and ready for traffic |
failureThreshold |
integer |
2 |
When a probe fails, Kubernetes will try this many times before marking the container as Unready. Updates deployment, resulting in respawn of dnsdist pods |
healthCheck |
boolean |
true |
Whether or not the agent will use DNS queries (see do53* items) to judge the health of the dnsdist container. If disabled, the dnsdist container will always be marked Ready |
initialDelaySeconds |
integer |
5 |
Number of seconds after the containers have started before readiness probes are initiated. Updates deployment, resulting in respawn of dnsdist pods |
periodSeconds |
integer |
2 |
How often (in seconds) to perform the readiness probes. Updates deployment, resulting in respawn of dnsdist pods |
stateProbeInterval |
integer |
2 |
How often (in seconds) the agent will judge the health state of the dnsdist agent |
successThreshold |
integer |
2 |
Minimum consecutive successful probes before a container is marked Ready. Updates deployment, resulting in respawn of dnsdist pods |
timeoutSeconds |
integer |
1 |
Number of seconds after which the readiness probes time out. Updates deployment, resulting in respawn of dnsdist pods |
Ring buffers
You can configure the dnsdist ring buffers as follows:
In the above example the maximum entries in the ring buffers will be raised to 20000
. Parameters which can be used to further configure ring buffers:
Parameter | Type | Default | Description |
---|---|---|---|
retries |
integer |
Number of shards to attempt to lock without blocking before giving up and simply blocking while waiting for the next shard to be available. Default: 5 if there is more than 1 shard, else it defaults to 0 |
|
shards |
integer |
1 |
Number of shards to use to limit lock contention |
size |
integer |
10000 |
Maximum amount of queries to keep in the ringbuffer |
Server pools
You can configure server pools as follows:
dnsdists:
mydnsdist:
pools:
default:
serverGroups:
- group: myrecursor
packetcache:
maxEntries: 200000
In the above example we add the instances of instance set myrecursor
to the dnsdist default
pool and ensure the default
pool has a packet cache enables with a capacity of 200000 entries. To further configure pools, you can use the following parameters:
Parameter | Type | Default | Description |
---|---|---|---|
ecs |
boolean |
false |
If true, dnsdist will add EDNS Client Subnet information to the query before looking up into the cache, when all servers from this pool are down. If at least one server is up, the preference of the selected server is used, this parameter is only useful if all the backends in this pool are down and have EDNS Client Subnet enabled, since the queries in the cache will have been inserted with ECS information |
packetcache |
Packet Cache | {} |
Configuration of packet cache |
serverGroups |
List of Server Groups | [] |
List of server groups to define which instance sets should receive traffic handled by this pool |
serverPolicy |
string |
"leastOutstanding" |
Policy for dnsdist to use to select the server in this pool to send a query to. Available options: "leastOutstanding" "firstAvailable" "wrandom" "whashed" "chashed" "roundrobin" |
Packet Cache
Packet cache in dnsdist is crucial to performance. To activate caching on a specific pool, set a value for maxEntries
, for example:
dnsdists:
mydnsdist:
pools:
default:
serverGroups:
- group: myrecursor
packetcache:
maxEntries: 200000
Above enables a packet cache for the default
pool and sets a capacity of 200000
entries. Further options for configuring the packet cache are:
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
cookieHashing |
boolean |
false |
Whether EDNS Cookie values will be hashed, resulting in separate entries for different cookies in the packet cache. This is required if the backend is sending answers with EDNS Cookies, otherwise a client might receive an answer with the wrong cookie | |
deferrableInsertLock |
boolean |
true |
Whether the cache should give up insertion if the lock is held by another thread, or simply wait to get the lock | |
keepStaleData |
boolean |
false |
Whether to suspend the removal of expired entries from the cache when there is no backend available in at least one of the pools using this cache | |
maxEntries |
integer |
yes |
Capacity of the packet cache | |
maxNegativeTTL |
integer |
3600 |
Cache a NXDomain or NoData answer from the backend for at most this amount of seconds, even if the TTL of the SOA record is higher | |
maxTTL |
integer |
86400 |
Cap the TTL for records to his number | |
minTTL |
integer |
0 |
Do not cache entries with a TTL lower than this | |
numberOfShards |
integer |
20 |
Number of shards to divide the cache into, to reduce lock contention | |
parseECS |
boolean |
false |
Whether any EDNS Client Subnet option present in the query should be extracted and stored to be able to detect hash collisions involving queries with the same qname, qtype and qclass but a different incoming ECS value | |
staleTTL |
integer |
60 |
When the backend servers are not reachable, and global configuration setStaleCacheEntriesTTL is set appropriately, TTL that will be used when a stale cache entry is returned | |
temporaryFailureTTL |
integer |
60 |
On a SERVFAIL or REFUSED from the backend, cache for this amount of seconds |
Server Group
A server group is a reference to a set of instances of auth
recursor
or resolver
to which traffic should be sent. An example:
dnsdists:
mydnsdist:
pools:
default:
serverGroups:
- group: externalresolvers
backendsPerServer: 4
resolvers:
externalresolvers:
ips:
- 8.8.8.8
- 1.1.1.1
- 8.8.4.4
- 9.9.9.9
The above will add the members of the externalresolvers
instance set to the default
server pool. Due to backendsPerServer
being set to 4, each member will be added 4 times to increase potential throughput.
Parameters available to configure server groups:
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
group |
string |
yes |
Name of the instance set whose members should be added to the pool | |
backendsPerServer |
integer |
1 |
How many times each member should be added to the pool |
Service Configuration - Do53
Parameters to configure a service object for Do53 traffic. This service configuration exposes a port (:53
by default) for both TCP and UDP protocols. For example:
This format is reusable for all Do53 services in a dnsdist configuration. For example, the default dnsdist service:
dnsdists:
mydnsdist:
service:
type: LoadBalancer
annotations:
metallb.universe.tf/address-pool: name_of_pool
Parameter | Type | Default | Description |
---|---|---|---|
allocateLoadBalancerNodePorts |
boolean |
true |
If true, services with type LoadBalancer automatically assign NodePorts. Can be set to false if the LoadBalancer provider does not rely on NodePorts |
annotations |
k8s: Annotations |
{} |
Annotations for the service |
clusterIP |
string |
Static cluster IP, must be in the cluster's range of cluster IPs and not in use. Randomly assigned when not specified. | |
clusterIPs |
List of string |
List of static cluster IPs, must be in the cluster's range of cluster IPs and not in use. | |
externalIPs |
List of string |
List of IP addresses for which nodes in the cluster will also accept traffic for this service. These IPs are not managed by Kubernetes and must be user-defined on the cluster's nodes | |
externalTrafficPolicy |
string |
Cluster |
Can be set to Local to let nodes distribute traffic received on one of the externally-facing addresses (NodePort and LoadBalancer ) solely to endpoints on the node itself |
healthCheckNodePort |
integer |
For services with type LoadBalancer and externalTrafficPolicy Local you can configure this value to choose a static port for the NodePort which external systems (LoadBalancer provider mainly) can use to determine which node holds endpoints for this service |
|
internalTrafficPolicy |
string |
Cluster |
Can be set to Local to let nodes distribute traffic received on the ClusterIP solely to endpoints on the node itself |
lbMixedProtocol |
boolean |
false |
If true and type: LoadBalancer : Create a single LoadBalancer with both TCP and UDP ports |
lbPerIPFamily |
boolean |
false |
If true and type: LoadBalancer : Create a separate LoadBalancer for IPv4 and IPv6 |
loadBalancerIP |
string |
Deprecated Kubernetes feature, available for backwards compatibility: IP address to attempt to claim for use by this LoadBalancer. Replaced by annotations specific to each LoadBalancer provider |
|
loadBalancerSourceRanges |
List of string |
If supported by the LoadBalancer provider, restrict traffic to this LoadBalancer to these ranges | |
loadBalancerClass |
string |
Used to select a non-default type of LoadBalancer class to ensure the appropriate LoadBalancer provisioner attempt to manage this LoadBalancer service | |
publishNotReadyAddresses |
boolean |
false |
Service is populated with endpoints regardless of readiness state |
servicePerPort |
boolean |
false |
If true and type: ClusterIP or type: NodePort : Create a separate service for both TCP and UDP ports |
sessionAffinity |
string |
None |
Can be set to ClientIP to attempt to maintain session affinity. |
sessionAffinityConfig |
k8s: SessionAffinityConfig |
{} |
Configuration of session affinity |
type |
string |
ClusterIP |
Type of service. Available options: "ClusterIP" "LoadBalancer" "NodePort" |
Service Configuration - Generic
Parameters to configure a service object for non-Do53 traffic. For example:
This format is reusable for all non-Do53 services in a dnsdist configuration. Parameters which you can configure for it:
Parameter | Type | Default | Description |
---|---|---|---|
allocateLoadBalancerNodePorts |
boolean |
true |
If true, services with type LoadBalancer automatically assign NodePorts. Can be set to false if the LoadBalancer provider does not rely on NodePorts |
annotations |
k8s: Annotations |
{} |
Annotations for the service |
clusterIP |
string |
Static cluster IP, must be in the cluster's range of cluster IPs and not in use. Randomly assigned when not specified. | |
clusterIPs |
List of string |
List of static cluster IPs, must be in the cluster's range of cluster IPs and not in use. | |
externalIPs |
List of string |
List of IP addresses for which nodes in the cluster will also accept traffic for this service. These IPs are not managed by Kubernetes and must be user-defined on the cluster's nodes | |
externalTrafficPolicy |
string |
Cluster |
Can be set to Local to let nodes distribute traffic received on one of the externally-facing addresses (NodePort and LoadBalancer ) solely to endpoints on the node itself |
healthCheckNodePort |
integer |
For services with type LoadBalancer and externalTrafficPolicy Local you can configure this value to choose a static port for the NodePort which external systems (LoadBalancer provider mainly) can use to determine which node holds endpoints for this service |
|
internalTrafficPolicy |
string |
Cluster |
Can be set to Local to let nodes distribute traffic received on the ClusterIP solely to endpoints on the node itself |
loadBalancerIP |
string |
Deprecated Kubernetes feature, available for backwards compatibility: IP address to attempt to claim for use by this LoadBalancer. Replaced by annotations specific to each LoadBalancer provider |
|
loadBalancerSourceRanges |
List of string |
If supported by the LoadBalancer provider, restrict traffic to this LoadBalancer to these ranges | |
loadBalancerClass |
string |
Used to select a non-default type of LoadBalancer class to ensure the appropriate LoadBalancer provisioner attempt to manage this LoadBalancer service | |
publishNotReadyAddresses |
boolean |
false |
Service is populated with endpoints regardless of readiness state |
sessionAffinity |
string |
None |
Can be set to ClientIP to attempt to maintain session affinity. |
sessionAffinityConfig |
k8s: SessionAffinityConfig |
{} |
Configuration of session affinity |
type |
string |
ClusterIP |
Type of service. Available options: "ClusterIP" "LoadBalancer" "NodePort" |
Additional Services
Additional services can be used to create multiple Do53 entrypoints to your dnsdist instances. An additional service takes a name and a Service Do53 configuration. For example:
dnsdists:
mydnsdist:
additionalServices:
- name: test1
- name: test2
type: LoadBalancer
annotations:
metallb.universe.tf/address-pool: name_of_pool
Above example will result in 2 extra services:
test1
has no configuration, so it will use the default oftype: ClusterIP
test2
will be a LoadBalancer with the extra annotation on it
Tuning configuration
You can configure Cloud Control to apply dnsdist tuning functions to further optimize performance. For example:
In the above example the setMaxTCPClientThreads
function will be run to set this value to 20
. All options which can be configured this way:
Parameter | Type | Default | Description |
---|---|---|---|
setCacheCleaningDelay |
integer |
60 |
Interval in seconds between two runs of the cache cleaning algorithm, removing expired entries |
setCacheCleaningPercentage |
integer |
100 |
Percentage of the cache that the cache cleaning algorithm will try to free by removing expired entries |
setMaxTCPClientThreads |
integer |
10 |
Maximum amount of TCP client threads, handling TCP connections |
setMaxTCPConnectionDuration |
integer |
0 |
Maximum duration of an incoming TCP connection, in seconds. Default: 0 (unlimited) |
setMaxTCPConnectionsPerClient |
integer |
0 |
Maximum number of TCP connections per client. Default: 0 (unlimited) |
setMaxTCPQueriesPerConnection |
integer |
0 |
Maximum number of queries in an incoming TCP connection. Default: 0 (unlimited) |
setMaxTCPQueuedConnections |
integer |
1000 |
Maximum number of TCP connections queued (waiting to be picked up by a client thread). 0 means unlimited |
setMaxUDPOutstanding |
integer |
65535 |
Maximum number of outstanding UDP queries to a given backend server |
setStaleCacheEntriesTTL |
integer |
TTL for expired cache entries to be eligible as answer when no backends are available for a query, in seconds | |
setTCPRecvTimeout |
integer |
2 |
Read timeout on TCP connections from the client, in seconds |
setTCPSendTimeout |
integer |
2 |
Write timeout on TCP connections from the client, in seconds |
setUDPTimeout |
integer |
2 |
Maximum time dnsdist will wait for a response from a backend over UDP, in seconds |
Rulesets
Limited functionality
Rulesets defined in the manner described below are limited in terms of functionality. To utilize more advanced rules & actions you can use the luaScript
parameter on the dnsdist instance set to import rules using the syntax described in the dnsdist documentation
Rulesets allow for the configuration of sets of rules which allow you to match traffic and perform specific actions. Each rule is made up of 4 components:
- Name: Name of the rule
- Selectors: List of filters
- Combinator: Logic of how to combine the Selectors
- Action: Action to apply to the traffic selected by the above Selectors & Combinator
For example:
- name: Refuse TCP
selectors:
- TCP: true
- QName: "tcptrue.example.com"
combinator: AND
action:
RCode:
rcode: "REFUSED"
In the above example we create a rule named Refuse TCP
and via the AND
combinator we need both TCP
to be true
and QNAME
to match tcptrue.example.com
. This means we are matching against traffic received over TCP for the domain tcptrue.example.com
. If this is the case, the action is to answer with an RCode
which equals REFUSED
.
To let us specify multiple rules in a single group that we can later assign to a dnsdist instance, the rules are wrapped in a ruleset
:
rulesets:
myruleset:
group: block-traffic
type: DNSDistRule
rules:
- name: Refuse TCP
selectors:
- TCP: true
- QName: "tcptrue.example.com"
combinator: AND
action:
RCode:
rcode: "REFUSED"
- name: LocalPool
combinator: AND
selectors:
- SuffixMatchNode:
smn:
- "local"
- "internal"
action:
Pool:
poolname: "localpool"
We now have a ruleset named myruleset
which contains 2 rules. The group
is a tag which we can specify on a dnsdist instance via the rulegroups
argument to apply all rulesets with this group
tag. For example:
dnsdists:
mydnsdist:
rulegroups: block-traffic
rulesets:
myruleset:
group: block-traffic
type: DNSDistRule
rules:
<rules configuration>
Rulesets configuration
To configure a ruleset, you can use the following parameters:
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
group |
string |
yes |
Group label which can be used to assign rulesets to dnsdist instances | |
type |
string |
yes |
"" |
Type of rule. Available options: "DNSDistRule" |
rules |
List of Rule | yes |
[] |
Rules that make up this ruleset |
priority |
integer |
If multiple rulesets are assigned to a dnsdist instance, they will be processed in their order of priority (lowest priority value being handled first) |
Rules
To configure a rule, you can use the following parameters:
Parameter | Type | Required | Default | Description |
---|---|---|---|---|
name |
string |
yes |
Name of the rule | |
selectors |
List of Selector | yes |
[] |
List of filters on which to apply the logic of the combinator |
combinator |
string |
yes |
"" |
A combinator to apply to the list of selectors. Available options: "AND" "OR" "NOT" |
action |
Action | yes |
Action to apply on the selected traffic |
Selectors
Currently the following selectors are available:
TCP
The TCP selector can be used to select whether or not traffic was received over TCP.
Format:
Parameters:
Parameter | Type | Description |
---|---|---|
TCP |
boolean |
If true, select traffic received over TCP. If false select non-TCP traffic |
MaxQPS
The MaxQPS selector can be used to select traffic that fells within the specified QPS limit.
Format:
Parameters:
Parameter | Type | Description |
---|---|---|
qps |
integer |
Match any traffic which falls within this qps limit. If 50 , the first 50 within a second will match, request 51 onwards will not match |
MaxQPSIP
The MaxQPS selector can be used to select traffic that fells within the specified QPS limit, specific to a traffic source.
Format:
Or relying on most of the defaults:
Parameters:
Parameter | Type | Default | Description |
---|---|---|---|
qps |
integer |
Match any traffic which falls within this qps limit. If 50 , the first 50 within a second will match, request 51 onwards will not match |
|
v4Mask |
integer |
32 |
The IPv4 netmask to match on |
v6Mask |
integer |
64 |
The IPv6 netmask to match on |
burst |
integer |
The number of burstable queries per second allowed. Default: same as qps |
|
expiration |
integer |
300 |
How long to keep netmask or IP addresses after they have last been seen, in seconds |
cleanupDelay |
integer |
60 |
The number of seconds between two cleanups |
scanFraction |
integer |
10 |
The maximum fraction of the store to scan for expired entries |
NetmaskGroup
The NetmaskGroup selector can be used to select based on source or destination address of the traffic.
Format:
Parameters:
Parameter | Type | Default | Description |
---|---|---|---|
nmg |
List of string |
The NetMaskGroups to match on | |
src |
boolean |
true |
If true, match on source address. If false, match on destination address |
Opcode
The Opcode selector can be used to select traffic based on the requested operation.
Format:
Parameters:
Parameter | Type | Description |
---|---|---|
Opcode |
string |
Name of the operation to select |
QName
The QName selector can be used to select traffic matching a specific QName
Format:
Parameters:
Parameter | Type | Description |
---|---|---|
QName |
string |
Match traffic for this exact QName |
QType
The QType selector can be used to select traffic requesting this specific QType
Format:
Parameters:
Parameter | Type | Description |
---|---|---|
QType |
string |
Match traffic for this QType |
Actions
Currently the following actions are available:
Allow
The Allow action will let the traffic proceed to be handled.
Format:
Parameters:
Parameter | Type | Description |
---|---|---|
Allow |
boolean |
If true, let traffic proceed |
Drop
The Drop action will ensure the traffic is dropped and will not be responded to.
Format:
Parameters:
Parameter | Type | Description |
---|---|---|
Drop |
boolean |
If true, drop the traffic |
Pool
The Pool action will ensure dnsdist lets a named server pool handle the traffic
Format:
Parameters:
Parameter | Type | Description |
---|---|---|
poolname |
string |
Name of a server pool |
RCode
The RCode action will respond to the matched traffic with a specific RCode.
Format:
Parameters:
Parameter | Type | Description |
---|---|---|
rcode |
string |
The RCode to return |
TC
The TC action will answer traffic with the TC bit set, and the RA bit set to the value of RD in the query, to force the client to TCP.
Format:
Parameters:
Parameter | Type | Description |
---|---|---|
TC |
boolean |
If true, set the TC bit |