mirror of
https://github.com/coredns/coredns.git
synced 2025-11-07 12:36:20 -05:00
257 lines
7.0 KiB
Markdown
257 lines
7.0 KiB
Markdown
|
|
# forwardcrd
|
||
|
|
|
||
|
|
## Name
|
||
|
|
|
||
|
|
*forwardcrd* - enables proxying DNS messages to upstream resolvers by reading
|
||
|
|
the `Forward` CRD from a Kubernetes cluster
|
||
|
|
|
||
|
|
## Description
|
||
|
|
|
||
|
|
The *forwardcrd* plugin is used to dynamically configure stub-domains by
|
||
|
|
reading a `Forward` CRD within a Kubernetes cluster.
|
||
|
|
|
||
|
|
See [Configuring Private DNS Zones and Upstream Nameservers in
|
||
|
|
Kubernetes](https://kubernetes.io/blog/2017/04/configuring-private-dns-zones-upstream-nameservers-kubernetes/)
|
||
|
|
for a description of stub-domains within Kubernetes.
|
||
|
|
|
||
|
|
This plugin can only be used once per Server Block.
|
||
|
|
|
||
|
|
## Security
|
||
|
|
|
||
|
|
This plugin gives users of Kubernetes another avenue of modifying the CoreDNS
|
||
|
|
server other than the `coredns` configmap. Therefore, it is important that you
|
||
|
|
limit the RBAC and the `namespace` the plugin reads from to reduce the surface
|
||
|
|
area a malicious actor can use. Ideally, the level of access to create `Forward`
|
||
|
|
resources is at the same level as the access to the `coredns` configmap.
|
||
|
|
|
||
|
|
## Syntax
|
||
|
|
|
||
|
|
~~~
|
||
|
|
forwardcrd [ZONES...]
|
||
|
|
~~~
|
||
|
|
|
||
|
|
With only the plugin specified, the *forwardcrd* plugin will default to the
|
||
|
|
zone specified in the server's block. It will allow any `Forward` resource that
|
||
|
|
matches or includes the zone as a suffix. If **ZONES** are specified it allows
|
||
|
|
any zone listed as a suffix.
|
||
|
|
|
||
|
|
```
|
||
|
|
forwardcrd [ZONES...] {
|
||
|
|
endpoint URL
|
||
|
|
tls CERT KEY CACERT
|
||
|
|
kubeconfig KUBECONFIG [CONTEXT]
|
||
|
|
namespace [NAMESPACE]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
* `endpoint` specifies the **URL** for a remote k8s API endpoint. If omitted,
|
||
|
|
it will connect to k8s in-cluster using the cluster service account.
|
||
|
|
* `tls` **CERT** **KEY** **CACERT** are the TLS cert, key and the CA cert file
|
||
|
|
names for remote k8s connection. This option is ignored if connecting
|
||
|
|
in-cluster (i.e. endpoint is not specified).
|
||
|
|
* `kubeconfig` **KUBECONFIG [CONTEXT]** authenticates the connection to a remote
|
||
|
|
k8s cluster using a kubeconfig file. **[CONTEXT]** is optional, if not set,
|
||
|
|
then the current context specified in kubeconfig will be used. It supports
|
||
|
|
TLS, username and password, or token-based authentication. This option is
|
||
|
|
ignored if connecting in-cluster (i.e., the endpoint is not specified).
|
||
|
|
* `namespace` **[NAMESPACE]** only reads `Forward` resources from the namespace
|
||
|
|
listed. If this option is omitted then it will read from the default
|
||
|
|
namespace, `kube-system`. If this option is specified without any namespaces
|
||
|
|
listed it will read from all namespaces. **Note**: It is recommended to limit
|
||
|
|
the namespace (e.g to `kube-system`) because this can be potentially misused.
|
||
|
|
It is ideal to keep the level of write access similar to the `coredns`
|
||
|
|
configmap in the `kube-system` namespace.
|
||
|
|
|
||
|
|
## Ready
|
||
|
|
|
||
|
|
This plugin reports readiness to the ready plugin. This will happen after it has
|
||
|
|
synced to the Kubernetes API.
|
||
|
|
|
||
|
|
## Ordering
|
||
|
|
|
||
|
|
Forward behavior can be defined in three ways, via a Server Block, via the
|
||
|
|
*forwardcrd* plugin, and via the *forward* plugin. If more than one of these
|
||
|
|
methods is employed and a query falls within the zone of more than one, CoreDNS
|
||
|
|
selects which one to use based on the following precedence:
|
||
|
|
Corefile Server Block -> *forwardcrd* plugin -> *forward* plugin.
|
||
|
|
|
||
|
|
When `Forward` CRDs and Server Blocks define stub domains that are used,
|
||
|
|
domains defined in the Corefile take precedence (in the event of zone overlap).
|
||
|
|
e.g. if the
|
||
|
|
domain `example.com` is defined in the Corefile as a stub domain, and a
|
||
|
|
`Forward` CRD record defined for `sub.example.com`, then `sub.example.com` would
|
||
|
|
get forwarded to the upstream defined in the Corefile, not the `Forward` CRD.
|
||
|
|
|
||
|
|
When using *forwardcrd* and *forward* plugins in the same Server Block, `Forward` CRDs
|
||
|
|
take precedence over the *forward* plugin defined in the same Server Block.
|
||
|
|
e.g. if a `Forward` CRD is defined for `.`, then no queries would be
|
||
|
|
forwarded to the upstream defined in the *forward* plugin of the same Server Block.
|
||
|
|
|
||
|
|
## Metrics
|
||
|
|
|
||
|
|
`Forward` CRD metrics are all labeled in a single zone (the zone of the enclosing
|
||
|
|
Server Block).
|
||
|
|
|
||
|
|
## Forward CRD
|
||
|
|
|
||
|
|
The `Forward` CRD has the following spec properties:
|
||
|
|
|
||
|
|
* **from** is the base domain to match for the request to be forwarded.
|
||
|
|
* **to** are the destination endpoints to forward to. The **to** syntax allows
|
||
|
|
you to specify a protocol, `tls://9.9.9.9` or `dns://` (or no protocol) for
|
||
|
|
plain DNS. The number of upstreams is limited to 15.
|
||
|
|
|
||
|
|
## Examples
|
||
|
|
|
||
|
|
The following is an example of how you might modify the `coredns` ConfigMap of
|
||
|
|
your cluster to enable the *forwardcrd* plugin. The following configuration will
|
||
|
|
watch and read any `Forward` CRD records in the `kube-system` namespace for
|
||
|
|
*any* zone name. This means you are able to able to create a `Forward` CRD
|
||
|
|
record that overlaps an existing zone.
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
---
|
||
|
|
apiVersion: v1
|
||
|
|
kind: ConfigMap
|
||
|
|
metadata:
|
||
|
|
name: coredns
|
||
|
|
namespace: kube-system
|
||
|
|
data:
|
||
|
|
Corefile: |
|
||
|
|
.:53 {
|
||
|
|
errors
|
||
|
|
health {
|
||
|
|
lameduck 5s
|
||
|
|
}
|
||
|
|
ready
|
||
|
|
kubernetes cluster.local in-addr.arpa ip6.arpa {
|
||
|
|
pods insecure
|
||
|
|
fallthrough in-addr.arpa ip6.arpa
|
||
|
|
ttl 30
|
||
|
|
}
|
||
|
|
forwardcrd
|
||
|
|
prometheus :9153
|
||
|
|
forward . /etc/resolv.conf
|
||
|
|
cache 30
|
||
|
|
loop
|
||
|
|
reload
|
||
|
|
loadbalance
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
When you want to enable the *forwardcrd* plugin, you will need to apply the CRD
|
||
|
|
as well.
|
||
|
|
|
||
|
|
```
|
||
|
|
kubectl apply -f ./manifests/crds/coredns.io_forwards.yaml
|
||
|
|
```
|
||
|
|
|
||
|
|
Also note that the `ClusterRole` for CoreDNS must include:
|
||
|
|
In addition, you will need to modify the `system:coredns` ClusterRole in the
|
||
|
|
`kube-system` namespace to include the following:
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
rules:
|
||
|
|
- apiGroups:
|
||
|
|
- coredns.io
|
||
|
|
resources:
|
||
|
|
- forwards
|
||
|
|
verbs:
|
||
|
|
- list
|
||
|
|
- watch
|
||
|
|
```
|
||
|
|
|
||
|
|
This will allow CoreDNS to watch and list `Forward` CRD records from the
|
||
|
|
Kubernetes API.
|
||
|
|
|
||
|
|
Now you can configure stubdomains by creating `Forward` CRD records in the
|
||
|
|
`kube-system` namespace.
|
||
|
|
|
||
|
|
For example, if a cluster operator has a [Consul](https://www.consul.io/) domain
|
||
|
|
server located at 10.150.0.1, and all Consul names have the suffix
|
||
|
|
.consul.local. To configure this, the cluster administrator creates the
|
||
|
|
following record:
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
---
|
||
|
|
apiVersion: coredns.io/v1alpha1
|
||
|
|
kind: Forward
|
||
|
|
metadata:
|
||
|
|
name: consul-local
|
||
|
|
namespace: kube-system
|
||
|
|
spec:
|
||
|
|
from: consul.local
|
||
|
|
to:
|
||
|
|
- 10.150.0.1
|
||
|
|
```
|
||
|
|
|
||
|
|
### Additional examples
|
||
|
|
|
||
|
|
Allow `Forward` resources to be created for any zone and only read `Forward`
|
||
|
|
resources from the `kube-system` namespace:
|
||
|
|
|
||
|
|
~~~ txt
|
||
|
|
. {
|
||
|
|
forwardcrd
|
||
|
|
}
|
||
|
|
~~~
|
||
|
|
|
||
|
|
Allow `Forward` resources to be created for the `.local` zone and only read
|
||
|
|
`Forward` resources from the `kube-system` namespace:
|
||
|
|
|
||
|
|
|
||
|
|
~~~ txt
|
||
|
|
. {
|
||
|
|
forwardcrd local
|
||
|
|
}
|
||
|
|
~~~
|
||
|
|
|
||
|
|
or:
|
||
|
|
|
||
|
|
~~~ txt
|
||
|
|
local {
|
||
|
|
forwardcrd
|
||
|
|
}
|
||
|
|
~~~
|
||
|
|
|
||
|
|
Only read `Forward` resources from the `dns-system` namespace:
|
||
|
|
|
||
|
|
~~~ txt
|
||
|
|
. {
|
||
|
|
forwardcrd {
|
||
|
|
namespace dns-system
|
||
|
|
}
|
||
|
|
}
|
||
|
|
~~~
|
||
|
|
|
||
|
|
Read `Forward` resources from all namespaces:
|
||
|
|
|
||
|
|
~~~ txt
|
||
|
|
. {
|
||
|
|
forwardcrd {
|
||
|
|
namespace
|
||
|
|
}
|
||
|
|
}
|
||
|
|
~~~
|
||
|
|
|
||
|
|
Connect to Kubernetes with CoreDNS running outside the cluster:
|
||
|
|
|
||
|
|
~~~ txt
|
||
|
|
. {
|
||
|
|
forwardcrd {
|
||
|
|
endpoint https://k8s-endpoint:8443
|
||
|
|
tls cert key cacert
|
||
|
|
}
|
||
|
|
}
|
||
|
|
~~~
|
||
|
|
|
||
|
|
or:
|
||
|
|
|
||
|
|
~~~ txt
|
||
|
|
. {
|
||
|
|
forwardcrd {
|
||
|
|
kubeconfig ./kubeconfig
|
||
|
|
}
|
||
|
|
}
|
||
|
|
~~~
|