1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Vendor Libnetwork v0.7.0-rc.1

- Fixes https://github.com/docker/libnetwork/issues/1051
- Fixes https://github.com/docker/libnetwork/issues/985
- Fixes https://github.com/docker/libnetwork/issues/945
- Log time taken to set sandbox key
- Limit number of concurrent DNS queries

Signed-off-by: Madhu Venugopal <madhu@docker.com>
This commit is contained in:
Madhu Venugopal 2016-03-30 18:12:23 -07:00
parent c43deb2ea1
commit 90bb5301b5
11 changed files with 109 additions and 29 deletions

View file

@ -29,7 +29,7 @@ clone git github.com/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837
clone git github.com/imdario/mergo 0.2.1 clone git github.com/imdario/mergo 0.2.1
#get libnetwork packages #get libnetwork packages
clone git github.com/docker/libnetwork v0.7.0-dev.10 clone git github.com/docker/libnetwork v0.7.0-rc.1
clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4 clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4

View file

@ -1,5 +1,11 @@
# Changelog # Changelog
## 0.7.0-rc.1 (2016-03-30)
- Fixes https://github.com/docker/libnetwork/issues/985
- Fixes https://github.com/docker/libnetwork/issues/945
- Log time taken to set sandbox key
- Limit number of concurrent DNS queries
## 0.7.0-dev.10 (2016-03-21) ## 0.7.0-dev.10 (2016-03-21)
- Add IPv6 service discovery (AAAA records) in embedded DNS server - Add IPv6 service discovery (AAAA records) in embedded DNS server
- Honor enableIPv6 flag in network create for the IP allocation - Honor enableIPv6 flag in network create for the IP allocation

View file

