mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Add embedded DNS server support for host loopback resolver
Signed-off-by: Santhosh Manohar <santhosh@docker.com>
This commit is contained in:
parent
3d32070063
commit
bf832ec2a7
6 changed files with 55 additions and 17 deletions
|
@ -918,6 +918,7 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (s
|
|||
populatedEndpoints: map[string]struct{}{},
|
||||
config: containerConfig{},
|
||||
controller: c,
|
||||
extDNS: []extDNSEntry{},
|
||||
}
|
||||
}
|
||||
sBox = sb
|
||||
|
|
|
@ -4,10 +4,14 @@ import (
|
|||
"regexp"
|
||||
)
|
||||
|
||||
// IPLocalhost is a regex patter for localhost IP address range.
|
||||
// IPLocalhost is a regex pattern for IPv4 or IPv6 loopback range.
|
||||
const IPLocalhost = `((127\.([0-9]{1,3}\.){2}[0-9]{1,3})|(::1)$)`
|
||||
|
||||
// IPv4Localhost is a regex pattern for IPv4 localhost address range.
|
||||
const IPv4Localhost = `(127\.([0-9]{1,3}\.){2}[0-9]{1,3})`
|
||||
|
||||
var localhostIPRegexp = regexp.MustCompile(IPLocalhost)
|
||||
var localhostIPv4Regexp = regexp.MustCompile(IPv4Localhost)
|
||||
|
||||
// IsLocalhost returns true if ip matches the localhost IP regular expression.
|
||||
// Used for determining if nameserver settings are being passed which are
|
||||
|
@ -15,3 +19,8 @@ var localhostIPRegexp = regexp.MustCompile(IPLocalhost)
|
|||
func IsLocalhost(ip string) bool {
|
||||
return localhostIPRegexp.MatchString(ip)
|
||||
}
|
||||
|
||||
// IsIPv4Localhost returns true if ip matches the IPv4 localhost regular expression.
|
||||
func IsIPv4Localhost(ip string) bool {
|
||||
return localhostIPv4Regexp.MatchString(ip)
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ type Resolver interface {
|
|||
NameServer() string
|
||||
// SetExtServers configures the external nameservers the resolver
|
||||
// should use to forward queries
|
||||
SetExtServers([]string)
|
||||
SetExtServers([]extDNSEntry)
|
||||
// ResolverOptions returns resolv.conf options that should be set
|
||||
ResolverOptions() []string
|
||||
}
|
||||
|
@ -69,7 +69,8 @@ const (
|
|||
)
|
||||
|
||||
type extDNSEntry struct {
|
||||
ipStr string
|
||||
ipStr string
|
||||
hostLoopback bool
|
||||
}
|
||||
|
||||
// resolver implements the Resolver interface
|
||||
|
@ -182,13 +183,13 @@ func (r *resolver) Stop() {
|
|||
r.queryLock = sync.Mutex{}
|
||||
}
|
||||
|
||||
func (r *resolver) SetExtServers(dns []string) {
|
||||
l := len(dns)
|
||||
func (r *resolver) SetExtServers(extDNS []extDNSEntry) {
|
||||
l := len(extDNS)
|
||||
if l > maxExtDNS {
|
||||
l = maxExtDNS
|
||||
}
|
||||
for i := 0; i < l; i++ {
|
||||
r.extDNSList[i].ipStr = dns[i]
|
||||
r.extDNSList[i] = extDNS[i]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -417,10 +418,14 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
|
|||
extConn, err = net.DialTimeout(proto, addr, extIOTimeout)
|
||||
}
|
||||
|
||||
execErr := r.backend.ExecFunc(extConnect)
|
||||
if execErr != nil {
|
||||
logrus.Warn(execErr)
|
||||
continue
|
||||
if extDNS.hostLoopback {
|
||||
extConnect()
|
||||
} else {
|
||||
execErr := r.backend.ExecFunc(extConnect)
|
||||
if execErr != nil {
|
||||
logrus.Warn(execErr)
|
||||
continue
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
logrus.Warnf("Connect failed: %s", err)
|
||||
|
|
|
@ -69,7 +69,7 @@ type sandbox struct {
|
|||
id string
|
||||
containerID string
|
||||
config containerConfig
|
||||
extDNS []string
|
||||
extDNS []extDNSEntry
|
||||
osSbox osl.Sandbox
|
||||
controller *controller
|
||||
resolver Resolver
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/libnetwork/etchosts"
|
||||
"github.com/docker/libnetwork/resolvconf"
|
||||
"github.com/docker/libnetwork/resolvconf/dns"
|
||||
"github.com/docker/libnetwork/types"
|
||||
)
|
||||
|
||||
|
@ -161,6 +162,20 @@ func (sb *sandbox) restorePath() {
|
|||
}
|
||||
}
|
||||
|
||||
func (sb *sandbox) setExternalResolvers(content []byte, addrType int, checkLoopback bool) {
|
||||
servers := resolvconf.GetNameservers(content, addrType)
|
||||
for _, ip := range servers {
|
||||
hostLoopback := false
|
||||
if checkLoopback {
|
||||
hostLoopback = dns.IsIPv4Localhost(ip)
|
||||
}
|
||||
sb.extDNS = append(sb.extDNS, extDNSEntry{
|
||||
ipStr: ip,
|
||||
hostLoopback: hostLoopback,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (sb *sandbox) setupDNS() error {
|
||||
var newRC *resolvconf.File
|
||||
|
||||
|
@ -208,7 +223,17 @@ func (sb *sandbox) setupDNS() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// After building the resolv.conf from the user config save the
|
||||
// external resolvers in the sandbox. Note that --dns 127.0.0.x
|
||||
// config refers to the loopback in the container namespace
|
||||
sb.setExternalResolvers(newRC.Content, types.IPv4, false)
|
||||
} else {
|
||||
// If the host resolv.conf file has 127.0.0.x container should
|
||||
// use the host restolver for queries. This is supported by the
|
||||
// docker embedded DNS server. Hence save the external resolvers
|
||||
// before filtering it out.
|
||||
sb.setExternalResolvers(currRC.Content, types.IPv4, true)
|
||||
|
||||
// Replace any localhost/127.* (at this point we have no info about ipv6, pass it as true)
|
||||
if newRC, err = resolvconf.FilterResolvDNS(currRC.Content, true); err != nil {
|
||||
return err
|
||||
|
@ -297,7 +322,6 @@ func (sb *sandbox) updateDNS(ipv6Enabled bool) error {
|
|||
|
||||
// Embedded DNS server has to be enabled for this sandbox. Rebuild the container's
|
||||
// resolv.conf by doing the following
|
||||
// - Save the external name servers in resolv.conf in the sandbox
|
||||
// - Add only the embedded server's IP to container's resolv.conf
|
||||
// - If the embedded server needs any resolv.conf options add it to the current list
|
||||
func (sb *sandbox) rebuildDNS() error {
|
||||
|
@ -306,10 +330,9 @@ func (sb *sandbox) rebuildDNS() error {
|
|||
return err
|
||||
}
|
||||
|
||||
// localhost entries have already been filtered out from the list
|
||||
// retain only the v4 servers in sb for forwarding the DNS queries
|
||||
sb.extDNS = resolvconf.GetNameservers(currRC.Content, types.IPv4)
|
||||
|
||||
if len(sb.extDNS) == 0 {
|
||||
sb.setExternalResolvers(currRC.Content, types.IPv4, false)
|
||||
}
|
||||
var (
|
||||
dnsList = []string{sb.resolver.NameServer()}
|
||||
dnsOptionsList = resolvconf.GetOptions(currRC.Content)
|
||||
|
|
|
@ -27,7 +27,7 @@ type sbState struct {
|
|||
dbExists bool
|
||||
Eps []epState
|
||||
EpPriority map[string]int
|
||||
ExtDNS []string
|
||||
ExtDNS []extDNSEntry
|
||||
}
|
||||
|
||||
func (sbs *sbState) Key() []string {
|
||||
|
|
Loading…
Reference in a new issue