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
|
## Release 2.1.2
|
||||||
|
|
||||||
This release fixes a couple of bugs discovered since the release of Weave Net 2.1.0
|
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
|
DOCKER_VERSION=17.06
|
||||||
KUBERNETES_VERSION=1.7.8
|
KUBERNETES_VERSION=1.9.2
|
||||||
KUBERNETES_CNI_VERSION=0.5.1
|
KUBERNETES_CNI_VERSION=0.6.0
|
||||||
+2
-2
@@ -196,7 +196,7 @@ publish() {
|
|||||||
|
|
||||||
if [ "$RELEASE_TYPE" = 'PRERELEASE' ] ; then
|
if [ "$RELEASE_TYPE" = 'PRERELEASE' ] ; then
|
||||||
echo "== Building and pushing plugin"
|
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 "** Plugin built and pushed"
|
||||||
|
|
||||||
echo "== Tagging and pushing images on docker hub as user $DOCKERHUB_USER"
|
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 '** Sanity checks OK for publishing tag' $LATEST_TAG as $DOCKERHUB_USER/weave:$VERSION
|
||||||
|
|
||||||
echo "== Building and pushing plugin"
|
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 "** Plugin built and pushed"
|
||||||
|
|
||||||
echo "== Tagging and pushing images on docker hub as user $DOCKERHUB_USER"
|
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 {
|
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()
|
dpif, err := odp.NewDpif()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -87,5 +95,9 @@ func AddDatapathInterface(dpname string, ifname string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, err = dp.CreateVport(odp.NewNetdevVportSpec(ifname))
|
_, err = dp.CreateVport(odp.NewNetdevVportSpec(ifname))
|
||||||
|
if ignoreIfExist && err == odp.NetlinkError(syscall.EEXIST) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return err
|
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
|
* 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)
|
* 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
|
* 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
|
tag, push to GitHub and set [WEAVE_NET_REV](https://github.com/weaveworks/website-next/blob/master/Makefile)
|
||||||
published to https://www.weave.works
|
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
|
* Add the new version of `weave-net` to the checkpoint system at
|
||||||
https://checkpoint-api.weave.works/admin
|
https://checkpoint-api.weave.works/admin
|
||||||
* File a PR to update the version of the daemonset at
|
* 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) {
|
func EnsureBridge(procPath string, config *BridgeConfig, log *logrus.Logger) (Bridge, error) {
|
||||||
bridgeType, err := ExistingBridgeType(config.WeaveBridgeName, config.DatapathName)
|
existingBridgeType, err := ExistingBridgeType(config.WeaveBridgeName, config.DatapathName)
|
||||||
if bridgeType != nil || err != nil {
|
if err != nil {
|
||||||
return bridgeType, err
|
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 {
|
for {
|
||||||
if err := bridgeType.init(config); err != nil {
|
if err := bridgeType.init(config); err != nil {
|
||||||
if errors.Cause(err) == errBridgeNotSupported {
|
if errors.Cause(err) == errBridgeNotSupported {
|
||||||
@@ -288,7 +295,7 @@ func (b bridgeImpl) initPrep(config *BridgeConfig) error {
|
|||||||
config.MTU = 65535
|
config.MTU = 65535
|
||||||
}
|
}
|
||||||
b.bridge = &netlink.Bridge{LinkAttrs: linkAttrs}
|
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)
|
return errors.Wrapf(err, "creating bridge %q", config.WeaveBridgeName)
|
||||||
}
|
}
|
||||||
if err := netlink.LinkSetHardwareAddr(b.bridge, mac); err != nil {
|
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 {
|
if err := b.initPrep(config); err != nil {
|
||||||
return err
|
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)
|
return netlink.LinkSetUp(veth)
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return errors.Wrap(err, "creating pcap veth pair")
|
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 {
|
if err := bf.bridgeImpl.initPrep(config); err != nil {
|
||||||
return err
|
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 {
|
if err := netlink.LinkSetUp(veth); err != nil {
|
||||||
return errors.Wrapf(err, "setting link up on %q", veth.Attrs().Name)
|
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 errors.Wrapf(err, "adding interface %q to datapath %q", veth.Attrs().Name, bf.datapathName)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -394,7 +401,7 @@ func (bf bridgedFastdpImpl) attach(veth *netlink.Veth) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f fastdpImpl) 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 {
|
func configureIPTables(config *BridgeConfig) error {
|
||||||
@@ -402,12 +409,13 @@ func configureIPTables(config *BridgeConfig) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "creating iptables object")
|
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.DockerBridgeName != "" {
|
||||||
if config.WeaveBridgeName != config.DockerBridgeName {
|
if config.WeaveBridgeName != config.DockerBridgeName {
|
||||||
err := ipt.Insert("filter", "FORWARD", 1, "-i", config.DockerBridgeName, "-o", config.WeaveBridgeName, "-j", "DROP")
|
fwdRules = append(fwdRules, []string{"-i", config.DockerBridgeName, "-o", config.WeaveBridgeName, "-j", "DROP"})
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dockerBridgeIP, err := FindBridgeIP(config.DockerBridgeName, nil)
|
dockerBridgeIP, err := FindBridgeIP(config.DockerBridgeName, nil)
|
||||||
@@ -438,45 +446,42 @@ func configureIPTables(config *BridgeConfig) error {
|
|||||||
if config.NPC {
|
if config.NPC {
|
||||||
// Steer traffic via the NPC
|
// Steer traffic via the NPC
|
||||||
_ = ipt.NewChain("filter", "WEAVE-NPC") // ignore error because it might already exist
|
_ = 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 WEAVE-NPC chain doesn't exist then creating a rule in the chain will fail
|
||||||
if err = ipt.AppendUnique("filter", "FORWARD", "-o", config.WeaveBridgeName, "-j", "WEAVE-NPC"); err != nil {
|
fwdRules = append(fwdRules,
|
||||||
return err
|
[][]string{
|
||||||
}
|
{"-o", config.WeaveBridgeName,
|
||||||
if err = ipt.AppendUnique("filter", "FORWARD", "-o", config.WeaveBridgeName, "-m", "state", "--state", "NEW", "-j", "NFLOG", "--nflog-group", "86"); err != nil {
|
"-m", "comment", "--comment", "NOTE: this must go before '-j KUBE-FORWARD'",
|
||||||
return err
|
"-j", "WEAVE-NPC"},
|
||||||
}
|
{"-o", config.WeaveBridgeName, "-m", "state", "--state", "NEW", "-j", "NFLOG", "--nflog-group", "86"},
|
||||||
if err = ipt.AppendUnique("filter", "FORWARD", "-o", config.WeaveBridgeName, "-j", "DROP"); err != nil {
|
{"-o", config.WeaveBridgeName, "-j", "DROP"},
|
||||||
return err
|
}...)
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Work around the situation where there are no rules allowing traffic
|
// Work around the situation where there are no rules allowing traffic
|
||||||
// across our bridge. E.g. ufw
|
// across our bridge. E.g. ufw
|
||||||
if err = ipt.AppendUnique("filter", "FORWARD", "-i", config.WeaveBridgeName, "-o", config.WeaveBridgeName, "-j", "ACCEPT"); err != nil {
|
fwdRules = append(fwdRules, []string{"-i", config.WeaveBridgeName, "-o", config.WeaveBridgeName, "-j", "ACCEPT"})
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !config.NPC {
|
if !config.NPC {
|
||||||
// Create a chain for allowing ingress traffic when the bridge is exposed
|
// Create a chain for allowing ingress traffic when the bridge is exposed
|
||||||
_ = ipt.NewChain("filter", "WEAVE-EXPOSE")
|
_ = ipt.NewChain("filter", "WEAVE-EXPOSE")
|
||||||
if err = ipt.AppendUnique("filter", "FORWARD", "-o", config.WeaveBridgeName, "-j", "WEAVE-EXPOSE"); err != nil {
|
fwdRules = append(fwdRules, []string{"-o", config.WeaveBridgeName, "-j", "WEAVE-EXPOSE"})
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward from weave to the rest of the world
|
// 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 {
|
fwdRules = append(fwdRules, []string{"-i", config.WeaveBridgeName, "!", "-o", config.WeaveBridgeName, "-j", "ACCEPT"})
|
||||||
return err
|
|
||||||
}
|
|
||||||
// and allow replies back
|
// 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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a chain for masquerading
|
// 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")
|
return ipt.AppendUnique("nat", "POSTROUTING", "-j", "WEAVE")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,3 +492,40 @@ func linkSetUpByName(linkName string) error {
|
|||||||
}
|
}
|
||||||
return netlink.LinkSetUp(link)
|
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
|
// 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)
|
bridge, err := netlink.LinkByName(bridgeName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf(`bridge "%s" not present; did you launch weave?`, bridgeName)
|
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},
|
MTU: mtu},
|
||||||
PeerName: peerName,
|
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)
|
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
|
id = id[:maxIDLen] // trim passed ID if too long
|
||||||
}
|
}
|
||||||
name, peerName := vethPrefix+"pl"+id, vethPrefix+"pg"+id
|
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 {
|
if err := netlink.LinkSetNsFd(veth, int(ns)); err != nil {
|
||||||
return fmt.Errorf("failed to move veth to container netns: %s", err)
|
return fmt.Errorf("failed to move veth to container netns: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
+49
@@ -4,7 +4,56 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Return JSON suitable for logging an API object.
|
||||||
func js(v interface{}) string {
|
func js(v interface{}) string {
|
||||||
|
// Get the raw JSON
|
||||||
a, _ := json.Marshal(v)
|
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)
|
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
|
// create veths. note we assume endpoint IDs are unique in the first 9 chars
|
||||||
name, peerName := vethPair(create.EndpointID)
|
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)
|
return nil, driver.error("JoinEndpoint", "%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,8 +73,10 @@ const (
|
|||||||
retryPeriod = time.Second * 2
|
retryPeriod = time.Second * 2
|
||||||
jitterFactor = 1.0
|
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 is the default annotation key
|
||||||
KubePeersAnnotationKey = "kube-peers.weave.works/peers"
|
KubePeersAnnotationKey = KubePeersPrefix + "peers"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (cml *configMapAnnotations) Init() error {
|
func (cml *configMapAnnotations) Init() error {
|
||||||
@@ -130,46 +132,59 @@ func (cml *configMapAnnotations) UpdatePeerList(list peerList) error {
|
|||||||
return cml.UpdateAnnotation(KubePeersAnnotationKey, string(recordBytes))
|
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 {
|
if cml.cm == nil {
|
||||||
return errors.New("endpoint not initialized, call Init first")
|
return errors.New("endpoint not initialized, call Init first")
|
||||||
}
|
}
|
||||||
cm := cml.cm
|
// speculatively change the state, then replace with whatever comes back
|
||||||
cm.Annotations[key] = value
|
// from Update(), which will be the latest on the server whatever happened
|
||||||
cm, err := cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm)
|
cml.cm.Annotations[cleanKey(key)] = value
|
||||||
if err == nil {
|
cml.cm, err = cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm)
|
||||||
cml.cm = cm
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cml *configMapAnnotations) RemoveAnnotation(key string) error {
|
func (cml *configMapAnnotations) RemoveAnnotation(key string) (err error) {
|
||||||
if cml.cm == nil {
|
if cml.cm == nil {
|
||||||
return errors.New("endpoint not initialized, call Init first")
|
return errors.New("endpoint not initialized, call Init first")
|
||||||
}
|
}
|
||||||
cm := cml.cm
|
// speculatively change the state, then replace with whatever comes back
|
||||||
delete(cm.Annotations, key)
|
// from Update(), which will be the latest on the server whatever happened
|
||||||
cm, err := cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm)
|
delete(cml.cm.Annotations, cleanKey(key))
|
||||||
if err == nil {
|
cml.cm, err = cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm)
|
||||||
cml.cm = cm
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cml *configMapAnnotations) RemoveAnnotationsWithValue(valueToRemove string) error {
|
func (cml *configMapAnnotations) RemoveAnnotationsWithValue(valueToRemove string) (err error) {
|
||||||
if cml.cm == nil {
|
if cml.cm == nil {
|
||||||
return errors.New("endpoint not initialized, call Init first")
|
return errors.New("endpoint not initialized, call Init first")
|
||||||
}
|
}
|
||||||
cm := cml.cm
|
// speculatively change the state, then replace with whatever comes back
|
||||||
for key, value := range cm.Annotations {
|
// from Update(), which will be the latest on the server whatever happened
|
||||||
|
for key, value := range cml.cm.Annotations {
|
||||||
if value == valueToRemove {
|
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)
|
cml.cm, err = cml.Client.ConfigMaps(cml.Namespace).Update(cml.cm)
|
||||||
if err == nil {
|
|
||||||
cml.cm = cm
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,6 +98,9 @@ func checkIamInPeerList(cml *configMapAnnotations, c *kubernetes.Clientset, peer
|
|||||||
// Kubernetes, remove it from Weave IPAM
|
// Kubernetes, remove it from Weave IPAM
|
||||||
func reclaimRemovedPeers(weave *weaveapi.Client, cml *configMapAnnotations, nodes []nodeInfo, myPeerName string) error {
|
func reclaimRemovedPeers(weave *weaveapi.Client, cml *configMapAnnotations, nodes []nodeInfo, myPeerName string) error {
|
||||||
for {
|
for {
|
||||||
|
if err := cml.Init(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
// 1. Compare peers stored in the peerList against all peers reported by k8s now.
|
// 1. Compare peers stored in the peerList against all peers reported by k8s now.
|
||||||
storedPeerList, err := cml.GetPeerList()
|
storedPeerList, err := cml.GetPeerList()
|
||||||
if err != nil {
|
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)
|
common.Log.Debugln("[kube-peers] Preparing to remove disappeared peer", peer)
|
||||||
okToRemove := false
|
okToRemove := false
|
||||||
// 3. Check if there is an existing annotation with key X
|
// 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)
|
common.Log.Debugln("[kube-peers] Existing annotation", existingAnnotation)
|
||||||
// 4. If annotation already contains my identity, ok;
|
// 4. If annotation already contains my identity, ok;
|
||||||
if existingAnnotation == myPeerName {
|
if existingAnnotation == myPeerName {
|
||||||
@@ -128,14 +131,16 @@ func reclaimRemovedPeers(weave *weaveapi.Client, cml *configMapAnnotations, node
|
|||||||
} else {
|
} else {
|
||||||
// 5. If non-existent, write an annotation with key X and contents "my identity"
|
// 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)
|
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
|
okToRemove = true
|
||||||
|
} else {
|
||||||
|
common.Log.Debugln("[kube-peers] error from UpdateAnnotation: ", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if okToRemove {
|
if okToRemove {
|
||||||
// 6. If step 4 or 5 succeeded, rmpeer X
|
// 6. If step 4 or 5 succeeded, rmpeer X
|
||||||
result, err := weave.RmPeer(peer.PeerName)
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -146,15 +151,12 @@ func reclaimRemovedPeers(weave *weaveapi.Client, cml *configMapAnnotations, node
|
|||||||
}
|
}
|
||||||
// 7a. Remove X from peerList
|
// 7a. Remove X from peerList
|
||||||
storedPeerList.remove(peer.PeerName)
|
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 {
|
if err := cml.UpdatePeerList(*storedPeerList); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
common.Log.Infoln("[kube-peers] Removing annotation ", peer.PeerName)
|
|
||||||
// 7b. Remove annotation with key X
|
// 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
|
// 8. If step 5 failed due to optimistic lock conflict, stop: someone else is handling X
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,14 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"env": [
|
"env": [
|
||||||
|
{
|
||||||
|
"description": "Log level",
|
||||||
|
"name": "LOG_LEVEL",
|
||||||
|
"settable": [
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "Extra args to `weaver` and `plugin`",
|
"description": "Extra args to `weaver` and `plugin`",
|
||||||
"name": "EXTRA_ARGS",
|
"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}
|
HTTP_ADDR=${WEAVE_HTTP_ADDR:-127.0.0.1:6784}
|
||||||
STATUS_ADDR=${WEAVE_STATUS_ADDR:-0.0.0.0:6782}
|
STATUS_ADDR=${WEAVE_STATUS_ADDR:-0.0.0.0:6782}
|
||||||
HOST_ROOT=${HOST_ROOT:-/host}
|
HOST_ROOT=${HOST_ROOT:-/host}
|
||||||
|
LOG_LEVEL=${LOG_LEVEL:-info}
|
||||||
WEAVE_DIR="/host/var/lib/weave"
|
WEAVE_DIR="/host/var/lib/weave"
|
||||||
|
|
||||||
mkdir $WEAVE_DIR || true
|
mkdir $WEAVE_DIR || true
|
||||||
@@ -44,7 +45,7 @@ exec /home/weave/weaver $EXTRA_ARGS --port=6783 $(router_bridge_opts) \
|
|||||||
--no-dns \
|
--no-dns \
|
||||||
--ipalloc-range=$IPALLOC_RANGE \
|
--ipalloc-range=$IPALLOC_RANGE \
|
||||||
--nickname "$(hostname)" \
|
--nickname "$(hostname)" \
|
||||||
--log-level=debug \
|
--log-level=$LOG_LEVEL \
|
||||||
--db-prefix="$WEAVE_DIR/weave" \
|
--db-prefix="$WEAVE_DIR/weave" \
|
||||||
--plugin-v2 \
|
--plugin-v2 \
|
||||||
$(multicast_opt) \
|
$(multicast_opt) \
|
||||||
|
|||||||
+19
-13
@@ -45,12 +45,20 @@ type ipamConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type dnsConfig struct {
|
type dnsConfig struct {
|
||||||
Domain string
|
Domain string
|
||||||
ListenAddress string
|
ListenAddress string
|
||||||
TTL int
|
TTL int
|
||||||
ClientTimeout time.Duration
|
ClientTimeout time.Duration
|
||||||
EffectiveListenAddress string
|
ResolvConf string
|
||||||
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 {
|
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.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.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.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(&dnsConfig.ResolvConf, []string{"-resolv-conf"}, "", "path to resolver configuration for fallback DNS lookups")
|
||||||
mflag.StringVar(&bridgeConfig.DatapathName, []string{"-datapath"}, "", "ODP datapath name")
|
mflag.StringVar(&bridgeConfig.DatapathName, []string{"-datapath"}, "", "ODP datapath name")
|
||||||
mflag.BoolVar(&bridgeConfig.NoFastdp, []string{"-no-fastdp"}, false, "Disable Fast Datapath")
|
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(&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(&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")
|
mflag.StringVar(&procPath, []string{"-proc-path"}, "/proc", "path to reach host /proc filesystem")
|
||||||
@@ -263,6 +271,8 @@ func main() {
|
|||||||
var proxy *weaveproxy.Proxy
|
var proxy *weaveproxy.Proxy
|
||||||
var err error
|
var err error
|
||||||
if proxyConfig.Enabled {
|
if proxyConfig.Enabled {
|
||||||
|
proxyConfig.DNSListenAddress = dnsConfig.addressOnly()
|
||||||
|
proxyConfig.DNSDomain = dnsConfig.Domain
|
||||||
if noDNS {
|
if noDNS {
|
||||||
proxyConfig.WithoutDNS = true
|
proxyConfig.WithoutDNS = true
|
||||||
}
|
}
|
||||||
@@ -635,17 +645,13 @@ func createDNSServer(config dnsConfig, router *mesh.Router, isKnownPeer func(mes
|
|||||||
gossip, err := router.NewGossip("nameserver", ns)
|
gossip, err := router.NewGossip("nameserver", ns)
|
||||||
checkFatal(err)
|
checkFatal(err)
|
||||||
ns.SetGossip(gossip)
|
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,
|
dnsserver, err := nameserver.NewDNSServer(ns, config.Domain, config.ListenAddress,
|
||||||
upstream, uint32(config.TTL), config.ClientTimeout)
|
upstream, uint32(config.TTL), config.ClientTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Log.Fatal("Unable to start dns server: ", err)
|
Log.Fatal("Unable to start dns server: ", err)
|
||||||
}
|
}
|
||||||
listenAddr := config.ListenAddress
|
Log.Println("Listening for DNS queries on", config.ListenAddress)
|
||||||
if config.EffectiveListenAddress != "" {
|
|
||||||
listenAddr = config.EffectiveListenAddress
|
|
||||||
}
|
|
||||||
Log.Println("Listening for DNS queries on", listenAddr)
|
|
||||||
return ns, dnsserver
|
return ns, dnsserver
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
@@ -15,8 +14,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func attach(args []string) error {
|
func attach(args []string) error {
|
||||||
if len(args) < 4 {
|
if len(args) < 3 {
|
||||||
cmdUsage("attach-container", "[--no-multicast-route] [--keep-tx-on] [--hairpin-mode=true|false] <container-id> <bridge-name> <mtu> <cidr>...")
|
cmdUsage("attach-container", "[--no-multicast-route] [--keep-tx-on] [--hairpin-mode=true|false] <container-id> <bridge-name> <cidr>...")
|
||||||
}
|
}
|
||||||
|
|
||||||
keepTXOn := false
|
keepTXOn := false
|
||||||
@@ -52,16 +51,12 @@ func attach(args []string) error {
|
|||||||
} else if nsHost.Equal(nsContainer) {
|
} 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")
|
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])
|
cidrs, err := parseCIDRs(args[2:])
|
||||||
if err != nil && args[3] != "" {
|
|
||||||
return fmt.Errorf("unable to parse mtu %q: %s", args[2], err)
|
|
||||||
}
|
|
||||||
cidrs, err := parseCIDRs(args[3:])
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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 we detected an error but the container has died, tell the user that instead.
|
||||||
if err != nil && !processExists(pid) {
|
if err != nil && !processExists(pid) {
|
||||||
err = fmt.Errorf("Container %s died", args[0])
|
err = fmt.Errorf("Container %s died", args[0])
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/weaveworks/weave/common"
|
|
||||||
weavenet "github.com/weaveworks/weave/net"
|
weavenet "github.com/weaveworks/weave/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -22,36 +20,3 @@ func detectBridgeType(args []string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
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,
|
"help": help,
|
||||||
"netcheck": netcheck,
|
"netcheck": netcheck,
|
||||||
"docker-tls-args": dockerTLSArgs,
|
"docker-tls-args": dockerTLSArgs,
|
||||||
"create-bridge": createBridge,
|
|
||||||
"detect-bridge-type": detectBridgeType,
|
"detect-bridge-type": detectBridgeType,
|
||||||
"create-datapath": createDatapath,
|
"create-datapath": createDatapath,
|
||||||
"delete-datapath": deleteDatapath,
|
"delete-datapath": deleteDatapath,
|
||||||
|
|||||||
@@ -68,11 +68,11 @@ func (i *createContainerInterceptor) InterceptRequest(r *http.Request) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if dnsDomain := i.proxy.getDNSDomain(); dnsDomain != "" {
|
if !i.proxy.WithoutDNS {
|
||||||
if err := i.setHostname(container, hostname, dnsDomain); err != nil {
|
if err := i.setHostname(container, hostname, i.proxy.DNSDomain); err != nil {
|
||||||
return err
|
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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-19
@@ -61,6 +61,8 @@ type Config struct {
|
|||||||
NoRewriteHosts bool
|
NoRewriteHosts bool
|
||||||
TLSConfig TLSConfig
|
TLSConfig TLSConfig
|
||||||
WithoutDNS bool
|
WithoutDNS bool
|
||||||
|
DNSListenAddress string
|
||||||
|
DNSDomain string
|
||||||
NoMulticastRoute bool
|
NoMulticastRoute bool
|
||||||
KeepTXOn bool
|
KeepTXOn bool
|
||||||
DockerBridge string
|
DockerBridge string
|
||||||
@@ -78,7 +80,6 @@ type Proxy struct {
|
|||||||
Config
|
Config
|
||||||
client *weavedocker.Client
|
client *weavedocker.Client
|
||||||
weave *weaveapi.Client
|
weave *weaveapi.Client
|
||||||
dockerBridgeIP string
|
|
||||||
hostnameMatchRegexp *regexp.Regexp
|
hostnameMatchRegexp *regexp.Regexp
|
||||||
weaveWaitVolume string
|
weaveWaitVolume string
|
||||||
weaveWaitNoopVolume string
|
weaveWaitNoopVolume string
|
||||||
@@ -158,15 +159,6 @@ func NewProxy(c Config) (*Proxy, error) {
|
|||||||
|
|
||||||
Log.Info(p.client.Info())
|
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)
|
p.hostnameMatchRegexp, err = regexp.Compile(c.HostnameMatch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := fmt.Errorf("Incorrect hostname match '%s': %s", c.HostnameMatch, err.Error())
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
hostConfig["Dns"] = append(dns, proxy.dockerBridgeIP)
|
hostConfig["Dns"] = append(dns, proxy.DNSListenAddress)
|
||||||
|
|
||||||
dnsSearch, err := hostConfig.StringArray("DnsSearch")
|
dnsSearch, err := hostConfig.StringArray("DnsSearch")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -612,14 +604,6 @@ func (proxy *Proxy) setWeaveDNS(hostConfig jsonObject, hostname, dnsDomain strin
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (proxy *Proxy) getDNSDomain() string {
|
|
||||||
if proxy.WithoutDNS {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
domain, _ := proxy.weave.DNSDomain()
|
|
||||||
return domain
|
|
||||||
}
|
|
||||||
|
|
||||||
func (proxy *Proxy) updateContainerNetworkSettings(container jsonObject) error {
|
func (proxy *Proxy) updateContainerNetworkSettings(container jsonObject) error {
|
||||||
containerID, err := container.String("Id")
|
containerID, err := container.String("Id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ func (i *startContainerInterceptor) InterceptRequest(r *http.Request) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if dnsDomain := i.proxy.getDNSDomain(); dnsDomain != "" {
|
if !i.proxy.WithoutDNS {
|
||||||
if err := i.proxy.setWeaveDNS(hostConfig, container.Config.Hostname, dnsDomain); err != nil {
|
if err := i.proxy.setWeaveDNS(hostConfig, container.Config.Hostname, i.proxy.DNSDomain); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ func NewNetworkRouter(config mesh.Config, networkConfig NetworkConfig, bridgeCon
|
|||||||
router.Routes.OnChange(overlay.InvalidateRoutes)
|
router.Routes.OnChange(overlay.InvalidateRoutes)
|
||||||
router.Macs = NewMacCache(macMaxAge,
|
router.Macs = NewMacCache(macMaxAge,
|
||||||
func(mac net.HardwareAddr, peer *mesh.Peer) {
|
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) })
|
router.Peers.OnGC(func(peer *mesh.Peer) { router.Macs.Delete(peer) })
|
||||||
return router, nil
|
return router, nil
|
||||||
@@ -92,7 +92,7 @@ func (router *NetworkRouter) handleCapturedPacket(key PacketKey) FlowOp {
|
|||||||
|
|
||||||
switch newSrcMac, conflictPeer := router.Macs.Add(srcMac, router.Ourself.Peer); {
|
switch newSrcMac, conflictPeer := router.Macs.Add(srcMac, router.Ourself.Peer); {
|
||||||
case newSrcMac:
|
case newSrcMac:
|
||||||
log.Println("Discovered local MAC", srcMac)
|
log.Debugln("Discovered local MAC", srcMac)
|
||||||
case conflictPeer != nil:
|
case conflictPeer != nil:
|
||||||
// The MAC cache has an entry for the source MAC
|
// The MAC cache has an entry for the source MAC
|
||||||
// associated with another peer. This probably means
|
// associated with another peer. This probably means
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ The following topics are discussed:
|
|||||||
* [Upgrading the Daemon Sets](#daemon-sets)
|
* [Upgrading the Daemon Sets](#daemon-sets)
|
||||||
* [CPU and Memory Requirements](#resources)
|
* [CPU and Memory Requirements](#resources)
|
||||||
* [Pod Eviction](#eviction)
|
* [Pod Eviction](#eviction)
|
||||||
* [Network Policy Controller](#npc)
|
* [Features](#features)
|
||||||
|
* [Pod Network](#pod-network)
|
||||||
|
* [Network Policy](#npc)
|
||||||
* [Troubleshooting](#troubleshooting)
|
* [Troubleshooting](#troubleshooting)
|
||||||
* [Troubleshooting Blocked Connections](#blocked-connections)
|
* [Troubleshooting Blocked Connections](#blocked-connections)
|
||||||
* [Things to watch out for](#key-points)
|
* [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
|
If you see this in your cluster, consider some of the above steps to
|
||||||
reduce disruption.
|
reduce disruption.
|
||||||
|
|
||||||
## <a name="npc"></a>Network Policy Controller
|
## <a name="features"></a>Features
|
||||||
|
|
||||||
The addon also supports the [Kubernetes policy
|
### <a name="pod-network"></a>Pod Network
|
||||||
API](http://kubernetes.io/docs/user-guide/networkpolicies/) so that
|
|
||||||
you can securely isolate pods from each other based on namespaces and
|
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
|
labels. For more information on configuring network policies in
|
||||||
Kubernetes see the
|
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
|
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
|
**Note:** as of version 1.9 of Weave Net, the Network Policy
|
||||||
Controller allows all multicast traffic. Since a single multicast
|
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
|
## <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:
|
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:
|
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`.
|
- `disable-npc`: boolean (`true|false`). Default: `false`.
|
||||||
- `env.NAME=VALUE`: add environment variable `NAME` and set it to `VALUE`.
|
- `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`
|
- `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:
|
The list of variables you can set is:
|
||||||
|
|
||||||
* `CHECKPOINT_DISABLE` - if set to 1, disable checking for new Weave Net
|
* `CHECKPOINT_DISABLE` - if set to 1, disable checking for new Weave Net
|
||||||
versions (default is blank, i.e. check is enabled)
|
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
|
* `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
|
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
|
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
|
$ 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:02(two) 349525 IPs (33.3% of total)
|
||||||
00:00:00:00:00:03(three) 349525 IPs (33.3% of total) - unreachable!
|
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
|
* Peer Name and Nickname
|
||||||
* Absolute quantity/percentage of allocation range managed by peer
|
* 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
|
* Indication of unreachability. This means that the peer is not
|
||||||
visible (directly or indirectly) to the peer on which `weave status
|
visible (directly or indirectly) to the peer on which `weave status
|
||||||
ipam` was run; whilst this could be a transient condition due to a
|
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
|
`--without-dns` option to `weave launch`. To
|
||||||
disable weaveDNS itself, launch weave with the `--no-dns` option.
|
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**
|
**See Also**
|
||||||
|
|
||||||
* [Integrating Docker via the API Proxy](/site/tasks/weave-docker-api/weave-docker-api.md)
|
* [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 c1"
|
||||||
assert "show_multicast_route_on $HOST1 c2"
|
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
|
# Now try via docker network options
|
||||||
# using ssh rather than docker -H because CircleCI docker client is older
|
# 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"
|
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 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
|
$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
|
# Ensure current proxy options are obeyed on container start
|
||||||
docker_on $HOST1 stop -t 1 c2
|
docker_on $HOST1 stop -t 1 c2
|
||||||
@@ -39,7 +39,7 @@ weave_on $HOST1 launch
|
|||||||
|
|
||||||
proxy docker_on $HOST1 start c2
|
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
|
docker_on $HOST1 rm -f c3 c4 c5
|
||||||
$SSH $HOST1 docker network rm testmcasttrue testmcastfalse
|
$SSH $HOST1 docker network rm testmcasttrue testmcastfalse
|
||||||
|
|||||||
@@ -5,6 +5,10 @@
|
|||||||
tear_down_kubeadm() {
|
tear_down_kubeadm() {
|
||||||
for host in $HOSTS; do
|
for host in $HOSTS; do
|
||||||
run_on $host "sudo kubeadm reset && sudo rm -r -f /opt/cni/bin/*weave*"
|
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
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,6 +22,7 @@ NUM_HOSTS=$(howmany $HOSTS)
|
|||||||
SUCCESS="$(( $NUM_HOSTS * ($NUM_HOSTS-1) )) established"
|
SUCCESS="$(( $NUM_HOSTS * ($NUM_HOSTS-1) )) established"
|
||||||
KUBECTL="sudo kubectl --kubeconfig /etc/kubernetes/admin.conf"
|
KUBECTL="sudo kubectl --kubeconfig /etc/kubernetes/admin.conf"
|
||||||
KUBE_PORT=6443
|
KUBE_PORT=6443
|
||||||
|
WEAVE_NETWORK=10.32.0.0/12
|
||||||
IMAGE=weaveworks/network-tester:latest
|
IMAGE=weaveworks/network-tester:latest
|
||||||
DOMAIN=nettest.default.svc.cluster.local.
|
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
|
for host in $HOSTS; do
|
||||||
if [ $host = $HOST1 ] ; then
|
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
|
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
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -134,6 +139,22 @@ spec:
|
|||||||
run: nettest
|
run: nettest
|
||||||
EOF
|
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}}'")
|
podName=$($SSH $HOST1 "$KUBECTL get pods -l run=nettest -o go-template='{{(index .items 0).metadata.name}}'")
|
||||||
|
|
||||||
check_all_pods_communicate() {
|
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
|
# 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"
|
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
|
# allow access for nettest-deny
|
||||||
run_on $HOST1 "$KUBECTL apply -f -" <<EOF
|
run_on $HOST1 "$KUBECTL apply -f -" <<EOF
|
||||||
apiVersion: networking.k8s.io/v1
|
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"
|
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
|
tear_down_kubeadm
|
||||||
|
|
||||||
# Destroy our test ipset, and implicitly check it is still there
|
# Destroy our test ipset, and implicitly check it is still there
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ function setup_kubernetes_cluster {
|
|||||||
if [ $host = $HOST1 ] ; then
|
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"
|
||||||
else
|
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
|
fi
|
||||||
done
|
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
|
> **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:
|
**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):
|
1. Start the build virtual machine (see above article for more details):
|
||||||
|
|
||||||
|
```
|
||||||
vagrant up
|
vagrant up
|
||||||
|
```
|
||||||
|
|
||||||
2. Start the three testing VMs:
|
2. Start the three testing VMs:
|
||||||
|
|
||||||
|
```
|
||||||
cd test
|
cd test
|
||||||
vagrant up
|
vagrant up
|
||||||
|
```
|
||||||
|
|
||||||
3. SSH into the build VM and go to Weave Net's sources:
|
3. SSH into the build VM and go to Weave Net's sources:
|
||||||
|
|
||||||
|
```
|
||||||
cd ..
|
cd ..
|
||||||
vagrant ssh
|
vagrant ssh
|
||||||
# you are now on the build VM:
|
# you are now on the build VM:
|
||||||
cd ~/weave
|
cd ~/weave
|
||||||
|
```
|
||||||
|
|
||||||
4. Compile all code and dependencies:
|
4. Compile all code and dependencies:
|
||||||
|
|
||||||
|
```
|
||||||
make
|
make
|
||||||
make testrunner
|
make testrunner
|
||||||
cd test
|
cd test
|
||||||
|
```
|
||||||
|
|
||||||
5. Upload the weave images from where the `Makefile` puts them (`weave.tar.gz`) to
|
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:
|
the three docker hosts, `docker load` these, and copies the `weave` script over:
|
||||||
|
|
||||||
|
```
|
||||||
./setup.sh
|
./setup.sh
|
||||||
|
```
|
||||||
|
|
||||||
6. Run individual tests, e.g.:
|
6. Run individual tests, e.g.:
|
||||||
|
|
||||||
|
```
|
||||||
./200_dns_test.sh
|
./200_dns_test.sh
|
||||||
|
```
|
||||||
|
|
||||||
or run all tests (everything named `*_test.sh`):
|
or run all tests (everything named `*_test.sh`):
|
||||||
|
|
||||||
|
```
|
||||||
./run_all.sh
|
./run_all.sh
|
||||||
|
```
|
||||||
|
|
||||||
7. Stop all VMs:
|
7. Stop all VMs:
|
||||||
|
|
||||||
|
```
|
||||||
exit
|
exit
|
||||||
# you are now on your host machine
|
# you are now on your host machine
|
||||||
vagrant destroy -f
|
vagrant destroy -f
|
||||||
cd test
|
cd test
|
||||||
vagrant destroy -f
|
vagrant destroy -f
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Using other VMs
|
## 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.
|
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.
|
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.
|
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|
|
config.vm.define hostname do |host|
|
||||||
host.vm.provider :virtualbox do |vb|
|
host.vm.provider :virtualbox do |vb|
|
||||||
vb.name = hostname
|
vb.name = hostname
|
||||||
vb.memory = 384
|
vb.memory = 2048
|
||||||
configure_nat_dns(vb)
|
configure_nat_dns(vb)
|
||||||
end
|
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)}
|
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() {
|
validate_bridge_type() {
|
||||||
detect_bridge_type || return 0
|
detect_bridge_type || return 0
|
||||||
|
|
||||||
@@ -557,6 +536,7 @@ router_bridge_opts() {
|
|||||||
echo --docker-bridge "$DOCKER_BRIDGE" --weave-bridge "$BRIDGE" --datapath "$DATAPATH"
|
echo --docker-bridge "$DOCKER_BRIDGE" --weave-bridge "$BRIDGE" --datapath "$DATAPATH"
|
||||||
[ -z "$WEAVE_MTU" ] || echo --mtu "$WEAVE_MTU"
|
[ -z "$WEAVE_MTU" ] || echo --mtu "$WEAVE_MTU"
|
||||||
[ -z $WEAVE_NO_FASTDP ] || echo --no-fastdp
|
[ -z $WEAVE_NO_FASTDP ] || echo --no-fastdp
|
||||||
|
[ -z $WEAVE_NO_BRIDGED_FASTDP ] || echo --no-bridged-fastdp
|
||||||
}
|
}
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
@@ -918,9 +898,7 @@ check_overlap() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
detect_awsvpc() {
|
detect_awsvpc() {
|
||||||
# Ignoring errors here: if we cannot detect AWSVPC we will skip the relevant
|
[ "$(call_weave GET /ipinfo/tracker 2>/dev/null)" != "awsvpc" ] || AWSVPC=1
|
||||||
# steps, because "attach" should work without the weave router running.
|
|
||||||
[ "$(call_weave GET /ipinfo/tracker)" != "awsvpc" ] || AWSVPC=1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Call IPAM as necessary to lookup or allocate addresses
|
# Call IPAM as necessary to lookup or allocate addresses
|
||||||
@@ -1256,7 +1234,6 @@ launch() {
|
|||||||
--host-root=/host \
|
--host-root=/host \
|
||||||
$(router_bridge_opts) \
|
$(router_bridge_opts) \
|
||||||
--ipalloc-range "$IPRANGE" \
|
--ipalloc-range "$IPRANGE" \
|
||||||
--dns-effective-listen-address $DOCKER_BRIDGE_IP \
|
|
||||||
--dns-listen-address $DOCKER_BRIDGE_IP:53 \
|
--dns-listen-address $DOCKER_BRIDGE_IP:53 \
|
||||||
--http-addr $HTTP_ADDR \
|
--http-addr $HTTP_ADDR \
|
||||||
--status-addr $STATUS_ADDR \
|
--status-addr $STATUS_ADDR \
|
||||||
@@ -1436,7 +1413,6 @@ case "$COMMAND" in
|
|||||||
done
|
done
|
||||||
[ $# -eq 1 ] || usage
|
[ $# -eq 1 ] || usage
|
||||||
CONTAINER=$(util_op container-id $1)
|
CONTAINER=$(util_op container-id $1)
|
||||||
create_bridge
|
|
||||||
ipam_cidrs allocate $CONTAINER $CIDR_ARGS
|
ipam_cidrs allocate $CONTAINER $CIDR_ARGS
|
||||||
if [ -n "$REWRITE_HOSTS" ] ; then
|
if [ -n "$REWRITE_HOSTS" ] ; then
|
||||||
# rewrite /etc/hosts, unlinking the file (so Docker does
|
# 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
|
util_op rewrite-etc-hosts "$CONTAINER" "$EXEC_IMAGE" "$ALL_CIDRS" $DNS_EXTRA_HOSTS
|
||||||
fi
|
fi
|
||||||
[ -n "$AWSVPC" ] && ATTACH_ARGS="--no-multicast-route --keep-tx-on"
|
[ -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
|
[ -n "$WITHOUT_DNS" ] || when_weave_running with_container_fqdn $CONTAINER put_dns_fqdn $ALL_CIDRS
|
||||||
show_addrs $ALL_CIDRS
|
show_addrs $ALL_CIDRS
|
||||||
;;
|
;;
|
||||||
@@ -1494,7 +1470,6 @@ case "$COMMAND" in
|
|||||||
[ $# -eq 2 -a "$1" = "-h" ] || usage
|
[ $# -eq 2 -a "$1" = "-h" ] || usage
|
||||||
FQDN="$2"
|
FQDN="$2"
|
||||||
fi
|
fi
|
||||||
create_bridge
|
|
||||||
expose_ip
|
expose_ip
|
||||||
show_addrs $ALL_CIDRS
|
show_addrs $ALL_CIDRS
|
||||||
;;
|
;;
|
||||||
@@ -1502,7 +1477,6 @@ case "$COMMAND" in
|
|||||||
collect_cidr_args "$@"
|
collect_cidr_args "$@"
|
||||||
shift $CIDR_ARG_COUNT
|
shift $CIDR_ARG_COUNT
|
||||||
ipam_cidrs lookup weave:expose $CIDR_ARGS
|
ipam_cidrs lookup weave:expose $CIDR_ARGS
|
||||||
create_bridge
|
|
||||||
for CIDR in $ALL_CIDRS ; do
|
for CIDR in $ALL_CIDRS ; do
|
||||||
if ip addr show dev $BRIDGE | grep -qF $CIDR ; then
|
if ip addr show dev $BRIDGE | grep -qF $CIDR ; then
|
||||||
ip addr del dev $BRIDGE $CIDR
|
ip addr del dev $BRIDGE $CIDR
|
||||||
|
|||||||
Reference in new issue
Block a user