Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18b5cb10dc | ||
|
|
fff656f7e4 | ||
|
|
b42895b5c0 | ||
|
|
91ab0e4a76 | ||
|
|
20eee3818e | ||
|
|
5534ecf1b1 | ||
|
|
75bf62ca80 | ||
|
|
ce9c5162bd | ||
|
|
5c0da56ad5 | ||
|
|
08858c2a10 | ||
|
|
0268aeb25f | ||
|
|
ea3aba8971 | ||
|
|
265bfcf9d7 | ||
|
|
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 | ||
|
|
192e5a1f79 | ||
|
|
692bccc4fc | ||
|
|
51c2a0d732 | ||
|
|
0205adcedb | ||
|
|
a3fd36e2bb |
No files matched your search
@@ -1,3 +1,68 @@
|
|||||||
|
## Release 2.2.1
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
* Fix a bug in weave-npc which would allow ingress traffic to Kubernetes Pods selected
|
||||||
|
by a NetworkPolicy in which source and destination selectors were the same #3222,#3237
|
||||||
|
* Fix a bug in weave-npc which would crash if a previously deleted Kubernetes Namespace
|
||||||
|
has been created again #3247,#3250
|
||||||
|
|
||||||
|
### Other improvements
|
||||||
|
|
||||||
|
* Increase the default connection limit for Weave peers (from 30 to 100), so that
|
||||||
|
more peers could directly connect #3234
|
||||||
|
* When doing a rolling update of Weave Net on Kubernetes, allow each node five seconds
|
||||||
|
to initialize before rolling next Weave Net Pod, so that issues at startup will halt
|
||||||
|
the rollout and not spread across the whole cluster #3235
|
||||||
|
* Install common CA certificates from Alpine Linux package instead of copying
|
||||||
|
them manually #3236
|
||||||
|
|
||||||
|
### External contributors
|
||||||
|
|
||||||
|
Thanks to the following contributors:
|
||||||
|
|
||||||
|
* @alok87
|
||||||
|
|
||||||
|
[Full list of changes](https://github.com/weaveworks/weave/milestone/71?closed=1)
|
||||||
|
|
||||||
|
## 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
|
## Release 2.1.3
|
||||||
|
|
||||||
This release fixes a race-condition in the IP reclaim code for weave-kube
|
This release fixes a race-condition in the IP reclaim code for weave-kube
|
||||||
|
|||||||
+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
|
||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-2
@@ -108,7 +108,12 @@ func (ns *ns) analysePolicy(policy *networkingv1.NetworkPolicy) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
podSelectors[dstSelector.key] = dstSelector
|
|
||||||
|
// To prevent dstSelector being overwritten by a subsequent selector with
|
||||||
|
// the same key, addIfNotExist MUST be used when adding to podSelectors.
|
||||||
|
// Otherwise, dstSelector' "dst" property might be lost resulting in
|
||||||
|
// an invalid content of the "default-allow" ipset.
|
||||||
|
addIfNotExist(dstSelector, podSelectors)
|
||||||
|
|
||||||
// If ingress is empty then this NetworkPolicy does not allow any traffic
|
// If ingress is empty then this NetworkPolicy does not allow any traffic
|
||||||
if policy.Spec.Ingress == nil || len(policy.Spec.Ingress) == 0 {
|
if policy.Spec.Ingress == nil || len(policy.Spec.Ingress) == 0 {
|
||||||
@@ -142,7 +147,7 @@ func (ns *ns) analysePolicy(policy *networkingv1.NetworkPolicy) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
podSelectors[srcSelector.key] = srcSelector
|
addIfNotExist(srcSelector, podSelectors)
|
||||||
|
|
||||||
} else if peer.NamespaceSelector != nil {
|
} else if peer.NamespaceSelector != nil {
|
||||||
srcSelector, err = newSelectorSpec(peer.NamespaceSelector, false, "", ipset.ListSet)
|
srcSelector, err = newSelectorSpec(peer.NamespaceSelector, false, "", ipset.ListSet)
|
||||||
@@ -168,6 +173,12 @@ func (ns *ns) analysePolicy(policy *networkingv1.NetworkPolicy) (
|
|||||||
return rules, nsSelectors, podSelectors, nil
|
return rules, nsSelectors, podSelectors, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addIfNotExist(s *selectorSpec, ss map[string]*selectorSpec) {
|
||||||
|
if _, ok := ss[s.key]; !ok {
|
||||||
|
ss[s.key] = s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func withNormalisedProtoAndPortLegacy(npps []extnapi.NetworkPolicyPort, f func(proto, port string)) {
|
func withNormalisedProtoAndPortLegacy(npps []extnapi.NetworkPolicyPort, f func(proto, port string)) {
|
||||||
for _, npp := range npps {
|
for _, npp := range npps {
|
||||||
f(proto(npp.Protocol), port(npp.Port))
|
f(proto(npp.Protocol), port(npp.Port))
|
||||||
|
|||||||
@@ -294,6 +294,11 @@ func TestDefaultAllow(t *testing.T) {
|
|||||||
controller.DeletePod(podFoo)
|
controller.DeletePod(podFoo)
|
||||||
// Should remove foo pod from default-allow
|
// Should remove foo pod from default-allow
|
||||||
require.False(t, m.entryExists(defaultAllowIPSetName, fooPodIP))
|
require.False(t, m.entryExists(defaultAllowIPSetName, fooPodIP))
|
||||||
|
|
||||||
|
controller.DeleteNamespace(defaultNamespace)
|
||||||
|
// Should remove default ipset
|
||||||
|
require.NotContains(t, m.sets, defaultAllowIPSetName)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOutOfOrderPodEvents(t *testing.T) {
|
func TestOutOfOrderPodEvents(t *testing.T) {
|
||||||
@@ -376,3 +381,76 @@ func TestOutOfOrderPodEvents(t *testing.T) {
|
|||||||
require.Equal(t, 0, len(m.sets[defaultAllowIPSetName].subSets))
|
require.Equal(t, 0, len(m.sets[defaultAllowIPSetName].subSets))
|
||||||
require.False(t, m.entryExists(runBarIPSetName, podIP))
|
require.False(t, m.entryExists(runBarIPSetName, podIP))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test case for https://github.com/weaveworks/weave/issues/3222
|
||||||
|
func TestNewDstSelector(t *testing.T) {
|
||||||
|
const (
|
||||||
|
defaultAllowIPSetName = "weave-E.1.0W^NGSp]0_t5WwH/]gX@L"
|
||||||
|
podIP = "10.32.0.10"
|
||||||
|
)
|
||||||
|
|
||||||
|
m := newMockIPSet()
|
||||||
|
controller := New("baz", false, &mockIPTables{}, &m)
|
||||||
|
|
||||||
|
defaultNamespace := &coreapi.Namespace{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "default",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
controller.AddNamespace(defaultNamespace)
|
||||||
|
|
||||||
|
podFoo := &coreapi.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
UID: "foo",
|
||||||
|
Namespace: "default",
|
||||||
|
Name: "foo",
|
||||||
|
Labels: map[string]string{"run": "foo"}},
|
||||||
|
Status: coreapi.PodStatus{PodIP: podIP}}
|
||||||
|
controller.AddPod(podFoo)
|
||||||
|
|
||||||
|
require.True(t, m.entryExists(defaultAllowIPSetName, podIP))
|
||||||
|
|
||||||
|
netpolBar := &networkingv1.NetworkPolicy{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
UID: "netpol-bar",
|
||||||
|
Name: "allow-from-default-1",
|
||||||
|
Namespace: "default",
|
||||||
|
},
|
||||||
|
Spec: networkingv1.NetworkPolicySpec{
|
||||||
|
PodSelector: metav1.LabelSelector{},
|
||||||
|
Ingress: []networkingv1.NetworkPolicyIngressRule{{
|
||||||
|
From: []networkingv1.NetworkPolicyPeer{{
|
||||||
|
PodSelector: &metav1.LabelSelector{},
|
||||||
|
}},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
controller.AddNetworkPolicy(netpolBar)
|
||||||
|
|
||||||
|
// netpolBar dst selector selects podFoo
|
||||||
|
require.False(t, m.entryExists(defaultAllowIPSetName, podIP))
|
||||||
|
|
||||||
|
netpolFoo := &networkingv1.NetworkPolicy{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
UID: "netpol-foo",
|
||||||
|
Name: "allow-from-default-2",
|
||||||
|
Namespace: "default",
|
||||||
|
},
|
||||||
|
Spec: networkingv1.NetworkPolicySpec{
|
||||||
|
PodSelector: metav1.LabelSelector{},
|
||||||
|
Ingress: []networkingv1.NetworkPolicyIngressRule{{
|
||||||
|
From: []networkingv1.NetworkPolicyPeer{{
|
||||||
|
PodSelector: &metav1.LabelSelector{},
|
||||||
|
}},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
controller.AddNetworkPolicy(netpolFoo)
|
||||||
|
|
||||||
|
controller.DeleteNetworkPolicy(netpolBar)
|
||||||
|
// netpolFoo dst-selects podFoo
|
||||||
|
require.False(t, m.entryExists(defaultAllowIPSetName, podIP))
|
||||||
|
controller.DeleteNetworkPolicy(netpolFoo)
|
||||||
|
// No netpol dst-selects podFoo
|
||||||
|
require.True(t, m.entryExists(defaultAllowIPSetName, podIP))
|
||||||
|
}
|
||||||
+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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
-1
@@ -471,7 +471,16 @@ func (ns *ns) deleteNamespace(obj *coreapi.Namespace) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove namespace ipset from any matching namespace selectors
|
// Remove namespace ipset from any matching namespace selectors
|
||||||
return ns.nsSelectors.delFromMatching(obj.ObjectMeta.UID, obj.ObjectMeta.Labels, string(ns.allPods.ipsetName))
|
err := ns.nsSelectors.delFromMatching(obj.ObjectMeta.UID, obj.ObjectMeta.Labels, string(ns.allPods.ipsetName))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ns.legacy {
|
||||||
|
return ns.ips.Destroy(ns.defaultAllowIPSet)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ns *ns) isDefaultDeny(namespace *coreapi.Namespace) bool {
|
func (ns *ns) isDefaultDeny(namespace *coreapi.Namespace) bool {
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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) \
|
||||||
|
|||||||
@@ -101,6 +101,8 @@ items:
|
|||||||
name: weave-net
|
name: weave-net
|
||||||
namespace: kube-system
|
namespace: kube-system
|
||||||
spec:
|
spec:
|
||||||
|
# Wait 5 seconds to let pod connect before rolling next pod
|
||||||
|
minReadySeconds: 5
|
||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ RUN apk add --update \
|
|||||||
util-linux \
|
util-linux \
|
||||||
conntrack-tools \
|
conntrack-tools \
|
||||||
bind-tools \
|
bind-tools \
|
||||||
|
ca-certificates \
|
||||||
&& rm -rf /var/cache/apk/*
|
&& rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
ADD ./weave ./weaver /home/weave/
|
ADD ./weave ./weaver /home/weave/
|
||||||
ADD ./weaveutil /usr/bin/
|
ADD ./weaveutil /usr/bin/
|
||||||
ADD weavedata.db /weavedb/
|
ADD weavedata.db /weavedb/
|
||||||
COPY ca-certificates.crt /etc/ssl/certs/
|
|
||||||
ENTRYPOINT ["/home/weave/weaver"]
|
ENTRYPOINT ["/home/weave/weaver"]
|
||||||
WORKDIR /home/weave
|
WORKDIR /home/weave
|
||||||
File diff suppressed because it is too large.
Load diff
+20
-14
@@ -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 {
|
||||||
@@ -178,7 +186,7 @@ func main() {
|
|||||||
mflag.StringVar(&logLevel, []string{"-log-level"}, "info", "logging level (debug, info, warning, error)")
|
mflag.StringVar(&logLevel, []string{"-log-level"}, "info", "logging level (debug, info, warning, error)")
|
||||||
mflag.BoolVar(&pktdebug, []string{"-pkt-debug"}, false, "enable per-packet debug logging")
|
mflag.BoolVar(&pktdebug, []string{"-pkt-debug"}, false, "enable per-packet debug logging")
|
||||||
mflag.StringVar(&prof, []string{"-profile"}, "", "enable profiling and write profiles to given path")
|
mflag.StringVar(&prof, []string{"-profile"}, "", "enable profiling and write profiles to given path")
|
||||||
mflag.IntVar(&config.ConnLimit, []string{"-conn-limit"}, 30, "connection limit (0 for unlimited)")
|
mflag.IntVar(&config.ConnLimit, []string{"-conn-limit"}, 100, "connection limit (0 for unlimited)")
|
||||||
mflag.BoolVar(&noDiscovery, []string{"-no-discovery"}, false, "disable peer discovery")
|
mflag.BoolVar(&noDiscovery, []string{"-no-discovery"}, false, "disable peer discovery")
|
||||||
mflag.IntVar(&bufSzMB, []string{"-bufsz"}, 8, "capture buffer size in MB")
|
mflag.IntVar(&bufSzMB, []string{"-bufsz"}, 8, "capture buffer size in MB")
|
||||||
mflag.IntVar(&bridgeConfig.MTU, []string{"-mtu"}, 0, "MTU size")
|
mflag.IntVar(&bridgeConfig.MTU, []string{"-mtu"}, 0, "MTU size")
|
||||||
@@ -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,14 +149,31 @@ 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](https://v1-7.docs.kubernetes.io/docs/api-reference/v1.7/#networkpolicy-v1-networking)
|
definition](https://v1-7.docs.kubernetes.io/docs/api-reference/v1.7/#networkpolicy-v1-networking)
|
||||||
|
|
||||||
@@ -167,6 +186,11 @@ definition](https://v1-7.docs.kubernetes.io/docs/api-reference/v1.7/#networkpoli
|
|||||||
|
|
||||||
## <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:
|
||||||
@@ -287,11 +311,11 @@ UDP connection from 10.32.0.7:56648 to 10.32.0.11:80 blocked by Weave NPC.
|
|||||||
You can customise the YAML you get from `cloud.weave.works` by passing some of Weave Net's options, arguments and environment variables as query parameters:
|
You can customise the YAML you get from `cloud.weave.works` by passing some of Weave Net's options, arguments and environment variables as query parameters:
|
||||||
|
|
||||||
- `version`: Weave Net's version. Default: `latest`, i.e. latest release. *N.B.*: This only changes the specified version inside the generated YAML file, it does not ensure that the rest of the YAML is compatible with that version. To freeze the YAML version save a copy of the YAML file from the [release page](https://github.com/weaveworks/weave/releases) and use that copy instead of downloading it each time from `cloud.weave.works`.
|
- `version`: Weave Net's version. Default: `latest`, i.e. latest release. *N.B.*: This only changes the specified version inside the generated YAML file, it does not ensure that the rest of the YAML is compatible with that version. To freeze the YAML version save a copy of the YAML file from the [release page](https://github.com/weaveworks/weave/releases) and use that copy instead of downloading it each time from `cloud.weave.works`.
|
||||||
- `password-secret`: name of the Kubernetes secret containing your password.
|
- `password-secret`: name of the Kubernetes secret containing your password. *N.B*: The Kubernetes secret name must correspond to a name of a file containing your password.
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
$ echo "s3cr3tp4ssw0rd" > /var/lib/weave/weave-passwd.txt
|
$ echo "s3cr3tp4ssw0rd" > /var/lib/weave/weave-passwd
|
||||||
$ kubectl create secret -n kube-system generic weave-passwd --from-file=/var/lib/weave/weave-passwd.txt
|
$ kubectl create secret -n kube-system generic weave-passwd --from-file=/var/lib/weave/weave-passwd
|
||||||
$ kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')&password-secret=weave-passwd"
|
$ kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')&password-secret=weave-passwd"
|
||||||
|
|
||||||
- `known-peers`: comma-separated list of hosts. Default: empty.
|
- `known-peers`: comma-separated list of hosts. Default: empty.
|
||||||
@@ -299,12 +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-7.docs.kubernetes.io/docs/api-reference/v1.7/#networkpolicy-v1-networking), boolean (`true|false`). Default: `true` for Kubernetes version <= 1.6, `false` for > 1.6.
|
- `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