Extend pre-existing address reclaim to docker containers

This commit is contained in:
Bryan Boreham committed 2017-02-13 11:30:34 +00:00
1 parent e26dbf11e9
commit 7075b5d9fd
4 files changed
+53 -22

No files matched your search

+3 -2
View File
@@ -77,8 +77,9 @@ type Allocator struct {
}
type PreClaim struct {
Ident string
Cidr address.CIDR
Ident string
IsContainer bool
Cidr address.CIDR
}
type Config struct {
+1 -1
View File
@@ -174,7 +174,7 @@ func TestAllocatorClaim(t *testing.T) {
)
preAddr, _ := address.ParseCIDR(testPre)
allocs, router, subnet := makeNetworkOfAllocators(2, universe, []PreClaim{{container1, preAddr}})
allocs, router, subnet := makeNetworkOfAllocators(2, universe, []PreClaim{{container1, true, preAddr}})
defer stopNetworkOfAllocators(allocs, router)
alloc := allocs[1]
addr1, _ := address.ParseCIDR(testAddr1)
+7 -6
View File
@@ -306,15 +306,16 @@ func main() {
}
trackerName = "awsvpc"
}
preClaims, err := findExistingAddresses(weavenet.WeaveBridgeName)
var allContainerIDs []string
if dockerCli != nil {
allContainerIDs, err = dockerCli.AllContainerIDs()
checkFatal(err)
}
preClaims, err := findExistingAddresses(dockerCli, allContainerIDs, weavenet.WeaveBridgeName)
checkFatal(err)
allocator, defaultSubnet = createAllocator(router, ipamConfig, preClaims, db, t, isKnownPeer)
observeContainers(allocator)
if dockerCli != nil {
ids, err := dockerCli.AllContainerIDs()
checkFatal(err)
allocator.PruneOwned(ids)
}
allocator.PruneOwned(allContainerIDs)
}
var (
+42 -13
View File
@@ -3,8 +3,11 @@ package main
import (
"net"
docker "github.com/fsouza/go-dockerclient"
"github.com/weaveworks/weave/api"
"github.com/weaveworks/weave/common"
weavedocker "github.com/weaveworks/weave/common/docker"
"github.com/weaveworks/weave/ipam"
weavenet "github.com/weaveworks/weave/net"
"github.com/weaveworks/weave/net/address"
@@ -17,38 +20,64 @@ func a(cidr *net.IPNet) address.CIDR {
// Get all the existing Weave IPs at startup, so we can stop IPAM
// giving out any as duplicates
func findExistingAddresses(bridgeName string) (addrs []ipam.PreClaim, err error) {
func findExistingAddresses(dockerCli *weavedocker.Client, containerIDs []string, bridgeName string) (addrs []ipam.PreClaim, err error) {
Log.Infof("Checking for pre-existing addresses on %s bridge", bridgeName)
// First get the address for the bridge
bridgeNetDev, err := weavenet.GetBridgeNetDev(bridgeName)
if err != nil {
return nil, err
}
for _, cidr := range bridgeNetDev.CIDRs {
Log.Infof("%s bridge has address %v", bridgeName, cidr)
addrs = append(addrs, ipam.PreClaim{Ident: "weave:expose", Cidr: a(cidr)})
}
add := func(cid string, isContainer bool, netDevs []weavenet.Dev) {
for _, netDev := range netDevs {
for _, cidr := range netDev.CIDRs {
Log.Infof("Found address %v for ID %s", cidr, cid)
addrs = append(addrs, ipam.PreClaim{Ident: cid, IsContainer: isContainer, Cidr: a(cidr)})
}
}
}
// Then find all veths connected to the bridge
peerIDs, err := weavenet.ConnectedToBridgeVethPeerIds(bridgeName)
if err != nil {
return nil, err
}
pids, err := common.AllPids("/proc")
if err != nil {
return nil, err
}
// Now iterate over all processes to see if they have a network namespace with an attached interface
for _, pid := range pids {
netDevs, err := weavenet.GetNetDevsByVethPeerIds(pid, peerIDs)
// Now iterate over all containers to see if they have a network
// namespace with an attached interface
if dockerCli != nil {
for _, cid := range containerIDs {
container, err := dockerCli.InspectContainer(cid)
if err != nil {
if _, ok := err.(*docker.NoSuchContainer); ok {
continue
}
return nil, err
}
if container.State.Pid != 0 {
netDevs, err := weavenet.GetNetDevsByVethPeerIds(container.State.Pid, peerIDs)
if err != nil {
return nil, err
}
add(cid, true, netDevs)
}
}
} else {
// If we don't have a Docker connection, iterate over all processes
pids, err := common.AllPids("/proc")
if err != nil {
return nil, err
}
for _, netDev := range netDevs {
for _, cidr := range netDev.CIDRs {
// We don't know the container ID, so use special magic string
addrs = append(addrs, ipam.PreClaim{Ident: api.NoContainerID, Cidr: a(cidr)})
for _, pid := range pids {
netDevs, err := weavenet.GetNetDevsByVethPeerIds(pid, peerIDs)
if err != nil {
return nil, err
}
add(api.NoContainerID, false, netDevs)
}
}
return addrs, nil