Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a9fae5892 | ||
|
|
f66b0cc0aa | ||
|
|
e7f30106c0 | ||
|
|
86d2800b59 | ||
|
|
e65006042d | ||
|
|
65efc89b78 | ||
|
|
ae38834507 | ||
|
|
4261777613 | ||
|
|
7bc089f5c5 | ||
|
|
c46e3e8cf7 | ||
|
|
180d554205 | ||
|
|
a450d2e741 | ||
|
|
d528196033 | ||
|
|
0da2cbf84e | ||
|
|
20f981bc42 | ||
|
|
9a5514ffe0 | ||
|
|
439b4ad190 | ||
|
|
9a9c06966b | ||
|
|
b3f9baac8f | ||
|
|
bb961489b0 | ||
|
|
d6ae1f8375 | ||
|
|
5a1361167e | ||
|
|
4d5172f67e | ||
|
|
6f01c31458 | ||
|
|
6cfb208f3f | ||
|
|
3074892f1b | ||
|
|
b05d977cf9 | ||
|
|
36d183d988 | ||
|
|
b154fd56fb | ||
|
|
3419f69246 | ||
|
|
8e23301028 | ||
|
|
72724ee389 | ||
|
|
ae59a053b1 | ||
|
|
e71919226b | ||
|
|
6c5dd75216 | ||
|
|
23095728f5 | ||
|
|
498dacb4d2 | ||
|
|
b373a069e9 | ||
|
|
1d67e2f955 | ||
|
|
9a6935bf40 | ||
|
|
921ffefd90 | ||
|
|
a4fccd43eb | ||
|
|
48e1a8295b | ||
|
|
890c8c1905 | ||
|
|
38d50ce6fb | ||
|
|
14768d6947 | ||
|
|
b96399b563 | ||
|
|
d8c008dc7d | ||
|
|
b2ae5f4f4b | ||
|
|
ba871d7855 | ||
|
|
a0c8fc2ddb | ||
|
|
2a12053122 | ||
|
|
1860f21efb | ||
|
|
541adf6bb1 | ||
|
|
a71e90ddb8 | ||
|
|
60f4b3cdb8 | ||
|
|
0c249fa126 | ||
|
|
db1b57900b | ||
|
|
12b4898b3d | ||
|
|
f5f9bab77c | ||
|
|
ba7aa674d1 | ||
|
|
f670be4315 | ||
|
|
a658861fde | ||
|
|
192e5a1f79 | ||
|
|
475b15e372 | ||
|
|
d2ed91ccc8 | ||
|
|
333f4a1d3c | ||
|
|
832fe2f0b0 | ||
|
|
ea76185873 | ||
|
|
51c3ea184a | ||
|
|
692bccc4fc | ||
|
|
51c2a0d732 | ||
|
|
0205adcedb | ||
|
|
a3fd36e2bb |
No files matched your search
@@ -1,3 +1,47 @@
|
||||
## Release 2.2.0
|
||||
|
||||
This release improves the way Weave Net configures Linux network
|
||||
devices and network filter rules, so that it is more robust in the face
|
||||
of unexpected changes in its environment. #3204,#3224
|
||||
|
||||
As a consequence of these changes, the `weave attach` command will now
|
||||
fail unless the Weave Net daemon is up and running - previously it was
|
||||
possible to run independently as long as you managed all IP addresses
|
||||
yourself.
|
||||
|
||||
## Other improvements
|
||||
|
||||
* Update library miekg/dns for CVE-2017-15133 (details under embargo) #3223,#3227
|
||||
* Reduce the volume of logging from weave-npc #3183
|
||||
* Add ability to set log level for Docker "v2" plugin, and change
|
||||
default log level from DEBUG to INFO #3197
|
||||
* Downgrade log messages about Discovery and Expiration to DEBUG level #3202,#3203
|
||||
* Use command-line parameter for WeaveDNS address in Docker proxy #3196
|
||||
|
||||
## Bug fixes
|
||||
|
||||
* Ensure that rules to block traffic for NetworkPolicy are placed
|
||||
ahead of rules that Kubernetes has added to allow other traffic #3209,#3210
|
||||
|
||||
## Build and test
|
||||
|
||||
* Update CI tests to use Kubernetes 1.9.2 #3229
|
||||
* Remove "daily update" from test VMs that only run for a few minutes #3224
|
||||
|
||||
## External Contributors
|
||||
|
||||
Thanks to the following contributors:
|
||||
@vetal4444
|
||||
|
||||
[Full list of changes](https://github.com/weaveworks/weave/milestone/67?closed=1)
|
||||
|
||||
|
||||
## Release 2.1.3
|
||||
|
||||
This release fixes a race-condition in the IP reclaim code for weave-kube
|
||||
where two nodes could end up fighting over the same space and break
|
||||
connectivity #3190, #3192
|
||||
|
||||
## Release 2.1.2
|
||||
|
||||
This release fixes a couple of bugs discovered since the release of Weave Net 2.1.0
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
DOCKER_VERSION=17.06
|
||||
KUBERNETES_VERSION=1.7.8
|
||||
KUBERNETES_CNI_VERSION=0.5.1
|
||||
KUBERNETES_VERSION=1.9.2
|
||||
KUBERNETES_CNI_VERSION=0.6.0
|
||||
+2
-2
@@ -196,7 +196,7 @@ publish() {
|
||||
|
||||
if [ "$RELEASE_TYPE" = 'PRERELEASE' ] ; then
|
||||
echo "== Building and pushing plugin"
|
||||
make UPDATE_LATEST=$IS_MAINLINE SUDO=$SUDO WEAVE_VERSION=$VERSION DOCKERHUB_USER=$DOCKERHUB_USER plugin_publish
|
||||
make UPDATE_LATEST=false SUDO=$SUDO WEAVE_VERSION=$VERSION DOCKERHUB_USER=$DOCKERHUB_USER plugin_publish
|
||||
echo "** Plugin built and pushed"
|
||||
|
||||
echo "== Tagging and pushing images on docker hub as user $DOCKERHUB_USER"
|
||||
@@ -232,7 +232,7 @@ publish() {
|
||||
echo '** Sanity checks OK for publishing tag' $LATEST_TAG as $DOCKERHUB_USER/weave:$VERSION
|
||||
|
||||
echo "== Building and pushing plugin"
|
||||
make UPDATE_LATEST=$IS_MAINLINE SUDO=$SUDO WEAVE_VERSION=$VERSION DOCKERHUB_USER=$DOCKERHUB_USER plugin_publish
|
||||
make UPDATE_LATEST=true SUDO=$SUDO WEAVE_VERSION=$VERSION DOCKERHUB_USER=$DOCKERHUB_USER plugin_publish
|
||||
echo "** Plugin built and pushed"
|
||||
|
||||
echo "== Tagging and pushing images on docker hub as user $DOCKERHUB_USER"
|
||||
|
||||
@@ -75,6 +75,14 @@ func DeleteDatapath(dpname string) error {
|
||||
}
|
||||
|
||||
func AddDatapathInterface(dpname string, ifname string) error {
|
||||
return addDatapathInterface(dpname, ifname, false)
|
||||
}
|
||||
|
||||
func AddDatapathInterfaceIfNotExist(dpname string, ifname string) error {
|
||||
return addDatapathInterface(dpname, ifname, true)
|
||||
}
|
||||
|
||||
func addDatapathInterface(dpname, ifname string, ignoreIfExist bool) error {
|
||||
dpif, err := odp.NewDpif()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -87,5 +95,9 @@ func AddDatapathInterface(dpname string, ifname string) error {
|
||||
}
|
||||
|
||||
_, err = dp.CreateVport(odp.NewNetdevVportSpec(ifname))
|
||||
if ignoreIfExist && err == odp.NetlinkError(syscall.EEXIST) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
@@ -133,8 +133,8 @@ Finally, for **Mainline** releases only:
|
||||
* Close the [milestone](https://github.com/weaveworks/weave/milestones) in GitHub and create the next milestone
|
||||
* Update the `#weavenetwork` topic heading on freenode (requires 'chanops' permission)
|
||||
* For a mainline release vX.Y.0, create a release branch X.Y from the
|
||||
tag and push to GitHub - this will result in X.Y.0 site docs being
|
||||
published to https://www.weave.works
|
||||
tag, push to GitHub and set [WEAVE_NET_REV](https://github.com/weaveworks/website-next/blob/master/Makefile)
|
||||
to X.Y via a PR - this will result in X.Y.0 site docs being published to https://www.weave.works
|
||||
* Add the new version of `weave-net` to the checkpoint system at
|
||||
https://checkpoint-api.weave.works/admin
|
||||
* File a PR to update the version of the daemonset at
|
||||
|
||||
+78
-36
@@ -227,12 +227,19 @@ func (config *BridgeConfig) configuredBridgeType() Bridge {
|
||||
}
|
||||
|
||||
func EnsureBridge(procPath string, config *BridgeConfig, log *logrus.Logger) (Bridge, error) {
|
||||
bridgeType, err := ExistingBridgeType(config.WeaveBridgeName, config.DatapathName)
|
||||
if bridgeType != nil || err != nil {
|
||||
return bridgeType, err
|
||||
existingBridgeType, err := ExistingBridgeType(config.WeaveBridgeName, config.DatapathName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bridgeType := config.configuredBridgeType()
|
||||
|
||||
if existingBridgeType != nil && bridgeType.String() != existingBridgeType.String() {
|
||||
return nil,
|
||||
fmt.Errorf("Existing bridge type %q is different than requested %q. Please do 'weave reset' and try again",
|
||||
existingBridgeType, bridgeType)
|
||||
}
|
||||
|
||||
bridgeType = config.configuredBridgeType()
|
||||
for {
|
||||
if err := bridgeType.init(config); err != nil {
|
||||
if errors.Cause(err) == errBridgeNotSupported {
|
||||
@@ -288,7 +295,7 @@ func (b bridgeImpl) initPrep(config *BridgeConfig) error {
|
||||
config.MTU = 65535
|
||||
}
|
||||
b.bridge = &netlink.Bridge{LinkAttrs: linkAttrs}
|
||||
if err = netlink.LinkAdd(b.bridge); err != nil {
|
||||
if err := LinkAddIfNotExist(b.bridge); err != nil {
|
||||
return errors.Wrapf(err, "creating bridge %q", config.WeaveBridgeName)
|
||||
}
|
||||
if err := netlink.LinkSetHardwareAddr(b.bridge, mac); err != nil {
|
||||
@@ -320,7 +327,7 @@ func (b bridgeImpl) init(config *BridgeConfig) error {
|
||||
if err := b.initPrep(config); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := CreateAndAttachVeth(BridgeIfName, PcapIfName, config.WeaveBridgeName, config.MTU, true, func(veth netlink.Link) error {
|
||||
if _, err := CreateAndAttachVeth(BridgeIfName, PcapIfName, config.WeaveBridgeName, config.MTU, true, false, func(veth netlink.Link) error {
|
||||
return netlink.LinkSetUp(veth)
|
||||
}); err != nil {
|
||||
return errors.Wrap(err, "creating pcap veth pair")
|
||||
@@ -370,11 +377,11 @@ func (bf bridgedFastdpImpl) init(config *BridgeConfig) error {
|
||||
if err := bf.bridgeImpl.initPrep(config); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := CreateAndAttachVeth(BridgeIfName, DatapathIfName, config.WeaveBridgeName, config.MTU, true, func(veth netlink.Link) error {
|
||||
if _, err := CreateAndAttachVeth(BridgeIfName, DatapathIfName, config.WeaveBridgeName, config.MTU, true, false, func(veth netlink.Link) error {
|
||||
if err := netlink.LinkSetUp(veth); err != nil {
|
||||
return errors.Wrapf(err, "setting link up on %q", veth.Attrs().Name)
|
||||
}
|
||||
if err := odp.AddDatapathInterface(bf.datapathName, veth.Attrs().Name); err != nil {
|
||||
if err := odp.AddDatapathInterfaceIfNotExist(bf.datapathName, veth.Attrs().Name); err != nil {
|
||||
return errors.Wrapf(err, "adding interface %q to datapath %q", veth.Attrs().Name, bf.datapathName)
|
||||
}
|
||||
return nil
|
||||
@@ -394,7 +401,7 @@ func (bf bridgedFastdpImpl) attach(veth *netlink.Veth) error {
|
||||
}
|
||||
|
||||
func (f fastdpImpl) attach(veth *netlink.Veth) error {
|
||||
return odp.AddDatapathInterface(f.datapathName, veth.Attrs().Name)
|
||||
return odp.AddDatapathInterfaceIfNotExist(f.datapathName, veth.Attrs().Name)
|
||||
}
|
||||
|
||||
func configureIPTables(config *BridgeConfig) error {
|
||||
@@ -402,12 +409,13 @@ func configureIPTables(config *BridgeConfig) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "creating iptables object")
|
||||
}
|
||||
|
||||
// The order among weave filter/FORWARD rules is important!
|
||||
fwdRules := make([][]string, 0)
|
||||
|
||||
if config.DockerBridgeName != "" {
|
||||
if config.WeaveBridgeName != config.DockerBridgeName {
|
||||
err := ipt.Insert("filter", "FORWARD", 1, "-i", config.DockerBridgeName, "-o", config.WeaveBridgeName, "-j", "DROP")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fwdRules = append(fwdRules, []string{"-i", config.DockerBridgeName, "-o", config.WeaveBridgeName, "-j", "DROP"})
|
||||
}
|
||||
|
||||
dockerBridgeIP, err := FindBridgeIP(config.DockerBridgeName, nil)
|
||||
@@ -438,45 +446,42 @@ func configureIPTables(config *BridgeConfig) error {
|
||||
if config.NPC {
|
||||
// Steer traffic via the NPC
|
||||
_ = ipt.NewChain("filter", "WEAVE-NPC") // ignore error because it might already exist
|
||||
// If WEAVE-NPC chain doesn't exist then next line will fail
|
||||
if err = ipt.AppendUnique("filter", "FORWARD", "-o", config.WeaveBridgeName, "-j", "WEAVE-NPC"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = ipt.AppendUnique("filter", "FORWARD", "-o", config.WeaveBridgeName, "-m", "state", "--state", "NEW", "-j", "NFLOG", "--nflog-group", "86"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = ipt.AppendUnique("filter", "FORWARD", "-o", config.WeaveBridgeName, "-j", "DROP"); err != nil {
|
||||
return err
|
||||
}
|
||||
// If WEAVE-NPC chain doesn't exist then creating a rule in the chain will fail
|
||||
fwdRules = append(fwdRules,
|
||||
[][]string{
|
||||
{"-o", config.WeaveBridgeName,
|
||||
"-m", "comment", "--comment", "NOTE: this must go before '-j KUBE-FORWARD'",
|
||||
"-j", "WEAVE-NPC"},
|
||||
{"-o", config.WeaveBridgeName, "-m", "state", "--state", "NEW", "-j", "NFLOG", "--nflog-group", "86"},
|
||||
{"-o", config.WeaveBridgeName, "-j", "DROP"},
|
||||
}...)
|
||||
} else {
|
||||
// Work around the situation where there are no rules allowing traffic
|
||||
// across our bridge. E.g. ufw
|
||||
if err = ipt.AppendUnique("filter", "FORWARD", "-i", config.WeaveBridgeName, "-o", config.WeaveBridgeName, "-j", "ACCEPT"); err != nil {
|
||||
return err
|
||||
}
|
||||
fwdRules = append(fwdRules, []string{"-i", config.WeaveBridgeName, "-o", config.WeaveBridgeName, "-j", "ACCEPT"})
|
||||
}
|
||||
|
||||
if !config.NPC {
|
||||
// Create a chain for allowing ingress traffic when the bridge is exposed
|
||||
_ = ipt.NewChain("filter", "WEAVE-EXPOSE")
|
||||
if err = ipt.AppendUnique("filter", "FORWARD", "-o", config.WeaveBridgeName, "-j", "WEAVE-EXPOSE"); err != nil {
|
||||
return err
|
||||
}
|
||||
fwdRules = append(fwdRules, []string{"-o", config.WeaveBridgeName, "-j", "WEAVE-EXPOSE"})
|
||||
}
|
||||
|
||||
// Forward from weave to the rest of the world
|
||||
if err = ipt.AppendUnique("filter", "FORWARD", "-i", config.WeaveBridgeName, "!", "-o", config.WeaveBridgeName, "-j", "ACCEPT"); err != nil {
|
||||
return err
|
||||
}
|
||||
fwdRules = append(fwdRules, []string{"-i", config.WeaveBridgeName, "!", "-o", config.WeaveBridgeName, "-j", "ACCEPT"})
|
||||
// and allow replies back
|
||||
if err = ipt.AppendUnique("filter", "FORWARD", "-o", config.WeaveBridgeName, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"); err != nil {
|
||||
fwdRules = append(fwdRules, []string{"-o", config.WeaveBridgeName, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"})
|
||||
|
||||
if err := ensureRulesAtTop("filter", "FORWARD", fwdRules, ipt); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// create a chain for masquerading
|
||||
if err = ipt.ClearChain("nat", "WEAVE"); err != nil {
|
||||
return errors.Wrap(err, "clearing WEAVE chain")
|
||||
}
|
||||
//
|
||||
// NB: we do not clear the chain to preserve existing rules
|
||||
// inserted by "weave expose".
|
||||
_ = ipt.NewChain("nat", "WEAVE")
|
||||
|
||||
return ipt.AppendUnique("nat", "POSTROUTING", "-j", "WEAVE")
|
||||
}
|
||||
|
||||
@@ -487,3 +492,40 @@ func linkSetUpByName(linkName string) error {
|
||||
}
|
||||
return netlink.LinkSetUp(link)
|
||||
}
|
||||
|
||||
// ensureRulesAtTop ensures the presence of given iptables rules.
|
||||
//
|
||||
// If any rule from the list is missing, the function deletes all given
|
||||
// rules and re-inserts them at the top of the chain to ensure the order of the rules.
|
||||
func ensureRulesAtTop(table, chain string, rulespecs [][]string, ipt *iptables.IPTables) error {
|
||||
allFound := true
|
||||
|
||||
for _, rs := range rulespecs {
|
||||
found, err := ipt.Exists(table, chain, rs...)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "ipt.Exists(%s, %s, %s)", table, chain, rs)
|
||||
}
|
||||
if !found {
|
||||
allFound = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// All rules exist, do nothing.
|
||||
if allFound {
|
||||
return nil
|
||||
}
|
||||
|
||||
for pos, rs := range rulespecs {
|
||||
// If any is missing, then delete all, as we need to preserve the order of
|
||||
// given rules. Ignore errors, as rule might not exist.
|
||||
if !allFound {
|
||||
ipt.Delete(table, chain, rs...)
|
||||
}
|
||||
if err := ipt.Insert(table, chain, pos+1, rs...); err != nil {
|
||||
return errors.Wrapf(err, "ipt.Append(%s, %s, %s)", table, chain, rs)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
func LinkAddIfNotExist(link netlink.Link) error {
|
||||
err := netlink.LinkAdd(link)
|
||||
if err != nil && err == syscall.EEXIST {
|
||||
return nil
|
||||
}
|
||||
return errors.Wrapf(err, "creating link %q", link)
|
||||
}
|
||||
+8
-3
@@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
// create and attach a veth to the Weave bridge
|
||||
func CreateAndAttachVeth(name, peerName, bridgeName string, mtu int, keepTXOn bool, init func(peer netlink.Link) error) (*netlink.Veth, error) {
|
||||
func CreateAndAttachVeth(name, peerName, bridgeName string, mtu int, keepTXOn bool, errIfLinkExist bool, init func(peer netlink.Link) error) (*netlink.Veth, error) {
|
||||
bridge, err := netlink.LinkByName(bridgeName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(`bridge "%s" not present; did you launch weave?`, bridgeName)
|
||||
@@ -28,7 +28,12 @@ func CreateAndAttachVeth(name, peerName, bridgeName string, mtu int, keepTXOn bo
|
||||
MTU: mtu},
|
||||
PeerName: peerName,
|
||||
}
|
||||
if err := netlink.LinkAdd(veth); err != nil {
|
||||
|
||||
linkAdd := LinkAddIfNotExist
|
||||
if errIfLinkExist {
|
||||
linkAdd = netlink.LinkAdd
|
||||
}
|
||||
if err := linkAdd(veth); err != nil {
|
||||
return nil, fmt.Errorf(`could not create veth pair %s-%s: %s`, name, peerName, err)
|
||||
}
|
||||
|
||||
@@ -116,7 +121,7 @@ func AttachContainer(netNSPath, id, ifName, bridgeName string, mtu int, withMult
|
||||
id = id[:maxIDLen] // trim passed ID if too long
|
||||
}
|
||||
name, peerName := vethPrefix+"pl"+id, vethPrefix+"pg"+id
|
||||
veth, err := CreateAndAttachVeth(name, peerName, bridgeName, mtu, keepTXOn, func(veth netlink.Link) error {
|
||||
veth, err := CreateAndAttachVeth(name, peerName, bridgeName, mtu, keepTXOn, true, func(veth netlink.Link) error {
|
||||
if err := netlink.LinkSetNsFd(veth, int(ns)); err != nil {
|
||||
return fmt.Errorf("failed to move veth to container netns: %s", err)
|
||||
}
|
||||
|
||||
+49
@@ -4,7 +4,56 @@ import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// Return JSON suitable for logging an API object.
|
||||
func js(v interface{}) string {
|
||||
// Get the raw JSON
|
||||
a, _ := json.Marshal(v)
|
||||
// Convert this back into a tree of key-value maps
|
||||
var m map[string]interface{}
|
||||
if err := json.Unmarshal(a, &m); err != nil {
|
||||
// If that didn't work, just return the raw version
|
||||
return string(a)
|
||||
}
|
||||
// Trim some bulk, and potentially sensitive areas
|
||||
withMap(m["metadata"], func(status map[string]interface{}) {
|
||||
delete(status, "ownerReferences")
|
||||
})
|
||||
withMap(m["spec"], func(spec map[string]interface{}) {
|
||||
delete(spec, "tolerations")
|
||||
delete(spec, "volumes")
|
||||
rangeSlice(spec["containers"], func(container map[string]interface{}) {
|
||||
delete(container, "args")
|
||||
delete(container, "command")
|
||||
delete(container, "env")
|
||||
delete(container, "livenessProbe")
|
||||
delete(container, "resources")
|
||||
delete(container, "securityContext")
|
||||
delete(container, "volumeMounts")
|
||||
})
|
||||
})
|
||||
withMap(m["status"], func(status map[string]interface{}) {
|
||||
delete(status, "containerStatuses")
|
||||
})
|
||||
// Now marshall what's left to JSON
|
||||
a, _ = json.Marshal(m)
|
||||
return string(a)
|
||||
}
|
||||
|
||||
// Helper function: operate on a map node from a tree of key-value maps
|
||||
func withMap(m interface{}, f func(map[string]interface{})) {
|
||||
if v, ok := m.(map[string]interface{}); ok {
|
||||
f(v)
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function: operate on all nodes under i which is a slice in a
|
||||
// tree of key-value maps
|
||||
func rangeSlice(i interface{}, f func(map[string]interface{})) {
|
||||
if s, ok := i.([]interface{}); ok {
|
||||
for _, v := range s {
|
||||
if m, ok := v.(map[string]interface{}); ok {
|
||||
f(m)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +134,7 @@ func (driver *driver) CreateEndpoint(create *api.CreateEndpointRequest) (*api.Cr
|
||||
|
||||
// create veths. note we assume endpoint IDs are unique in the first 9 chars
|
||||
name, peerName := vethPair(create.EndpointID)
|
||||
if _, err := weavenet.CreateAndAttachVeth(name, peerName, weavenet.WeaveBridgeName, 0, false, nil); err != nil {
|
||||
if _, err := weavenet.CreateAndAttachVeth(name, peerName, weavenet.WeaveBridgeName, 0, false, true, nil); err != nil {
|
||||
return nil, driver.error("JoinEndpoint", "%s", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -73,8 +73,10 @@ const (
|
||||
retryPeriod = time.Second * 2
|
||||
jitterFactor = 1.0
|
||||
|
||||
// Prefix all our annotation keys with this string so they don't clash with anyone else's
|
||||
KubePeersPrefix = "kube-peers.weave.works/"
|
||||
// KubePeersAnnotationKey is the default annotation key
|
||||
KubePeersAnnotationKey = "kube-peers.weave.works/peers"
|
||||
KubePeersAnnotationKey = KubePeersPrefix + "peers"
|
||||
)
|
||||
|
||||
func (cml *configMapAnnotations) Init() error {
|
||||
@@ -130,46 +132,59 @@ func (cml *configMapAnnotations) UpdatePeerList(list peerList) error {
|
||||
return cml.UpdateAnnotation(KubePeersAnnotationKey, string(recordBytes))
|
||||
}
|
||||
|
||||
func (cml *configMapAnnotations) UpdateAnnotation(key, value string) error {
|
||||
// Clean up a string so it meets the Kubernetes requiremements for Annotation keys:
|
||||
// name part must consist of alphanumeric characters, '-', '_' or '.', and must
|
||||
// start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc')
|
||||
func cleanKey(key string) string {
|
||||
buf := []byte(key)
|
||||
for i, c := range buf {
|
||||
if (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '.' || c == '/' {
|
||||
continue
|
||||
}
|
||||
buf[i] = '_'
|
||||
}
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
func (cml *configMapAnnotations) GetAnnotation(key string) (string, bool) {
|
||||
value, ok := cml.cm.Annotations[cleanKey(key)]
|
||||
return value, ok
|
||||
}
|
||||
|
||||
func (cml *configMapAnnotations) UpdateAnnotation(key, value string) (err error) {
|
||||
if cml.cm == nil {
|
||||
return errors.New("endpoint not initialized, call Init first")
|
||||
}
|
||||
cm := cml.cm
|
||||
cm.Annotations[key] = value
|
||||
cm, err := cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm)
|
||||
if err == nil {
|
||||
cml.cm = cm
|
||||
}
|
||||
// speculatively change the state, then replace with whatever comes back
|
||||
// from Update(), which will be the latest on the server whatever happened
|
||||
cml.cm.Annotations[cleanKey(key)] = value
|
||||
cml.cm, err = cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm)
|
||||
return err
|
||||
}
|
||||
|
||||
func (cml *configMapAnnotations) RemoveAnnotation(key string) error {
|
||||
func (cml *configMapAnnotations) RemoveAnnotation(key string) (err error) {
|
||||
if cml.cm == nil {
|
||||
return errors.New("endpoint not initialized, call Init first")
|
||||
}
|
||||
cm := cml.cm
|
||||
delete(cm.Annotations, key)
|
||||
cm, err := cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm)
|
||||
if err == nil {
|
||||
cml.cm = cm
|
||||
}
|
||||
// speculatively change the state, then replace with whatever comes back
|
||||
// from Update(), which will be the latest on the server whatever happened
|
||||
delete(cml.cm.Annotations, cleanKey(key))
|
||||
cml.cm, err = cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm)
|
||||
return err
|
||||
}
|
||||
|
||||
func (cml *configMapAnnotations) RemoveAnnotationsWithValue(valueToRemove string) error {
|
||||
func (cml *configMapAnnotations) RemoveAnnotationsWithValue(valueToRemove string) (err error) {
|
||||
if cml.cm == nil {
|
||||
return errors.New("endpoint not initialized, call Init first")
|
||||
}
|
||||
cm := cml.cm
|
||||
for key, value := range cm.Annotations {
|
||||
// speculatively change the state, then replace with whatever comes back
|
||||
// from Update(), which will be the latest on the server whatever happened
|
||||
for key, value := range cml.cm.Annotations {
|
||||
if value == valueToRemove {
|
||||
delete(cm.Annotations, key)
|
||||
delete(cml.cm.Annotations, key) // don't need to clean this key as it came from the map
|
||||
}
|
||||
}
|
||||
cm, err := cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm)
|
||||
if err == nil {
|
||||
cml.cm = cm
|
||||
}
|
||||
cml.cm, err = cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,9 @@ func checkIamInPeerList(cml *configMapAnnotations, c *kubernetes.Clientset, peer
|
||||
// Kubernetes, remove it from Weave IPAM
|
||||
func reclaimRemovedPeers(weave *weaveapi.Client, cml *configMapAnnotations, nodes []nodeInfo, myPeerName string) error {
|
||||
for {
|
||||
if err := cml.Init(); err != nil {
|
||||
return err
|
||||
}
|
||||
// 1. Compare peers stored in the peerList against all peers reported by k8s now.
|
||||
storedPeerList, err := cml.GetPeerList()
|
||||
if err != nil {
|
||||
@@ -119,7 +122,7 @@ func reclaimRemovedPeers(weave *weaveapi.Client, cml *configMapAnnotations, node
|
||||
common.Log.Debugln("[kube-peers] Preparing to remove disappeared peer", peer)
|
||||
okToRemove := false
|
||||
// 3. Check if there is an existing annotation with key X
|
||||
if existingAnnotation, found := cml.cm.Annotations[peer.PeerName]; found {
|
||||
if existingAnnotation, found := cml.GetAnnotation(KubePeersPrefix + peer.PeerName); found {
|
||||
common.Log.Debugln("[kube-peers] Existing annotation", existingAnnotation)
|
||||
// 4. If annotation already contains my identity, ok;
|
||||
if existingAnnotation == myPeerName {
|
||||
@@ -128,14 +131,16 @@ func reclaimRemovedPeers(weave *weaveapi.Client, cml *configMapAnnotations, node
|
||||
} else {
|
||||
// 5. If non-existent, write an annotation with key X and contents "my identity"
|
||||
common.Log.Debugln("[kube-peers] Noting I plan to remove ", peer.PeerName)
|
||||
if err := cml.UpdateAnnotation(peer.PeerName, myPeerName); err == nil {
|
||||
if err := cml.UpdateAnnotation(KubePeersPrefix+peer.PeerName, myPeerName); err == nil {
|
||||
okToRemove = true
|
||||
} else {
|
||||
common.Log.Debugln("[kube-peers] error from UpdateAnnotation: ", err)
|
||||
}
|
||||
}
|
||||
if okToRemove {
|
||||
// 6. If step 4 or 5 succeeded, rmpeer X
|
||||
result, err := weave.RmPeer(peer.PeerName)
|
||||
common.Log.Infoln("[kube-peers] rmpeer of", peer.PeerName, ":", result)
|
||||
common.Log.Infof("[kube-peers] rmpeer of %s: %s", peer.PeerName, result)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -146,15 +151,12 @@ func reclaimRemovedPeers(weave *weaveapi.Client, cml *configMapAnnotations, node
|
||||
}
|
||||
// 7a. Remove X from peerList
|
||||
storedPeerList.remove(peer.PeerName)
|
||||
common.Log.Infoln("[kube-peers] Removing peer ", peer.PeerName, ". Expecting to remove linked annotation next.")
|
||||
if err := cml.UpdatePeerList(*storedPeerList); err != nil {
|
||||
return err
|
||||
}
|
||||
common.Log.Infoln("[kube-peers] Removing annotation ", peer.PeerName)
|
||||
// 7b. Remove annotation with key X
|
||||
return cml.RemoveAnnotation(peer.PeerName)
|
||||
return cml.RemoveAnnotation(KubePeersPrefix + peer.PeerName)
|
||||
})
|
||||
common.Log.Debugln("[kube-peers] Finished removal of ", peer.PeerName)
|
||||
}
|
||||
// 8. If step 5 failed due to optimistic lock conflict, stop: someone else is handling X
|
||||
|
||||
|
||||
@@ -50,6 +50,14 @@
|
||||
}
|
||||
],
|
||||
"env": [
|
||||
{
|
||||
"description": "Log level",
|
||||
"name": "LOG_LEVEL",
|
||||
"settable": [
|
||||
"value"
|
||||
],
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"description": "Extra args to `weaver` and `plugin`",
|
||||
"name": "EXTRA_ARGS",
|
||||
|
||||
@@ -7,6 +7,7 @@ IPALLOC_RANGE=${IPALLOC_RANGE:-10.32.0.0/12}
|
||||
HTTP_ADDR=${WEAVE_HTTP_ADDR:-127.0.0.1:6784}
|
||||
STATUS_ADDR=${WEAVE_STATUS_ADDR:-0.0.0.0:6782}
|
||||
HOST_ROOT=${HOST_ROOT:-/host}
|
||||
LOG_LEVEL=${LOG_LEVEL:-info}
|
||||
WEAVE_DIR="/host/var/lib/weave"
|
||||
|
||||
mkdir $WEAVE_DIR || true
|
||||
@@ -44,7 +45,7 @@ exec /home/weave/weaver $EXTRA_ARGS --port=6783 $(router_bridge_opts) \
|
||||
--no-dns \
|
||||
--ipalloc-range=$IPALLOC_RANGE \
|
||||
--nickname "$(hostname)" \
|
||||
--log-level=debug \
|
||||
--log-level=$LOG_LEVEL \
|
||||
--db-prefix="$WEAVE_DIR/weave" \
|
||||
--plugin-v2 \
|
||||
$(multicast_opt) \
|
||||
|
||||
+19
-13
@@ -45,12 +45,20 @@ type ipamConfig struct {
|
||||
}
|
||||
|
||||
type dnsConfig struct {
|
||||
Domain string
|
||||
ListenAddress string
|
||||
TTL int
|
||||
ClientTimeout time.Duration
|
||||
EffectiveListenAddress string
|
||||
ResolvConf string
|
||||
Domain string
|
||||
ListenAddress string
|
||||
TTL int
|
||||
ClientTimeout time.Duration
|
||||
ResolvConf string
|
||||
}
|
||||
|
||||
// return the address part of the DNS listen address, without ":53" on the end
|
||||
func (c dnsConfig) addressOnly() string {
|
||||
addr, _, err := net.SplitHostPort(c.ListenAddress)
|
||||
if err != nil {
|
||||
Log.Fatalf("Error when parsing DNS listen address %q: %s", c.ListenAddress, err)
|
||||
}
|
||||
return addr
|
||||
}
|
||||
|
||||
func (c *ipamConfig) Enabled() bool {
|
||||
@@ -193,10 +201,10 @@ func main() {
|
||||
mflag.StringVar(&dnsConfig.ListenAddress, []string{"-dns-listen-address"}, nameserver.DefaultListenAddress, "address to listen on for DNS requests")
|
||||
mflag.IntVar(&dnsConfig.TTL, []string{"-dns-ttl"}, nameserver.DefaultTTL, "TTL for DNS request from our domain")
|
||||
mflag.DurationVar(&dnsConfig.ClientTimeout, []string{"-dns-fallback-timeout"}, nameserver.DefaultClientTimeout, "timeout for fallback DNS requests")
|
||||
mflag.StringVar(&dnsConfig.EffectiveListenAddress, []string{"-dns-effective-listen-address"}, "", "address DNS will actually be listening, after Docker port mapping")
|
||||
mflag.StringVar(&dnsConfig.ResolvConf, []string{"-resolv-conf"}, "", "path to resolver configuration for fallback DNS lookups")
|
||||
mflag.StringVar(&bridgeConfig.DatapathName, []string{"-datapath"}, "", "ODP datapath name")
|
||||
mflag.BoolVar(&bridgeConfig.NoFastdp, []string{"-no-fastdp"}, false, "Disable Fast Datapath")
|
||||
mflag.BoolVar(&bridgeConfig.NoBridgedFastdp, []string{"-no-bridged-fastdp"}, false, "Disable Bridged Fast Datapath")
|
||||
mflag.StringVar(&trustedSubnetStr, []string{"-trusted-subnets"}, "", "comma-separated list of trusted subnets in CIDR notation")
|
||||
mflag.StringVar(&dbPrefix, []string{"-db-prefix"}, "/weavedb/weave", "pathname/prefix of filename to store data")
|
||||
mflag.StringVar(&procPath, []string{"-proc-path"}, "/proc", "path to reach host /proc filesystem")
|
||||
@@ -263,6 +271,8 @@ func main() {
|
||||
var proxy *weaveproxy.Proxy
|
||||
var err error
|
||||
if proxyConfig.Enabled {
|
||||
proxyConfig.DNSListenAddress = dnsConfig.addressOnly()
|
||||
proxyConfig.DNSDomain = dnsConfig.Domain
|
||||
if noDNS {
|
||||
proxyConfig.WithoutDNS = true
|
||||
}
|
||||
@@ -635,17 +645,13 @@ func createDNSServer(config dnsConfig, router *mesh.Router, isKnownPeer func(mes
|
||||
gossip, err := router.NewGossip("nameserver", ns)
|
||||
checkFatal(err)
|
||||
ns.SetGossip(gossip)
|
||||
upstream := nameserver.NewUpstream(config.ResolvConf, config.EffectiveListenAddress)
|
||||
upstream := nameserver.NewUpstream(config.ResolvConf, config.addressOnly())
|
||||
dnsserver, err := nameserver.NewDNSServer(ns, config.Domain, config.ListenAddress,
|
||||
upstream, uint32(config.TTL), config.ClientTimeout)
|
||||
if err != nil {
|
||||
Log.Fatal("Unable to start dns server: ", err)
|
||||
}
|
||||
listenAddr := config.ListenAddress
|
||||
if config.EffectiveListenAddress != "" {
|
||||
listenAddr = config.EffectiveListenAddress
|
||||
}
|
||||
Log.Println("Listening for DNS queries on", listenAddr)
|
||||
Log.Println("Listening for DNS queries on", config.ListenAddress)
|
||||
return ns, dnsserver
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
@@ -15,8 +14,8 @@ import (
|
||||
)
|
||||
|
||||
func attach(args []string) error {
|
||||
if len(args) < 4 {
|
||||
cmdUsage("attach-container", "[--no-multicast-route] [--keep-tx-on] [--hairpin-mode=true|false] <container-id> <bridge-name> <mtu> <cidr>...")
|
||||
if len(args) < 3 {
|
||||
cmdUsage("attach-container", "[--no-multicast-route] [--keep-tx-on] [--hairpin-mode=true|false] <container-id> <bridge-name> <cidr>...")
|
||||
}
|
||||
|
||||
keepTXOn := false
|
||||
@@ -52,16 +51,12 @@ func attach(args []string) error {
|
||||
} else if nsHost.Equal(nsContainer) {
|
||||
return fmt.Errorf("Container is running in the host network namespace, and therefore cannot be\nconnected to weave - perhaps the container was started with --net=host")
|
||||
}
|
||||
mtu, err := strconv.Atoi(args[2])
|
||||
if err != nil && args[3] != "" {
|
||||
return fmt.Errorf("unable to parse mtu %q: %s", args[2], err)
|
||||
}
|
||||
cidrs, err := parseCIDRs(args[3:])
|
||||
cidrs, err := parseCIDRs(args[2:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = weavenet.AttachContainer(weavenet.NSPathByPid(pid), fmt.Sprint(pid), weavenet.VethName, args[1], mtu, withMulticastRoute, cidrs, keepTXOn, hairpinMode)
|
||||
err = weavenet.AttachContainer(weavenet.NSPathByPid(pid), fmt.Sprint(pid), weavenet.VethName, args[1], 0, withMulticastRoute, cidrs, keepTXOn, hairpinMode)
|
||||
// If we detected an error but the container has died, tell the user that instead.
|
||||
if err != nil && !processExists(pid) {
|
||||
err = fmt.Errorf("Container %s died", args[0])
|
||||
|
||||
@@ -2,9 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/weaveworks/weave/common"
|
||||
weavenet "github.com/weaveworks/weave/net"
|
||||
)
|
||||
|
||||
@@ -22,36 +20,3 @@ func detectBridgeType(args []string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func createBridge(args []string) error {
|
||||
if len(args) != 10 {
|
||||
cmdUsage("create-bridge", "<docker-bridge-name> <weave-bridge-name> <datapath-name> <mtu> <port> <mac> <no-fastdp> <no-bridged-fastdp> <proc-path> <expect-npc>")
|
||||
}
|
||||
|
||||
mtu, err := strconv.Atoi(args[3])
|
||||
if err != nil && args[3] != "" {
|
||||
return err
|
||||
}
|
||||
port, err := strconv.Atoi(args[4])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config := weavenet.BridgeConfig{
|
||||
DockerBridgeName: args[0],
|
||||
WeaveBridgeName: args[1],
|
||||
DatapathName: args[2],
|
||||
MTU: mtu,
|
||||
Port: port,
|
||||
Mac: args[5],
|
||||
NoFastdp: args[6] != "",
|
||||
NoBridgedFastdp: args[7] != "",
|
||||
NPC: args[9] == "--expect-npc",
|
||||
}
|
||||
procPath := args[8]
|
||||
bridgeType, err := weavenet.EnsureBridge(procPath, &config, common.Log)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(bridgeType.String())
|
||||
return nil
|
||||
}
|
||||
@@ -17,7 +17,6 @@ func init() {
|
||||
"help": help,
|
||||
"netcheck": netcheck,
|
||||
"docker-tls-args": dockerTLSArgs,
|
||||
"create-bridge": createBridge,
|
||||
"detect-bridge-type": detectBridgeType,
|
||||
"create-datapath": createDatapath,
|
||||
"delete-datapath": deleteDatapath,
|
||||
|
||||
@@ -68,11 +68,11 @@ func (i *createContainerInterceptor) InterceptRequest(r *http.Request) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if dnsDomain := i.proxy.getDNSDomain(); dnsDomain != "" {
|
||||
if err := i.setHostname(container, hostname, dnsDomain); err != nil {
|
||||
if !i.proxy.WithoutDNS {
|
||||
if err := i.setHostname(container, hostname, i.proxy.DNSDomain); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := i.proxy.setWeaveDNS(hostConfig, hostname, dnsDomain); err != nil {
|
||||
if err := i.proxy.setWeaveDNS(hostConfig, hostname, i.proxy.DNSDomain); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
+3
-19
@@ -61,6 +61,8 @@ type Config struct {
|
||||
NoRewriteHosts bool
|
||||
TLSConfig TLSConfig
|
||||
WithoutDNS bool
|
||||
DNSListenAddress string
|
||||
DNSDomain string
|
||||
NoMulticastRoute bool
|
||||
KeepTXOn bool
|
||||
DockerBridge string
|
||||
@@ -78,7 +80,6 @@ type Proxy struct {
|
||||
Config
|
||||
client *weavedocker.Client
|
||||
weave *weaveapi.Client
|
||||
dockerBridgeIP string
|
||||
hostnameMatchRegexp *regexp.Regexp
|
||||
weaveWaitVolume string
|
||||
weaveWaitNoopVolume string
|
||||
@@ -158,15 +159,6 @@ func NewProxy(c Config) (*Proxy, error) {
|
||||
|
||||
Log.Info(p.client.Info())
|
||||
|
||||
if !p.WithoutDNS {
|
||||
ip, err := weavenet.FindBridgeIP(c.DockerBridge, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.dockerBridgeIP = ip.String()
|
||||
Log.Infof("Using docker bridge IP for DNS: %v", p.dockerBridgeIP)
|
||||
}
|
||||
|
||||
p.hostnameMatchRegexp, err = regexp.Compile(c.HostnameMatch)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Incorrect hostname match '%s': %s", c.HostnameMatch, err.Error())
|
||||
@@ -595,7 +587,7 @@ func (proxy *Proxy) setWeaveDNS(hostConfig jsonObject, hostname, dnsDomain strin
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hostConfig["Dns"] = append(dns, proxy.dockerBridgeIP)
|
||||
hostConfig["Dns"] = append(dns, proxy.DNSListenAddress)
|
||||
|
||||
dnsSearch, err := hostConfig.StringArray("DnsSearch")
|
||||
if err != nil {
|
||||
@@ -612,14 +604,6 @@ func (proxy *Proxy) setWeaveDNS(hostConfig jsonObject, hostname, dnsDomain strin
|
||||
return nil
|
||||
}
|
||||
|
||||
func (proxy *Proxy) getDNSDomain() string {
|
||||
if proxy.WithoutDNS {
|
||||
return ""
|
||||
}
|
||||
domain, _ := proxy.weave.DNSDomain()
|
||||
return domain
|
||||
}
|
||||
|
||||
func (proxy *Proxy) updateContainerNetworkSettings(container jsonObject) error {
|
||||
containerID, err := container.String("Id")
|
||||
if err != nil {
|
||||
|
||||
@@ -50,8 +50,8 @@ func (i *startContainerInterceptor) InterceptRequest(r *http.Request) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if dnsDomain := i.proxy.getDNSDomain(); dnsDomain != "" {
|
||||
if err := i.proxy.setWeaveDNS(hostConfig, container.Config.Hostname, dnsDomain); err != nil {
|
||||
if !i.proxy.WithoutDNS {
|
||||
if err := i.proxy.setWeaveDNS(hostConfig, container.Config.Hostname, i.proxy.DNSDomain); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ func NewNetworkRouter(config mesh.Config, networkConfig NetworkConfig, bridgeCon
|
||||
router.Routes.OnChange(overlay.InvalidateRoutes)
|
||||
router.Macs = NewMacCache(macMaxAge,
|
||||
func(mac net.HardwareAddr, peer *mesh.Peer) {
|
||||
log.Println("Expired MAC", mac, "at", peer)
|
||||
log.Debugln("Expired MAC", mac, "at", peer)
|
||||
})
|
||||
router.Peers.OnGC(func(peer *mesh.Peer) { router.Macs.Delete(peer) })
|
||||
return router, nil
|
||||
@@ -92,7 +92,7 @@ func (router *NetworkRouter) handleCapturedPacket(key PacketKey) FlowOp {
|
||||
|
||||
switch newSrcMac, conflictPeer := router.Macs.Add(srcMac, router.Ourself.Peer); {
|
||||
case newSrcMac:
|
||||
log.Println("Discovered local MAC", srcMac)
|
||||
log.Debugln("Discovered local MAC", srcMac)
|
||||
case conflictPeer != nil:
|
||||
// The MAC cache has an entry for the source MAC
|
||||
// associated with another peer. This probably means
|
||||
|
||||
@@ -11,7 +11,9 @@ The following topics are discussed:
|
||||
* [Upgrading the Daemon Sets](#daemon-sets)
|
||||
* [CPU and Memory Requirements](#resources)
|
||||
* [Pod Eviction](#eviction)
|
||||
* [Network Policy Controller](#npc)
|
||||
* [Features](#features)
|
||||
* [Pod Network](#pod-network)
|
||||
* [Network Policy](#npc)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
* [Troubleshooting Blocked Connections](#blocked-connections)
|
||||
* [Things to watch out for](#key-points)
|
||||
@@ -147,16 +149,33 @@ mypod-09vkd 0/1 Evicted 0 1h <none> node-1
|
||||
If you see this in your cluster, consider some of the above steps to
|
||||
reduce disruption.
|
||||
|
||||
## <a name="npc"></a>Network Policy Controller
|
||||
## <a name="features"></a>Features
|
||||
|
||||
The addon also supports the [Kubernetes policy
|
||||
API](http://kubernetes.io/docs/user-guide/networkpolicies/) so that
|
||||
you can securely isolate pods from each other based on namespaces and
|
||||
### <a name="pod-network"></a>Pod Network
|
||||
|
||||
Weave Net provides a network to connect all pods together,
|
||||
implementing the [Kubernetes
|
||||
model](https://kubernetes.io/docs/concepts/cluster-administration/networking/#kubernetes-model).
|
||||
|
||||
Kubernetes uses the _Container Network Interface_
|
||||
([CNI](https://github.com/containernetworking/cni)) to join pods onto Weave Net.
|
||||
|
||||
Kubernetes implements many network features itself on top of the pod
|
||||
network. This includes
|
||||
[Services](https://kubernetes.io/docs/concepts/services-networking/service/),
|
||||
[Service Discovery via DNS](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/)
|
||||
and [Ingress into the cluster](https://kubernetes.io/docs/concepts/services-networking/ingress/).
|
||||
WeaveDNS is disabled when using the Kubernetes addon.
|
||||
|
||||
### <a name="npc"></a>Network Policy
|
||||
|
||||
[Kubernetes Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/) let
|
||||
you securely isolate pods from each other based on namespaces and
|
||||
labels. For more information on configuring network policies in
|
||||
Kubernetes see the
|
||||
[walkthrough](http://kubernetes.io/docs/getting-started-guides/network-policy/walkthrough/)
|
||||
[walkthrough](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy/)
|
||||
and the [NetworkPolicy API object
|
||||
definition](http://kubernetes.io/docs/api-reference/extensions/v1beta1/definitions/#_v1beta1_networkpolicy).
|
||||
definition](https://v1-7.docs.kubernetes.io/docs/api-reference/v1.7/#networkpolicy-v1-networking)
|
||||
|
||||
**Note:** as of version 1.9 of Weave Net, the Network Policy
|
||||
Controller allows all multicast traffic. Since a single multicast
|
||||
@@ -167,6 +186,11 @@ definition](http://kubernetes.io/docs/api-reference/extensions/v1beta1/definitio
|
||||
|
||||
## <a name="troubleshooting"></a> Troubleshooting
|
||||
|
||||
Many Kubernetes network issues occur at a higher level than Weave Net.
|
||||
The [Kubernetes Service Debugging Guide]
|
||||
(https://kubernetes.io/docs/tasks/debug-application-cluster/debug-service/)
|
||||
has a detailed step-by-step guide.
|
||||
|
||||
The status of Weave Net can be checked by running its CLI commands. This can be done in various ways:
|
||||
|
||||
1\. [Install the `weave` script](/site/installing-weave.md) and run:
|
||||
@@ -299,11 +323,14 @@ You can customise the YAML you get from `cloud.weave.works` by passing some of W
|
||||
- `disable-npc`: boolean (`true|false`). Default: `false`.
|
||||
- `env.NAME=VALUE`: add environment variable `NAME` and set it to `VALUE`.
|
||||
- `seLinuxOptions.NAME=VALUE`: add SELinux option `NAME` and set it to `VALUE`, e.g. `seLinuxOptions.type=spc_t`
|
||||
- `use-legacy-netpol`: use [legacy NetworkPolicy semantics](https://v1-6.docs.kubernetes.io/docs/api-reference/v1.6/#networkpolicy-v1beta1-extensions), boolean (`true|false`). Default: `true` for Kubernetes version <= 1.6, `false` for > 1.6.
|
||||
|
||||
The list of variables you can set is:
|
||||
|
||||
* `CHECKPOINT_DISABLE` - if set to 1, disable checking for new Weave Net
|
||||
versions (default is blank, i.e. check is enabled)
|
||||
* `CONN_LIMIT` - soft limit on the number of connections between
|
||||
peers. Defaults to 30.
|
||||
* `HAIRPIN_MODE` - Weave Net defaults to enabling hairpin on the bridge side of
|
||||
the `veth` pair for containers attached. If you need to disable hairpin, e.g. your
|
||||
kernel is one of those that can panic if hairpin is enabled, then you can disable it
|
||||
|
||||
@@ -50,7 +50,7 @@ peers and their reachability can be obtained with
|
||||
|
||||
```
|
||||
$ weave status ipam
|
||||
00:00:00:00:00:01(one) 349526 IPs (33.3% of total)
|
||||
00:00:00:00:00:01(one) 349526 IPs (33.3% of total) (2 active)
|
||||
00:00:00:00:00:02(two) 349525 IPs (33.3% of total)
|
||||
00:00:00:00:00:03(three) 349525 IPs (33.3% of total) - unreachable!
|
||||
```
|
||||
@@ -59,6 +59,8 @@ Columns are as follows:
|
||||
|
||||
* Peer Name and Nickname
|
||||
* Absolute quantity/percentage of allocation range managed by peer
|
||||
* Active - number of IP addresses in use on that peer - this is only
|
||||
available for the peer where you run the status command.
|
||||
* Indication of unreachability. This means that the peer is not
|
||||
visible (directly or indirectly) to the peer on which `weave status
|
||||
ipam` was run; whilst this could be a transient condition due to a
|
||||
|
||||
@@ -43,6 +43,10 @@ To disable an application container's use of weaveDNS, add the
|
||||
`--without-dns` option to `weave launch`. To
|
||||
disable weaveDNS itself, launch weave with the `--no-dns` option.
|
||||
|
||||
> **Note** WeaveDNS is not part of the Weave Net Kubernetes add-on.
|
||||
Kubernetes has its own DNS service, integrated with Kubernetes
|
||||
Services, and WeaveDNS does not duplicate that functionality.
|
||||
|
||||
**See Also**
|
||||
|
||||
* [Integrating Docker via the API Proxy](/site/tasks/weave-docker-api/weave-docker-api.md)
|
||||
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
#! /bin/bash
|
||||
|
||||
. "$(dirname "$0")/config.sh"
|
||||
|
||||
C1=10.32.0.2
|
||||
C2=10.32.0.3
|
||||
|
||||
kill_weaver() {
|
||||
run_on $HOST1 sudo ip link set weave down
|
||||
WEAVER_PID=$(container_pid $HOST1 weave)
|
||||
run_on $HOST1 sudo kill -9 $WEAVER_PID
|
||||
sleep 3
|
||||
}
|
||||
|
||||
start_suite "Re-create bridge after restart"
|
||||
|
||||
# Should create a bridge of the "bridge" type.
|
||||
WEAVE_NO_FASTDP=1 weave_on $HOST1 launch
|
||||
WEAVE_NO_FASTDP=1 weave_on $HOST2 launch $HOST1
|
||||
|
||||
start_container $HOST1 $C1/24 --name=c1
|
||||
start_container $HOST2 $C2/24 --name=c2
|
||||
assert_raises "exec_on $HOST1 c1 $PING $C2"
|
||||
|
||||
kill_weaver # should re-create the bridge
|
||||
|
||||
assert_raises "exec_on $HOST1 c1 $PING $C2"
|
||||
|
||||
# Should create a bridge of the "bridged_fastdp" type
|
||||
weave_on $HOST1 reset
|
||||
weave_on $HOST1 launch $HOST2
|
||||
weave_on $HOST1 attach $C1/24 c1
|
||||
assert_raises "exec_on $HOST1 c1 $PING $C2"
|
||||
|
||||
kill_weaver # should re-create the bridge
|
||||
|
||||
assert_raises "exec_on $HOST1 c1 $PING $C2"
|
||||
|
||||
# test restore of iptables
|
||||
|
||||
weave_on $HOST1 reset
|
||||
# `--expect-npc` to trigger creation of WEAVE-NPC iptables chain.
|
||||
weave_on $HOST1 launch --expect-npc
|
||||
# To create POSTROUTING rules.
|
||||
weave_on $HOST1 expose
|
||||
|
||||
IPT_BEFORE=$(mktemp)
|
||||
IPT_AFTER=$(mktemp)
|
||||
run_on $HOST1 "sudo iptables-save | grep -i weave | grep -v '\[.*:.*\]' > $IPT_BEFORE"
|
||||
|
||||
run_on $HOST1 "sudo iptables -t filter -D FORWARD -o weave -m comment --comment \"NOTE: this must go before '-j KUBE-FORWARD'\" -j WEAVE-NPC"
|
||||
run_on $HOST1 sudo iptables -t nat -D POSTROUTING -j WEAVE
|
||||
kill_weaver # should re-create the bridge and iptables friends
|
||||
|
||||
# Rudimentary check that weave related iptables rules has been restored
|
||||
run_on $HOST1 "sudo iptables-save | grep -i weave | grep -v '\[.*:.*\]' > $IPT_AFTER"
|
||||
assert_raises "run_on $HOST1 diff $IPT_BEFORE $IPT_AFTER"
|
||||
|
||||
end_suite
|
||||
@@ -21,7 +21,7 @@ start_container_local_plugin $HOST1 --name=c3
|
||||
|
||||
assert "show_multicast_route_on $HOST1 c1"
|
||||
assert "show_multicast_route_on $HOST1 c2"
|
||||
assert "show_multicast_route_on $HOST1 c3" "224.0.0.0/4 dev ethwe0 "
|
||||
assert "show_multicast_route_on $HOST1 c3" "224.0.0.0/4 dev ethwe0 scope link "
|
||||
|
||||
# Now try via docker network options
|
||||
# using ssh rather than docker -H because CircleCI docker client is older
|
||||
@@ -30,7 +30,7 @@ $SSH $HOST1 docker run --net=testmcastfalse --name c4 -di $SMALL_IMAGE /bin/sh
|
||||
assert "show_multicast_route_on $HOST1 c4"
|
||||
$SSH $HOST1 docker network create --driver weavemesh --ipam-driver weavemesh --opt works.weave.multicast testmcasttrue
|
||||
$SSH $HOST1 docker run --net=testmcasttrue --name c5 -di $SMALL_IMAGE /bin/sh
|
||||
assert "show_multicast_route_on $HOST1 c5" "224.0.0.0/4 dev ethwe0 "
|
||||
assert "show_multicast_route_on $HOST1 c5" "224.0.0.0/4 dev ethwe0 scope link "
|
||||
|
||||
# Ensure current proxy options are obeyed on container start
|
||||
docker_on $HOST1 stop -t 1 c2
|
||||
@@ -39,7 +39,7 @@ weave_on $HOST1 launch
|
||||
|
||||
proxy docker_on $HOST1 start c2
|
||||
|
||||
assert "show_multicast_route_on $HOST1 c2" "224.0.0.0/4 dev ethwe "
|
||||
assert "show_multicast_route_on $HOST1 c2" "224.0.0.0/4 dev ethwe scope link "
|
||||
|
||||
docker_on $HOST1 rm -f c3 c4 c5
|
||||
$SSH $HOST1 docker network rm testmcasttrue testmcastfalse
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
tear_down_kubeadm() {
|
||||
for host in $HOSTS; do
|
||||
run_on $host "sudo kubeadm reset && sudo rm -r -f /opt/cni/bin/*weave*"
|
||||
# Remove the rule to ensure that api-server is not accessible while kube-proxy
|
||||
# is not ready. Otherwise, we have a race between "-j KUBE-FORWARD" and "-j WEAVE-NPC"
|
||||
# which makes the NodePort isolation test case to fail.
|
||||
run_on $host "sudo iptables -t nat -D PREROUTING -m comment --comment \"kubernetes service portals\" -j KUBE-SERVICES" || true
|
||||
done
|
||||
}
|
||||
|
||||
@@ -18,6 +22,7 @@ NUM_HOSTS=$(howmany $HOSTS)
|
||||
SUCCESS="$(( $NUM_HOSTS * ($NUM_HOSTS-1) )) established"
|
||||
KUBECTL="sudo kubectl --kubeconfig /etc/kubernetes/admin.conf"
|
||||
KUBE_PORT=6443
|
||||
WEAVE_NETWORK=10.32.0.0/12
|
||||
IMAGE=weaveworks/network-tester:latest
|
||||
DOMAIN=nettest.default.svc.cluster.local.
|
||||
|
||||
@@ -33,9 +38,9 @@ k8s_version_option="$([[ "$k8s_version" > "v1.6" ]] && echo "kubernetes-version"
|
||||
|
||||
for host in $HOSTS; do
|
||||
if [ $host = $HOST1 ] ; then
|
||||
run_on $host "sudo systemctl start kubelet && sudo kubeadm init --$k8s_version_option=$k8s_version --token=$TOKEN"
|
||||
run_on $host "sudo systemctl start kubelet && sudo kubeadm init --$k8s_version_option=$k8s_version --token=$TOKEN --pod-network-cidr=$WEAVE_NETWORK"
|
||||
else
|
||||
run_on $host "sudo systemctl start kubelet && sudo kubeadm join --token=$TOKEN $HOST1IP:$KUBE_PORT"
|
||||
run_on $host "sudo systemctl start kubelet && sudo kubeadm join --token=$TOKEN --discovery-token-unsafe-skip-ca-verification $HOST1IP:$KUBE_PORT"
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -134,6 +139,22 @@ spec:
|
||||
run: nettest
|
||||
EOF
|
||||
|
||||
# And a NodePort service so we can test virtual IP access
|
||||
run_on $HOST1 "$KUBECTL create -f -" <<EOF
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: netvirt
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 8080
|
||||
nodePort: 31138
|
||||
selector:
|
||||
run: nettest
|
||||
EOF
|
||||
|
||||
podName=$($SSH $HOST1 "$KUBECTL get pods -l run=nettest -o go-template='{{(index .items 0).metadata.name}}'")
|
||||
|
||||
check_all_pods_communicate() {
|
||||
@@ -170,6 +191,15 @@ assert_raises 'wait_for_x check_all_pods_communicate pods'
|
||||
# nettest-deny should still not be able to reach nettest pods
|
||||
assert_raises "! $SSH $HOST1 $KUBECTL exec $denyPodName -- curl -s -S -f -m 2 http://$DOMAIN:8080/status >/dev/null"
|
||||
|
||||
# check access via virtual IP
|
||||
VIRTUAL_IP=$($SSH $HOST1 $KUBECTL get service netvirt -o template --template={{.spec.clusterIP}})
|
||||
assert_raises "$SSH $HOST1 $KUBECTL exec $podName -- curl -s -S -f -m 2 http://$VIRTUAL_IP/status >/dev/null"
|
||||
assert_raises "! $SSH $HOST1 $KUBECTL exec $denyPodName -- curl -s -S -f -m 2 http://$VIRTUAL_IP/status >/dev/null"
|
||||
|
||||
# host should not be able to reach pods via service virtual IP or NodePort
|
||||
assert_raises "! $SSH $HOST1 curl -s -S -f -m 2 http://$VIRTUAL_IP/status >/dev/null"
|
||||
assert_raises "! $SSH $HOST1 curl -s -S -f -m 2 http://$HOST2:31138/status >/dev/null"
|
||||
|
||||
# allow access for nettest-deny
|
||||
run_on $HOST1 "$KUBECTL apply -f -" <<EOF
|
||||
apiVersion: networking.k8s.io/v1
|
||||
@@ -211,6 +241,10 @@ EOF
|
||||
|
||||
assert_raises "$SSH $HOST1 $KUBECTL exec $denyPodName -- curl -s -S -f -m 2 http://$DOMAIN:8080/status >/dev/null"
|
||||
|
||||
# Virtual IP and NodePort should now work
|
||||
assert_raises "$SSH $HOST1 curl -s -S -f -m 2 http://$VIRTUAL_IP/status >/dev/null"
|
||||
assert_raises "$SSH $HOST1 curl -s -S -f -m 2 http://$HOST2:31138/status >/dev/null"
|
||||
|
||||
tear_down_kubeadm
|
||||
|
||||
# Destroy our test ipset, and implicitly check it is still there
|
||||
|
||||
@@ -44,7 +44,7 @@ function setup_kubernetes_cluster {
|
||||
if [ $host = $HOST1 ] ; then
|
||||
run_on $host "sudo systemctl start kubelet && sudo kubeadm init --$k8s_version_option=$k8s_version --token=$TOKEN"
|
||||
else
|
||||
run_on $host "sudo systemctl start kubelet && sudo kubeadm join --token=$TOKEN $HOST1IP:$KUBE_PORT"
|
||||
run_on $host "sudo systemctl start kubelet && sudo kubeadm join --token=$TOKEN --discovery-token-unsafe-skip-ca-verification $HOST1IP:$KUBE_PORT"
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
+79
-1
@@ -13,7 +13,7 @@ it is recommended to run the tests from the build VM and not the host.
|
||||
|
||||
> **NOTE WELL** The number of hosts required by a test must be specified in the test name. For example, `000_some_test.sh` will use one host, while `001_some_other_3_test.sh` will use three hosts. The number of hosts must be the last part of the test name before the `_test.sh` prefix. See `/tools/runner/runner.go` for details
|
||||
|
||||
## Running tests
|
||||
## Running tests locally using VMs
|
||||
|
||||
**TL;DR**: You can run the steps 2. to 7. below with one command:
|
||||
|
||||
@@ -23,46 +23,62 @@ it is recommended to run the tests from the build VM and not the host.
|
||||
|
||||
1. Start the build virtual machine (see above article for more details):
|
||||
|
||||
```
|
||||
vagrant up
|
||||
```
|
||||
|
||||
2. Start the three testing VMs:
|
||||
|
||||
```
|
||||
cd test
|
||||
vagrant up
|
||||
```
|
||||
|
||||
3. SSH into the build VM and go to Weave Net's sources:
|
||||
|
||||
```
|
||||
cd ..
|
||||
vagrant ssh
|
||||
# you are now on the build VM:
|
||||
cd ~/weave
|
||||
```
|
||||
|
||||
4. Compile all code and dependencies:
|
||||
|
||||
```
|
||||
make
|
||||
make testrunner
|
||||
cd test
|
||||
```
|
||||
|
||||
5. Upload the weave images from where the `Makefile` puts them (`weave.tar.gz`) to
|
||||
the three docker hosts, `docker load` these, and copies the `weave` script over:
|
||||
|
||||
```
|
||||
./setup.sh
|
||||
```
|
||||
|
||||
6. Run individual tests, e.g.:
|
||||
|
||||
```
|
||||
./200_dns_test.sh
|
||||
```
|
||||
|
||||
or run all tests (everything named `*_test.sh`):
|
||||
|
||||
```
|
||||
./run_all.sh
|
||||
```
|
||||
|
||||
7. Stop all VMs:
|
||||
|
||||
```
|
||||
exit
|
||||
# you are now on your host machine
|
||||
vagrant destroy -f
|
||||
cd test
|
||||
vagrant destroy -f
|
||||
```
|
||||
|
||||
|
||||
## Using other VMs
|
||||
@@ -92,3 +108,65 @@ When a new version of Docker is released, you willneed to update the GCE test im
|
||||
To do this, change the Docker version in `run-integration-tests.sh` and push the change.
|
||||
Next build in CircleCI will detect that there is no template for this version of Docker and will first create the template before running tests.
|
||||
Subsequent builds will then simply re-use the template.
|
||||
|
||||
## Running the tests on a cloud provider
|
||||
|
||||
Running the tests against a remote provider instead of local vagrant VMs is a little more involved, and reproduces the environment used for CI. It is recommended that you use the build VM to coordinate the build phase. Make sure you have a recent version of [ansible](https://github.com/ansible/ansible) installed, terraform will fail to provision the VMs.
|
||||
|
||||
1. Create the build VM in the repository root and log in
|
||||
|
||||
```
|
||||
# On your development machine
|
||||
$ vagrant up
|
||||
$ vagrant ssh
|
||||
```
|
||||
|
||||
2. Once in the build vm, install the `gcloud` tools as [per the documentation](https://cloud.google.com/sdk/downloads). You need to do this manually as the circleCI VMs are already provisioned with `gcloud`.
|
||||
|
||||
```
|
||||
# On the build VM
|
||||
$ curl https://sdk.cloud.google.com | bash
|
||||
$ exec -l $SHELL
|
||||
```
|
||||
|
||||
You don't need to initialise the `gcloud` tools by running `gcloud init`.
|
||||
|
||||
3. Export the secret key needed to decrypt the cloud credentials - This assumes you're using the build tools
|
||||
|
||||
```
|
||||
# On the build VM
|
||||
$ export SECRET_KEY="XXXXXXXXXX"
|
||||
```
|
||||
|
||||
4. Navigate to the test directory and provision the VMs
|
||||
|
||||
```
|
||||
# On the build VM
|
||||
$ cd weave/test
|
||||
/weave/test$ ./run-integration-tests.sh up
|
||||
```
|
||||
5. Run the tests you need
|
||||
|
||||
```
|
||||
# On the build VM
|
||||
/weave/test$ export TESTS="./090_docker_restart_policy_2_test.sh"
|
||||
/weave/test$ ./run-integration-tests.sh test
|
||||
```
|
||||
|
||||
6. Don't forget to close down your remote VMs when you're done
|
||||
|
||||
```
|
||||
# On the build VM
|
||||
/weave/test$ ./run-integration-tests.sh destroy
|
||||
```
|
||||
|
||||
7. And switch off your build VM
|
||||
|
||||
```
|
||||
# On the build VM
|
||||
/weave/test$ exit
|
||||
|
||||
# On your development machine
|
||||
$ vagrant destroy -f
|
||||
# or "vagrant suspend" if you want to preserve the machine state
|
||||
```
|
||||
Vendored
+1
-1
@@ -25,7 +25,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
config.vm.define hostname do |host|
|
||||
host.vm.provider :virtualbox do |vb|
|
||||
vb.name = hostname
|
||||
vb.memory = 384
|
||||
vb.memory = 2048
|
||||
configure_nat_dns(vb)
|
||||
end
|
||||
|
||||
|
||||
+1
-1
Submodule tools updated: 74dc626b6d...ca69607f79.
+1
-1
Submodule vendor/github.com/miekg/dns updated: c9d1302d54...5364553f1e.
+1
-1
Submodule vendor/github.com/vishvananda/netlink updated: c19091b1c6...f67b75edbf.
@@ -405,27 +405,6 @@ detect_bridge_type() {
|
||||
MTU=${WEAVE_MTU:-$(cat /sys/class/net/$BRIDGE/mtu)}
|
||||
}
|
||||
|
||||
try_create_bridge() {
|
||||
# Pass /dev/null because we do not have access to the weavedb files when this runs; BoltDB
|
||||
# cannot open the file anyway if weaver is running, which is likely for attach|expose|hide.
|
||||
MAC=$(util_op unique-id "/dev/null" "$HOST_ROOT")
|
||||
BRIDGE_TYPE=$(util_op create-bridge "$DOCKER_BRIDGE" "$BRIDGE" "$DATAPATH" "$WEAVE_MTU" "$PORT" "$MAC" "$WEAVE_NO_FASTDP" "$WEAVE_NO_BRIDGED_FASTDP" "$PROC_PATH" "$1")
|
||||
# Set some variables that are expected by code that comes later
|
||||
[ "$BRIDGE_TYPE" != "fastdp" ] || DATAPATH="$BRIDGE"
|
||||
MTU=${WEAVE_MTU:-$(cat /sys/class/net/$BRIDGE/mtu)}
|
||||
}
|
||||
|
||||
create_bridge() {
|
||||
validate_bridge_type
|
||||
if ! try_create_bridge "$@" ; then
|
||||
echo "Creating bridge '$BRIDGE' failed" >&2
|
||||
# reset to original value so we destroy both kinds
|
||||
DATAPATH=datapath
|
||||
destroy_bridge
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
validate_bridge_type() {
|
||||
detect_bridge_type || return 0
|
||||
|
||||
@@ -557,6 +536,7 @@ router_bridge_opts() {
|
||||
echo --docker-bridge "$DOCKER_BRIDGE" --weave-bridge "$BRIDGE" --datapath "$DATAPATH"
|
||||
[ -z "$WEAVE_MTU" ] || echo --mtu "$WEAVE_MTU"
|
||||
[ -z $WEAVE_NO_FASTDP ] || echo --no-fastdp
|
||||
[ -z $WEAVE_NO_BRIDGED_FASTDP ] || echo --no-bridged-fastdp
|
||||
}
|
||||
|
||||
######################################################################
|
||||
@@ -918,9 +898,7 @@ check_overlap() {
|
||||
}
|
||||
|
||||
detect_awsvpc() {
|
||||
# Ignoring errors here: if we cannot detect AWSVPC we will skip the relevant
|
||||
# steps, because "attach" should work without the weave router running.
|
||||
[ "$(call_weave GET /ipinfo/tracker)" != "awsvpc" ] || AWSVPC=1
|
||||
[ "$(call_weave GET /ipinfo/tracker 2>/dev/null)" != "awsvpc" ] || AWSVPC=1
|
||||
}
|
||||
|
||||
# Call IPAM as necessary to lookup or allocate addresses
|
||||
@@ -1256,7 +1234,6 @@ launch() {
|
||||
--host-root=/host \
|
||||
$(router_bridge_opts) \
|
||||
--ipalloc-range "$IPRANGE" \
|
||||
--dns-effective-listen-address $DOCKER_BRIDGE_IP \
|
||||
--dns-listen-address $DOCKER_BRIDGE_IP:53 \
|
||||
--http-addr $HTTP_ADDR \
|
||||
--status-addr $STATUS_ADDR \
|
||||
@@ -1436,7 +1413,6 @@ case "$COMMAND" in
|
||||
done
|
||||
[ $# -eq 1 ] || usage
|
||||
CONTAINER=$(util_op container-id $1)
|
||||
create_bridge
|
||||
ipam_cidrs allocate $CONTAINER $CIDR_ARGS
|
||||
if [ -n "$REWRITE_HOSTS" ] ; then
|
||||
# rewrite /etc/hosts, unlinking the file (so Docker does
|
||||
@@ -1444,7 +1420,7 @@ case "$COMMAND" in
|
||||
util_op rewrite-etc-hosts "$CONTAINER" "$EXEC_IMAGE" "$ALL_CIDRS" $DNS_EXTRA_HOSTS
|
||||
fi
|
||||
[ -n "$AWSVPC" ] && ATTACH_ARGS="--no-multicast-route --keep-tx-on"
|
||||
util_op attach-container $ATTACH_ARGS $CONTAINER $BRIDGE $MTU $ALL_CIDRS >/dev/null
|
||||
util_op attach-container $ATTACH_ARGS $CONTAINER $BRIDGE $ALL_CIDRS >/dev/null
|
||||
[ -n "$WITHOUT_DNS" ] || when_weave_running with_container_fqdn $CONTAINER put_dns_fqdn $ALL_CIDRS
|
||||
show_addrs $ALL_CIDRS
|
||||
;;
|
||||
@@ -1494,7 +1470,6 @@ case "$COMMAND" in
|
||||
[ $# -eq 2 -a "$1" = "-h" ] || usage
|
||||
FQDN="$2"
|
||||
fi
|
||||
create_bridge
|
||||
expose_ip
|
||||
show_addrs $ALL_CIDRS
|
||||
;;
|
||||
@@ -1502,7 +1477,6 @@ case "$COMMAND" in
|
||||
collect_cidr_args "$@"
|
||||
shift $CIDR_ARG_COUNT
|
||||
ipam_cidrs lookup weave:expose $CIDR_ARGS
|
||||
create_bridge
|
||||
for CIDR in $ALL_CIDRS ; do
|
||||
if ip addr show dev $BRIDGE | grep -qF $CIDR ; then
|
||||
ip addr del dev $BRIDGE $CIDR
|
||||
|
||||
Reference in new issue
Block a user