Use CoreDNS for everything and make directives dynamic
This moves CoreDNS from Kubernetes to the network tree and uses
it for OS-side resolution too. For this to work together with Kubernetes it now
contains a dynamic directive system which allows various parts of the OS
to register and unregister directives at runtime. This system is used to hook
Kubernetes and DHCP-supplied DNS servers into the configuration.
This also enables the hosts plugin to resolve the local hostname from within
CoreDNS to avoid querying external DNS servers for that (T773).
Test Plan:
CTS covers K8s-related tests, external resolution manually tested from
a container.
Bug: T860, T773
X-Origin-Diff: phab/D628
GitOrigin-RevId: f1729237f3d17d8801506f4d299b90e7dce0893a
diff --git a/core/internal/network/main.go b/core/internal/network/main.go
index c92b21a..31c0b68 100644
--- a/core/internal/network/main.go
+++ b/core/internal/network/main.go
@@ -32,6 +32,7 @@
"git.monogon.dev/source/nexantic.git/core/internal/common/supervisor"
"git.monogon.dev/source/nexantic.git/core/internal/network/dhcp"
+ "git.monogon.dev/source/nexantic.git/core/internal/network/dns"
)
const (
@@ -47,6 +48,7 @@
}
type Config struct {
+ CorednsRegistrationChan chan *dns.ExtraDirective
}
func New(config Config) *Service {
@@ -117,9 +119,8 @@
return fmt.Errorf("could not get DHCP Status: %w", err)
}
- if err := setResolvconf(status.DNS, []string{}); err != nil {
- s.logger.Warn("failed to set resolvconf", zap.Error(err))
- }
+ // We're currently never removing this directive just like we're not removing routes and IPs
+ s.config.CorednsRegistrationChan <- dns.NewUpstreamDirective(status.DNS)
if err := s.addNetworkRoutes(iface, status.Address, status.Gateway); err != nil {
s.logger.Warn("failed to add routes", zap.Error(err))
@@ -172,18 +173,34 @@
}
func (s *Service) Run(ctx context.Context) error {
+ logger := supervisor.Logger(ctx)
+ dnsSvc := dns.New(s.config.CorednsRegistrationChan)
+ supervisor.Run(ctx, "dns", dnsSvc.Run)
+ supervisor.Run(ctx, "interfaces", s.runInterfaces)
+
+ if err := ioutil.WriteFile("/proc/sys/net/ipv4/ip_forward", []byte("1\n"), 0644); err != nil {
+ logger.Panic("Failed to enable IPv4 forwarding", zap.Error(err))
+ }
+
+ // We're handling all DNS requests with CoreDNS, including local ones
+ if err := setResolvconf([]net.IP{{127, 0, 0, 1}}, []string{}); err != nil {
+ logger.Warn("failed to set resolvconf", zap.Error(err))
+ }
+
+ supervisor.Signal(ctx, supervisor.SignalHealthy)
+ supervisor.Signal(ctx, supervisor.SignalDone)
+ return nil
+}
+
+func (s *Service) runInterfaces(ctx context.Context) error {
s.logger = supervisor.Logger(ctx)
- s.logger.Info("Starting network service")
+ s.logger.Info("Starting network interface management")
links, err := netlink.LinkList()
if err != nil {
s.logger.Fatal("Failed to list network links", zap.Error(err))
}
- if err := ioutil.WriteFile("/proc/sys/net/ipv4/ip_forward", []byte("1\n"), 0644); err != nil {
- s.logger.Panic("Failed to enable IPv4 forwarding", zap.Error(err))
- }
-
var ethernetLinks []netlink.Link
for _, link := range links {
attrs := link.Attrs()