@ -218,6 +218,9 @@ func (c *controller) ReloadConfiguration(cfgOptions ...config.Option) error {
return types.ForbiddenErrorf("cannot accept new configuration because it modifies an existing datastore client") return types.ForbiddenErrorf("cannot accept new configuration because it modifies an existing datastore client")
} }
} else { } else {
if err := c.initScopedStore(s, nSCfg); err != nil {
return err
}
update = true update = true
} }
} }
@ -229,10 +232,6 @@ func (c *controller) ReloadConfiguration(cfgOptions ...config.Option) error {
c.cfg = cfg c.cfg = cfg
c.Unlock() c.Unlock()
if err := c.initStores(); err != nil {
return err
}
if c.discovery == nil && c.cfg.Cluster.Watcher != nil { if c.discovery == nil && c.cfg.Cluster.Watcher != nil {
if err := c.initDiscovery(c.cfg.Cluster.Watcher); err != nil { if err := c.initDiscovery(c.cfg.Cluster.Watcher); err != nil {
log.Errorf("Failed to Initialize Discovery after configuration update: %v", err) log.Errorf("Failed to Initialize Discovery after configuration update: %v", err)

View file

@ -129,8 +129,8 @@ func (d *driver) Leave(nid, eid string) error {
if d.notifyCh != nil { if d.notifyCh != nil {
d.notifyCh <- ovNotify{ d.notifyCh <- ovNotify{
action: "leave", action: "leave",
nid: nid, nw: n,
eid: eid, ep: ep,
} }
} }

View file

@ -149,9 +149,9 @@ func (n *network) joinSubnetSandbox(s *subnet) error {
func (n *network) leaveSandbox() { func (n *network) leaveSandbox() {
n.Lock() n.Lock()
defer n.Unlock()
n.joinCnt-- n.joinCnt--
if n.joinCnt != 0 { if n.joinCnt != 0 {
n.Unlock()
return return
} }
@ -162,15 +162,14 @@ func (n *network) leaveSandbox() {
for _, s := range n.subnets { for _, s := range n.subnets {
s.once = &sync.Once{} s.once = &sync.Once{}
} }
n.Unlock()
n.destroySandbox() n.destroySandbox()
} }
// to be called while holding network lock
func (n *network) destroySandbox() { func (n *network) destroySandbox() {
sbox := n.sandbox() if n.sbox != nil {
if sbox != nil { for _, iface := range n.sbox.Info().Interfaces() {
for _, iface := range sbox.Info().Interfaces() {
if err := iface.Remove(); err != nil { if err := iface.Remove(); err != nil {
logrus.Debugf("Remove interface %s failed: %v", iface.SrcName(), err) logrus.Debugf("Remove interface %s failed: %v", iface.SrcName(), err)
} }
@ -197,8 +196,8 @@ func (n *network) destroySandbox() {
} }
} }
sbox.Destroy() n.sbox.Destroy()
n.setSandbox(nil) n.sbox = nil
} }
} }

View file

@ -12,8 +12,8 @@ import (
type ovNotify struct { type ovNotify struct {
action string action string
eid string ep *endpoint
nid string nw *network
} }
type logWriter struct{} type logWriter struct{}
@ -81,13 +81,12 @@ func (d *driver) serfJoin(neighIP string) error {
} }
func (d *driver) notifyEvent(event ovNotify) { func (d *driver) notifyEvent(event ovNotify) {
n := d.network(event.nid) ep := event.ep
ep := n.endpoint(event.eid)
ePayload := fmt.Sprintf("%s %s %s %s", event.action, ep.addr.IP.String(), ePayload := fmt.Sprintf("%s %s %s %s", event.action, ep.addr.IP.String(),
net.IP(ep.addr.Mask).String(), ep.mac.String()) net.IP(ep.addr.Mask).String(), ep.mac.String())
eName := fmt.Sprintf("jl %s %s %s", d.serfInstance.LocalMember().Addr.String(), eName := fmt.Sprintf("jl %s %s %s", d.serfInstance.LocalMember().Addr.String(),
event.nid, event.eid) event.nw.id, ep.id)
if err := d.serfInstance.UserEvent(eName, []byte(ePayload), true); err != nil { if err := d.serfInstance.UserEvent(eName, []byte(ePayload), true); err != nil {
logrus.Errorf("Sending user event failed: %v\n", err) logrus.Errorf("Sending user event failed: %v\n", err)

View file

@ -180,13 +180,24 @@ func (d *driver) nodeJoin(node string, self bool) {
} }
func (d *driver) pushLocalEndpointEvent(action, nid, eid string) { func (d *driver) pushLocalEndpointEvent(action, nid, eid string) {
n := d.network(nid)
if n == nil {
logrus.Debugf("Error pushing local endpoint event for network %s", nid)
return
}
ep := n.endpoint(eid)
if ep == nil {
logrus.Debugf("Error pushing local endpoint event for ep %s / %s", nid, eid)
return
}
if !d.isSerfAlive() { if !d.isSerfAlive() {
return return
} }
d.notifyCh <- ovNotify{ d.notifyCh <- ovNotify{
action: "join", action: "join",
nid: nid, nw: n,
eid: eid, ep: ep,
} }
} }

View file

@ -547,6 +547,10 @@ func (ep *endpoint) Leave(sbox Sandbox, options ...EndpointOption) error {
sb.joinLeaveStart() sb.joinLeaveStart()
defer sb.joinLeaveEnd() defer sb.joinLeaveEnd()
if sb.resolver != nil {
sb.resolver.FlushExtServers()
}
return ep.sbLeave(sb, false, options...) return ep.sbLeave(sb, false, options...)
} }

View file

@ -28,8 +28,12 @@ type Resolver interface {
// NameServer() returns the IP of the DNS resolver for the // NameServer() returns the IP of the DNS resolver for the
// containers. // containers.
NameServer() string NameServer() string
// To configure external name servers the resolver should use // SetExtServers configures the external nameservers the resolver
// should use to forward queries
SetExtServers([]string) SetExtServers([]string)
// FlushExtServers clears the cached UDP connections to external
// nameservers
FlushExtServers()
// ResolverOptions returns resolv.conf options that should be set // ResolverOptions returns resolv.conf options that should be set
ResolverOptions() []string ResolverOptions() []string
} }
@ -43,6 +47,8 @@ const (
maxExtDNS = 3 //max number of external servers to try maxExtDNS = 3 //max number of external servers to try
extIOTimeout = 3 * time.Second extIOTimeout = 3 * time.Second
defaultRespSize = 512 defaultRespSize = 512
maxConcurrent = 50
logInterval = 2 * time.Second
) )
type extDNSEntry struct { type extDNSEntry struct {
@ -60,6 +66,9 @@ type resolver struct {
tcpServer *dns.Server tcpServer *dns.Server
tcpListen *net.TCPListener tcpListen *net.TCPListener
err error err error
count int32
tStamp time.Time
queryLock sync.Mutex
} }
func init() { func init() {
@ -139,11 +148,15 @@ func (r *resolver) Start() error {
return nil return nil
} }
func (r *resolver) Stop() { func (r *resolver) FlushExtServers() {
for i := 0; i < maxExtDNS; i++ { for i := 0; i < maxExtDNS; i++ {
r.extDNSList[i].extConn = nil r.extDNSList[i].extConn = nil
r.extDNSList[i].extOnce = sync.Once{} r.extDNSList[i].extOnce = sync.Once{}
} }
}
func (r *resolver) Stop() {
r.FlushExtServers()
if r.server != nil { if r.server != nil {
r.server.Shutdown() r.server.Shutdown()
@ -154,6 +167,9 @@ func (r *resolver) Stop() {
r.conn = nil r.conn = nil
r.tcpServer = nil r.tcpServer = nil
r.err = fmt.Errorf("setup not done yet") r.err = fmt.Errorf("setup not done yet")
r.tStamp = time.Time{}
r.count = 0
r.queryLock = sync.Mutex{}
} }
func (r *resolver) SetExtServers(dns []string) { func (r *resolver) SetExtServers(dns []string) {
@ -320,7 +336,8 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
if extDNS.ipStr == "" { if extDNS.ipStr == "" {
break break
} }
log.Debugf("Querying ext dns %s:%s for %s[%d]", proto, extDNS.ipStr, name, query.Question[0].Qtype) log.Debugf("Query %s[%d] from %s, forwarding to %s:%s", name, query.Question[0].Qtype,
w.LocalAddr().String(), proto, extDNS.ipStr)
extConnect := func() { extConnect := func() {
addr := fmt.Sprintf("%s:%d", extDNS.ipStr, 53) addr := fmt.Sprintf("%s:%d", extDNS.ipStr, 53)
@ -358,6 +375,15 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
extConn.SetDeadline(time.Now().Add(extIOTimeout)) extConn.SetDeadline(time.Now().Add(extIOTimeout))
co := &dns.Conn{Conn: extConn} co := &dns.Conn{Conn: extConn}
if r.concurrentQueryInc() == false {
old := r.tStamp
r.tStamp = time.Now()
if r.tStamp.Sub(old) > logInterval {
log.Errorf("More than %v concurrent queries from %s", maxConcurrent, w.LocalAddr().String())
}
continue
}
defer func() { defer func() {
if proto == "tcp" { if proto == "tcp" {
co.Close() co.Close()
@ -365,11 +391,13 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
}() }()
err = co.WriteMsg(query) err = co.WriteMsg(query)
if err != nil { if err != nil {
r.concurrentQueryDec()
log.Debugf("Send to DNS server failed, %s", err) log.Debugf("Send to DNS server failed, %s", err)
continue continue
} }
resp, err = co.ReadMsg() resp, err = co.ReadMsg()
r.concurrentQueryDec()
if err != nil { if err != nil {
log.Debugf("Read from DNS server failed, %s", err) log.Debugf("Read from DNS server failed, %s", err)
continue continue
@ -389,3 +417,23 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
log.Errorf("error writing resolver resp, %s", err) log.Errorf("error writing resolver resp, %s", err)
} }
} }
func (r *resolver) concurrentQueryInc() bool {
r.queryLock.Lock()
defer r.queryLock.Unlock()
if r.count == maxConcurrent {
return false
}
r.count++
return true
}
func (r *resolver) concurrentQueryDec() bool {
r.queryLock.Lock()
defer r.queryLock.Unlock()
if r.count == 0 {
return false
}
r.count--
return true
}

View file

@ -7,6 +7,7 @@ import (
"net" "net"
"strings" "strings"
"sync" "sync"
"time"
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
"github.com/docker/libnetwork/etchosts" "github.com/docker/libnetwork/etchosts"
@ -536,6 +537,11 @@ func (sb *sandbox) resolveName(req string, networkName string, epList []*endpoin
} }
func (sb *sandbox) SetKey(basePath string) error { func (sb *sandbox) SetKey(basePath string) error {
start := time.Now()
defer func() {
log.Debugf("sandbox set key processing took %s for container %s", time.Now().Sub(start), sb.ContainerID())
}()
if basePath == "" { if basePath == "" {
return types.BadRequestErrorf("invalid sandbox key") return types.BadRequestErrorf("invalid sandbox key")
} }

View file

@ -7,6 +7,18 @@ import (
"github.com/docker/libnetwork/datastore" "github.com/docker/libnetwork/datastore"
) )
func (c *controller) initScopedStore(scope string, scfg *datastore.ScopeCfg) error {
store, err := datastore.NewDataStore(scope, scfg)
if err != nil {
return err
}
c.Lock()
c.stores = append(c.stores, store)
c.Unlock()
return nil
}
func (c *controller) initStores() error { func (c *controller) initStores() error {
c.Lock() c.Lock()
if c.cfg == nil { if c.cfg == nil {
@ -18,13 +30,9 @@ func (c *controller) initStores() error {
c.Unlock() c.Unlock()
for scope, scfg := range scopeConfigs { for scope, scfg := range scopeConfigs {
store, err := datastore.NewDataStore(scope, scfg) if err := c.initScopedStore(scope, scfg); err != nil {
if err != nil {
return err return err
} }
c.Lock()
c.stores = append(c.stores, store)
c.Unlock()
} }
c.startWatch() c.startWatch()