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{}{},
|
populatedEndpoints: map[string]struct{}{},
|
||||||
config: containerConfig{},
|
config: containerConfig{},
|
||||||
controller: c,
|
controller: c,
|
||||||
|
extDNS: []extDNSEntry{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sBox = sb
|
sBox = sb
|
||||||
|
|
|
@ -4,10 +4,14 @@ import (
|
||||||
"regexp"
|
"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)$)`
|
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 localhostIPRegexp = regexp.MustCompile(IPLocalhost)
|
||||||
|
var localhostIPv4Regexp = regexp.MustCompile(IPv4Localhost)
|
||||||
|
|
||||||
// IsLocalhost returns true if ip matches the localhost IP regular expression.
|
// IsLocalhost returns true if ip matches the localhost IP regular expression.
|
||||||
// Used for determining if nameserver settings are being passed which are
|
// 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 {
|
func IsLocalhost(ip string) bool {
|
||||||
return localhostIPRegexp.MatchString(ip)
|
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
|
NameServer() string
|
||||||
// SetExtServers configures the external nameservers the resolver
|
// SetExtServers configures the external nameservers the resolver
|
||||||
// should use to forward queries
|
// should use to forward queries
|
||||||
SetExtServers([]string)
|
SetExtServers([]extDNSEntry)
|
||||||
// ResolverOptions returns resolv.conf options that should be set
|
// ResolverOptions returns resolv.conf options that should be set
|
||||||
ResolverOptions() []string
|
ResolverOptions() []string
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,8 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type extDNSEntry struct {
|
type extDNSEntry struct {
|
||||||
ipStr string
|
ipStr string
|
||||||
|
hostLoopback bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolver implements the Resolver interface
|
// resolver implements the Resolver interface
|
||||||
|
@ -182,13 +183,13 @@ func (r *resolver) Stop() {
|
||||||
r.queryLock = sync.Mutex{}
|
r.queryLock = sync.Mutex{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *resolver) SetExtServers(dns []string) {
|
func (r *resolver) SetExtServers(extDNS []extDNSEntry) {
|
||||||
l := len(dns)
|
l := len(extDNS)
|
||||||
if l > maxExtDNS {
|
if l > maxExtDNS {
|
||||||
l = maxExtDNS
|
l = maxExtDNS
|
||||||
}
|
}
|
||||||
for i := 0; i < l; i++ {
|
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)
|
extConn, err = net.DialTimeout(proto, addr, extIOTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
execErr := r.backend.ExecFunc(extConnect)
|
if extDNS.hostLoopback {
|
||||||
if execErr != nil {
|
extConnect()
|
||||||
logrus.Warn(execErr)
|
} else {
|
||||||
continue
|
execErr := r.backend.ExecFunc(extConnect)
|
||||||
|
if execErr != nil {
|
||||||
|
logrus.Warn(execErr)
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Warnf("Connect failed: %s", err)
|
logrus.Warnf("Connect failed: %s", err)
|
||||||
|
|
|
@ -69,7 +69,7 @@ type sandbox struct {
|
||||||
id string
|
id string
|
||||||
containerID string
|
containerID string
|
||||||
config containerConfig
|
config containerConfig
|
||||||
extDNS []string
|
extDNS []extDNSEntry
|
||||||
osSbox osl.Sandbox
|
osSbox osl.Sandbox
|
||||||
controller *controller
|
controller *controller
|
||||||
resolver Resolver
|
resolver Resolver
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/libnetwork/etchosts"
|
"github.com/docker/libnetwork/etchosts"
|
||||||
"github.com/docker/libnetwork/resolvconf"
|
"github.com/docker/libnetwork/resolvconf"
|
||||||
|
"github.com/docker/libnetwork/resolvconf/dns"
|
||||||
"github.com/docker/libnetwork/types"
|
"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 {
|
func (sb *sandbox) setupDNS() error {
|
||||||
var newRC *resolvconf.File
|
var newRC *resolvconf.File
|
||||||
|
|
||||||
|
@ -208,7 +223,17 @@ func (sb *sandbox) setupDNS() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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 {
|
} 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)
|
// 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 {
|
if newRC, err = resolvconf.FilterResolvDNS(currRC.Content, true); err != nil {
|
||||||
return err
|
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
|
// Embedded DNS server has to be enabled for this sandbox. Rebuild the container's
|
||||||
// resolv.conf by doing the following
|
// 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
|
// - 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
|
// - If the embedded server needs any resolv.conf options add it to the current list
|
||||||
func (sb *sandbox) rebuildDNS() error {
|
func (sb *sandbox) rebuildDNS() error {
|
||||||
|
@ -306,10 +330,9 @@ func (sb *sandbox) rebuildDNS() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// localhost entries have already been filtered out from the list
|
if len(sb.extDNS) == 0 {
|
||||||
// retain only the v4 servers in sb for forwarding the DNS queries
|
sb.setExternalResolvers(currRC.Content, types.IPv4, false)
|
||||||
sb.extDNS = resolvconf.GetNameservers(currRC.Content, types.IPv4)
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
dnsList = []string{sb.resolver.NameServer()}
|
dnsList = []string{sb.resolver.NameServer()}
|
||||||
dnsOptionsList = resolvconf.GetOptions(currRC.Content)
|
dnsOptionsList = resolvconf.GetOptions(currRC.Content)
|
||||||
|
|
|
@ -27,7 +27,7 @@ type sbState struct {
|
||||||
dbExists bool
|
dbExists bool
|
||||||
Eps []epState
|
Eps []epState
|
||||||
EpPriority map[string]int
|
EpPriority map[string]int
|
||||||
ExtDNS []string
|
ExtDNS []extDNSEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sbs *sbState) Key() []string {
|
func (sbs *sbState) Key() []string {
|
||||||
|
|
Loading…
Reference in a new issue