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

Initial implementation of ForwardCRD plugin #4512

Merged
merged 8 commits into from
Nov 12, 2021

Conversation

christianang
Copy link
Contributor

@christianang christianang commented Mar 9, 2021

1. Why is this pull request needed and what does it do?

This PR is the initial implementation of the KubernetesCRD plugin that sets out to implement #4382. Namely, it allows CoreDNS to watch a DNSZone CRD to configure stub-domains for Kubernetes clusters.

Edit: This PR has been updated from just the readme to the initial implementation of the plugin.

2. Which issues (if any) are related?

#4382

3. Which documentation changes (if any) need to be made?

4. Does this introduce a backward incompatible change or deprecation?

plugin/forward/instance.go Outdated Show resolved Hide resolved
plugin/forward/instance.go Outdated Show resolved Hide resolved
plugin/kubernetescrd/kubernetescrd.go Outdated Show resolved Hide resolved
plugin/kubernetescrd/kubernetescrd.go Outdated Show resolved Hide resolved
plugin/kubernetescrd/kubernetescrd.go Outdated Show resolved Hide resolved
plugin/kubernetescrd/kubernetescrd.go Outdated Show resolved Hide resolved
@christianang christianang force-pushed the add-kubernetes-crd-plugin branch 2 times, most recently from 53e9e14 to 855394a Compare March 15, 2021 21:19
@christianang christianang changed the title Initial Readme/Spike of KubernetesCRD plugin Initial Readme of KubernetesCRD plugin Mar 15, 2021
@christianang christianang marked this pull request as ready for review March 15, 2021 21:30
@miekg
Copy link
Member

miekg commented Mar 16, 2021

very interesting idea. What the data model for the zone data? And how do you envision lookup taking weird DNS stuff into account, like wildcards and in-zone CNAMEs? You want to depend on file.Lookup ? Would not be a bad idea to make the interface suitable for different backends (long standing idea in another issue somewhere)

@christianang
Copy link
Contributor Author

Currently I'm thinking this would handle the very narrow case of forwarding dns messages to other dns servers based on the zone name (basically implementing stub-domains, but through crds). Not currently thinking of handling any individual records for a zone. I imagine handling requests at that point would be similar to how CoreDNS handles dns mux-ing now for server blocks. E.g there will be a map of zone names that map to forward plugins and we would loop through the map looking for a match, popping off subdomains of the zone until a match is found and we call that forward plugin's ServeDNS function. I think this sidesteps a lot of dns complexity, but let me know if I'm overlooking something.

I can envision that this plugin can become more flexible, through additional crd(s). Not sure what this might look like yet, since there are probably a few ways to slice it so starting with a pretty limited crd.

plugin/kubernetescrd/controller.go Outdated Show resolved Hide resolved
plugin/kubernetescrd/controller.go Outdated Show resolved Hide resolved
@christianang christianang changed the title Initial Readme of KubernetesCRD plugin Initial implementation of KubernetesCRD plugin Mar 22, 2021
@christianang
Copy link
Contributor Author

I've updated the PR to include my initial implementation of the plugin. Apologies for what is now a massive PR, it felt like it made sense to continue iterating on the single PR, but let me know if you prefer breaking this down in any way. I did try and keep commits focused, which may help digest the PR.

Would appreciate feedback, I imagine being new to this codebase there were design decisions I made that might not be the best approach for a given problem, so let me know if you spot ways this can be improved.

One design decision that might be worth pointing out, I added a function to the forward plugin NewWithConfig that allows the kubernetescrd plugin to create instances of forward on-demand. This duplicated some code, which could be "DRY"-ed up, but in favor of not making too far reaching changes to the code base I left it duplicated and am happy with making follow up PRs to de-duplicate code if the approach I used makes sense.

Copy link
Member

@chrisohaver chrisohaver left a comment

Choose a reason for hiding this comment

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

Thanks @christianang! Lots to digest, but from what I understand, it looks good so far.

core/dnsserver/zdirectives.go Outdated Show resolved Hide resolved
// New returns a new Forward.
func New() *Forward {
f := &Forward{maxfails: 2, tlsConfig: new(tls.Config), expire: defaultExpire, p: new(random), from: ".", hcInterval: hcInterval, opts: options{forceTCP: false, preferUDP: false, hcRecursionDesired: true}}
return f
}

// NewWithConfig returns a new Forward configured by the provided
// ForwardConfig.
func NewWithConfig(config ForwardConfig) (*Forward, error) {
Copy link
Member

Choose a reason for hiding this comment

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

I think I like this direction. I presume forward's existing Corefile parsing functions will also be refactored to create a ForwardConfig, and then use NewWithConfig to create the Forward struct. This also opens the way for other plugins to reuse the "forwarding" function of the forward plugin (e.g. adding a forwarding action to coredns/policy).

@miekg, WDYT?

Copy link

Choose a reason for hiding this comment

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

@chrisohaver I love this idea and implemented a similar solution in #4583. Anyway config parsing logic should be separated from plugin logic according to the single-responsibility principle. It will not only decouple components but also allow to thoroughly cover the parsing functionality with tests.

plugin/kubernetescrd/controller.go Outdated Show resolved Hide resolved
Co-authored-by: Aidan Obley <aobley@vmware.com>

Signed-off-by: Christian Ang <angc@vmware.com>
- Place forwardcrd before forward plugin in plugin list. This will avoid
forward from preventing the forwardcrd plugin from handling any queries
in the case of having a default upstream forwarder in a server block (as
is the case in the default kubernetes Corefile).

Co-authored-by: Aidan Obley <aobley@vmware.com>

Signed-off-by: Christian Ang <angc@vmware.com>
Signed-off-by: Christian Ang <angc@vmware.com>
- allows external packages to instanciate forward plugins

Co-authored-by: Aidan Obley <aobley@vmware.com>

Signed-off-by: Christian Ang <angc@vmware.com>
@christianang christianang force-pushed the add-kubernetes-crd-plugin branch 2 times, most recently from 8ab82af to 7dc40a0 Compare August 16, 2021 18:32
christianang and others added 3 commits August 16, 2021 18:43
- add a Kubernetes controller that can read Forward CRs
- instances of the forward plugin are created based on Forward CRs from
the Kubernetes controller
- DNS requests are handled by calling matching Forward plugin instances
based on zone name
- Defaults to the kube-system namespace to align with Corefile RBAC

Signed-off-by: Christian Ang <angc@vmware.com>

Use klog v2 in forwardcrd plugin
Co-authored-by: Christian Ang <angc@vmware.com>

Signed-off-by: Edwin Xie <exie@vmware.com>
- to ensure that the bitsize is 32 for later casting to uint32

Signed-off-by: Christian Ang <angc@vmware.com>
@christianang
Copy link
Contributor Author

Hi, revisiting this PR since its been some time. @miekg do you think you can give this a review? I would appreciate it.

@chrisohaver
Copy link
Member

@christianang, can you add this plugin and yourself as the owner, in the CODEOWNERS file?

@chrisohaver chrisohaver mentioned this pull request Sep 9, 2021
3 tasks
Signed-off-by: Christian Ang <angc@vmware.com>
@christianang
Copy link
Contributor Author

Done!

@chrisohaver
Copy link
Member

chrisohaver commented Oct 25, 2021

@miekg, is it OK with you if we merge this new plugin without your review, or would you like to review it first?

@miekg
Copy link
Member

miekg commented Nov 12, 2021 via email

@chrisohaver chrisohaver merged commit 2e6953c into coredns:master Nov 12, 2021
@miekg
Copy link
Member

miekg commented Nov 12, 2021

ok, wsn't expediting that,. Think this is perfectly fine as an external plugin. Never saw the use-case why this needs to be in coredns proper

@chrisohaver
Copy link
Member

chrisohaver commented Nov 12, 2021

ok, wsn't expediting that,. Think this is perfectly fine as an external plugin. Never saw the use-case why this needs to be in coredns proper

Sorry - I misinterpreted your response as an OK. I'll revert it.

@chrisohaver
Copy link
Member

@christianang, sorry for the mixup. If you have time, please register the plugin as an external plugin on coredns.io ...

@chrisohaver
Copy link
Member

chrisohaver commented Nov 12, 2021

... please register the plugin as an external plugin on coredns.io ...

Sorry - its been so long since I had looked at the code... quickly scanning it over, I remember now that this plugin required some refactoring of the forward plugin... so it cannot stand as-is as an external plugin unless we also create a new external plugin from a copy of the forward plugin with those modifications ... or we merge the mods to the forward plugin.

chrisohaver added a commit that referenced this pull request Nov 12, 2021
@johnbelamaric
Copy link
Member

Alternatives to consider, that (maybe) won't require changes to any existing plugins:

  1. Operator that consumes CRDs and rewrites the ConfigMap of the Corefile;
  2. New input flag(s) that read read directly from k8s CRDs to create a special CaddyfileInput a-la this example: https://github.com/coredns/learning-coredns/blob/master/dnscached/main.go (may require using CoreDNS as a library rather than directly)
  3. Some sort of tweak to coredns/caddyfile.Dispenser to construct a Corefile out of CRD input (similar to (2) but different approach internally

Of course (1) requires zero changes to CoreDNS.

@chrisohaver
Copy link
Member

chrisohaver commented Nov 13, 2021

1 was originally suggested, but I had suggested a coredns plugin idea. Sorry folks!

@christianang
Copy link
Contributor Author

Sad to hear. I'll hit pause on making any attempts at this for now since (as @chrisohaver brought up), this does require a refactor to the forward plugin so it can be used by the newly introduced crd plugin so just making it an external plugin will take some effort.

I am open to continuing discussion on the feature and how best to implement if someone wants to continue (perhaps it makes sense to reopen and continue on #4382?), but for now I'll put down the effort.

jinglina pushed a commit to jinglina/coredns that referenced this pull request Dec 23, 2021
* Add forwardcrd plugin README.md

Co-authored-by: Aidan Obley <aobley@vmware.com>

Signed-off-by: Christian Ang <angc@vmware.com>

* Create forwardcrd plugin

- Place forwardcrd before forward plugin in plugin list. This will avoid
forward from preventing the forwardcrd plugin from handling any queries
in the case of having a default upstream forwarder in a server block (as
is the case in the default kubernetes Corefile).

Co-authored-by: Aidan Obley <aobley@vmware.com>

Signed-off-by: Christian Ang <angc@vmware.com>

* Add Forward CRD

Signed-off-by: Christian Ang <angc@vmware.com>

* Add NewWithConfig to forward plugin

- allows external packages to instanciate forward plugins

Co-authored-by: Aidan Obley <aobley@vmware.com>

Signed-off-by: Christian Ang <angc@vmware.com>

* ForwardCRD plugin handles requests for Forward CRs

- add a Kubernetes controller that can read Forward CRs
- instances of the forward plugin are created based on Forward CRs from
the Kubernetes controller
- DNS requests are handled by calling matching Forward plugin instances
based on zone name
- Defaults to the kube-system namespace to align with Corefile RBAC

Signed-off-by: Christian Ang <angc@vmware.com>

Use klog v2 in forwardcrd plugin

* Refactor forward setup to use NewWithConfig

Co-authored-by: Christian Ang <angc@vmware.com>

Signed-off-by: Edwin Xie <exie@vmware.com>

* Use ParseInt instead of Atoi

- to ensure that the bitsize is 32 for later casting to uint32

Signed-off-by: Christian Ang <angc@vmware.com>

* Add @christianang to CODEOWNERS for forwardcrd

Signed-off-by: Christian Ang <angc@vmware.com>

Co-authored-by: Edwin Xie <exie@vmware.com>
Signed-off-by: jinglinax@163.com <jinglinax@163.com>
jinglina pushed a commit to jinglina/coredns that referenced this pull request Dec 23, 2021
…oredns#4981)

This reverts commit 2e6953c.

Signed-off-by: jinglinax@163.com <jinglinax@163.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants