Compare commits

..
55 Commits
Author SHA1 Message Date
Bryan Boreham a7ebe53cfa Add release v1.9.8 2017-06-15 17:05:11 +00:00
Marc Carré b655a3aede Merge pull request #3014 from weaveworks/issues/3011-allow-non-pod-source
Allow any non-local traffic onto the weave bridge
2017-06-14 14:52:11 +01:00
Bryan Boreham 819b395ae4 Temporarily raise the test timeout
Docker 1.11 seems much slower at the pull tests than Docker 1.13
while we investigate that, raise the timeout to allow tests to pass
2017-06-14 13:14:06 +00:00
Bryan Boreham 2584335b11 Allow any non-local traffic onto the weave bridge
If it's destined for a pod on another node it will be checked again
when it reaches that other node.  The previous version was rejecting
traffic coming in from outside the cluster.
2017-06-12 17:00:57 +00:00
Bryan Boreham 21d4fff450 Update broken link to Docker docs 2017-06-12 09:42:22 +01:00
Marc Carré a5d7fb66f0 Merge pull request #3010 from weaveworks/issues/3003-anonymous-claim
Fix use of '_' as container ID in claim outside range
2017-06-09 08:30:13 +01:00
Bryan Boreham b01a204c1f Check who previously owned an address claimed outside the range 2017-06-08 16:25:09 +00:00
Bryan Boreham e9310eba98 Don't use '_' as container ID in claim outside range
And added unit test for various claim-without-ID situations
2017-06-07 16:38:19 +00:00
Bryan Boreham 69285270e5 Bump Ruby version
2.3.4 is pre-installed by CircleCI, whereas 2.3.0 isn't
2017-06-07 13:01:15 +00:00
Bryan Boreham 6bd11a426e typo 2017-06-01 14:28:10 +00:00
Bryan Boreham 1abdc3afcf Add release v1.9.7 2017-06-01 13:51:06 +00:00
Bryan Boreham b8f98a5387 Merge pull request #2996 from Bregor/issues/2995-npc-and-hostname_override
Weave-NPC should get hostname from K8s Downward API.
2017-06-01 14:33:22 +01:00
Maxim Filatov cb3b858df6 Weave-NPC should get hostname from K8s Downward API.
It is necessary in case when kubelet's args includes `--hostname_override=`.
Without this change, pods on hostname overriding kubelets will never be local,
and all pod's traffic will be blocked.
2017-05-31 18:06:17 +03:00
Bryan Boreham afb0d5bd3d Add release v1.9.6 2017-05-30 16:28:11 +00:00
Bryan Boreham 2d3e070288 Let through connections from local pods to non-local pods
This means we only filter connections at the destination end,
which is a better match for the ingress-only rules.
2017-05-30 14:11:35 +00:00
Bryan Boreham 138141ac9b Ignore updates for pods on other nodes 2017-05-30 14:11:34 +00:00
Bryan Boreham fa56ad8bc3 Refactor: move logging of ipset entries down to ipset package 2017-05-30 14:11:33 +00:00
Bryan Boreham 9d29da8d27 Refactor creation of base iptables rules 2017-05-30 14:11:31 +00:00
Bryan Boreham 68f2cb9caa Merge pull request #2993 from weaveworks/hairpin-option-1.9
Turn on hairpin mode on veth bridge ports
2017-05-30 14:50:37 +01:00
Avi Deitcher d13c7ea7ee Make hairpin mode default true in CNI 2017-05-30 10:30:54 +00:00
Avi Deitcher 4c7c702b6d Test of hairpin mode in CNI 2017-05-30 10:30:54 +00:00
Avi Deitcher c05955d598 First cut of adding hairpin functionality to weave 2017-05-30 10:30:49 +00:00
Bryan Boreham ca64ab54e7 Remove trailing space 2017-05-30 10:30:02 +00:00
Àbéjídé Àyodélé e64442f6de Highlight the forward rules 2017-05-25 13:43:51 +00:00
Bryan Boreham 987a1618e9 Merge pull request #2985 from weaveworks/fix-broken-url-to-ecs-guide
Fix broken link to ECS guide
2017-05-23 17:59:49 +01:00
Marc CARRE 0ab95cdd27 Fix broken URL to ECS guide. 2017-05-23 16:58:36 +00:00
Marc Carré b0d0c3d731 Merge pull request #2986 from weaveworks/remove-wordepress
Stop doing Wordpress previews on Pantheon
2017-05-23 12:01:05 +01:00
Bryan Boreham 534dd8e16a Stop doing Wordpress previews on Pantheon
Now we are using Netlify instead
2017-05-23 11:33:57 +01:00
Marc Carré 79e703c8ac Merge pull request #2987 from weaveworks/use-fixed-version-of-shfmt
Use shfmt v1.3.0 instead of latest from master
2017-05-23 11:31:03 +01:00
Marc CARRE d4a98a58f4 Use shfmt v1.3.0 instead of latest from master.
Before this change, `go get`-ting` would pick the latest version of `shfmt` which keeps changing, hence frequently breaking our builds.

After this change, we download the `shfmt` binary from its GitHub releases page which is fast and locks the version we use. Note that `RUN` does not like herestrings, hence `echo "..." | sha256sum -c` for checksum.

Alternatives considered:
- `go get gopkg.in/mvdan/sh.v1/cmd/shfmt` -- but `gopkg.in` currently doesn't behave well for this tool
- `go build` from a `git` tag -- but this is much more involved.
2017-05-23 10:59:11 +01:00
Bryan Boreham 72532324ed Give up on versioned copy of shfmt; it doesn't build 2017-05-18 10:18:11 +00:00
Marc Carré 68106d804e Merge pull request #2959 from ocadotechnology/wip-2958
fix(npc): create ipsets with only valid xml characters
2017-05-15 13:30:10 +01:00
Bryan Boreham efff6d6e63 Merge pull request #2962 from weaveworks/fix-shfmt-lint-error
Fix shfmt lint error by escaping $ in sed expression
2017-05-15 13:21:12 +01:00
Marc CARRE 6bbd8d7a4c Escape $ in sed expression.
This fixes new error raised by latest version of shfmt, leading to build failures.
2017-05-15 12:36:55 +01:00
stuart.warren 9cbf0289d8 fix(npc): create ipsets with only valid xml characters
Why:
* xml output of ipset is invalid because ipset itself doesn't appear to
 escape invalid chars

* fixes #2958
2017-05-15 11:20:04 +01:00
Bryan Boreham 255d087416 Merge pull request #2949 from ocadotechnology/wip-2915
Flush weave ipsets before destroying
2017-05-12 13:15:09 +01:00
Mike Bryant 8668f6bb1e Flush weave ipsets before destroying
ipsets can't be destroyed when there are references to them.
This takes the easy way out and flushes all weave ipsets first.

Fixes #2915
2017-05-12 09:44:26 +01:00
Mike Bryant 95ee99d652 style: singular vs plural 2017-05-12 09:44:18 +01:00
Bryan Boreham 30583ec8f2 Merge pull request #2930 from weaveworks/fix-broken-links
Fix some broken links in documentation
2017-05-11 16:24:00 +01:00
Bryan Boreham e370ef7007 Fix 'How Weave Finds Containers' link 2017-05-11 15:06:29 +00:00
Ilya Dmitrichenko 42953faf70 Fix some broken links in documentation 2017-05-11 15:06:20 +00:00
Bryan Boreham 6c29a1f648 Merge pull request #2940 from weaveworks/fix_libssl_mismatch
Fix build libssl issue: Use cross-compilers from debian rather than ubuntu
2017-05-09 13:37:10 +01:00
Marcus Cobden fa29b18be7 Use cross-compilers from debian rather than ubuntu 2017-05-09 09:32:54 +00:00
Bryan Boreham 40db885b3a Merge pull request #2935 from ocadotechnology/wip-2934
Clean up xt_set_exists components in advance
2017-05-09 10:04:56 +01:00
Bryan Boreham ae0c16f375 Merge pull request #2884 from weaveworks/issues/2794-kube-evict-docs
Add pod resources and eviction to weave-kube doc
2017-05-09 10:02:54 +01:00
Bryan Boreham 909b751d6d Explain how to see Evicted pods 2017-05-08 13:14:59 +00:00
Mike Bryant 9419ad16bf Clean up xt_set_exists components in advance
If this function dies in the middle, the leftover weave-kube-test set
causes this function and weave-npc to break. In particular
this means we can never restart weave with the launch script.

Here we clean up in advance, in case there's leftovers from a previous run

Fixes #2934
2017-05-08 12:15:23 +01:00
Bryan Boreham 2c12c4f67e Merge pull request #2928 from weaveworks/issues/2921-ignore-enoent-on-iface-del
Ignore errors on network interface delete during CNI Delete
2017-05-05 20:45:38 +01:00
Marc CARRE be11db45d8 Ignore error when deleting a container's interface.
Fixes #2921, as all errors are now ignored, including `ENOENT`.
This command typically attempts to delete the network interface `eth0` of a container being destroyed by Kubernetes.
If this interface has already been destroyed or is missing for whatever reason, we still want to remove this container's entry from IPAM in order to free associated resources.
2017-05-05 17:24:08 +00:00
Marc CARRE 30213bd71e Comply to CNI 0.5 spec by always returning nil on DEL.
See also:
  "Plugins should generally complete a DEL action without error even if some resources are missing."
in:
  https://github.com/containernetworking/cni/blob/v0.5.0/SPEC.md
2017-05-05 17:24:08 +00:00
Bryan Boreham b14501f358 Merge pull request #2931 from weaveworks/patch-wordepress
Use a version of wordepress that handles 'search-type' attribute
2017-05-05 18:21:42 +01:00
Bryan Boreham e93a145bab Build a version of wordepress that handles 'search-type' attribute 2017-05-05 16:58:33 +00:00
Ilya Dmitrichenko 8b245a442c Add website preview 2017-05-05 15:23:08 +01:00
Bryan Boreham 109e249aa6 Review feedback 2017-04-25 14:08:25 +00:00
Bryan Boreham 60c5e11871 Add pod resources and eviction to weave-kube doc 2017-04-11 12:29:27 +00:00
39 changed files with 387 additions and 202 deletions

No files matched your search

+3
View File
@@ -70,3 +70,6 @@ test/coverage.*
*qemu-*-static
terraform.tfstate
terraform.tfstate.backup
# Website
site-build
+1
View File
@@ -0,0 +1 @@
2.3.4
+46
View File
@@ -1,3 +1,49 @@
## Release 1.9.8
Bug fixes and minor improvements
* Fix weave-npc blocking NodePort and any other non-local access #3011,#3014
* Fix bug where IPAM would duplicate a fixed IP address assigned via Docker plugin #3003,#3010
[Full list of changes](https://github.com/weaveworks/weave/milestone/56?closed=1).
## Release 1.9.7
This is identical to 1.9.6 with one additional bug-fix:
* weave-npc would block everything if `kubelet --hostname-override` was used #2995,#2996
## Release 1.9.6
Bug fixes and minor improvements
* Ensure that Kubernetes pods can contact a service implemented within
the same pod, by turning on "hairpin mode". This is required because
of a quiet change between Kubernetes 1.5 and 1.6. #2993
* Network Policy Controller (`weave-npc`) now checks local addresses
only, so it doesn't interfere with cross-cluster traffic. It should
be more efficient too #2622,#2973,#2979
* Stop reporting back to Kubernetes any issues encountered when
deleting a pod's network interface. This is required because
of a quiet change between Kubernetes 1.5 and 1.6. #2921,#2928
* Fixed an issue whereby `weave-npc` couldn't start because one
`ipset` was referring to another one and could not be destroyed #2915,#2949
* Improved the code which checks whether the kernel supports `ipset` #2934,#2935
* `weave-npc` now creates ipsets with only valid xml characters in the
name #2958,#2959
Build and Testing
* In build container use cross-compilers from debian package
repository, so they match other components #2940
* Pin the version of the linting tool `shfmt` so the set of things it
checks is stable #2987
* Fix lint error in script that runs smoke-tests #2962
* Moved website publishing from Wordpress to Netlify #2986
[Full list of changes](https://github.com/weaveworks/weave/milestone/55?closed=1).
## Release 1.9.5
Bug fixes and minor improvements
+11
View File
@@ -378,3 +378,14 @@ integration-tests: all testrunner
# integration-tests
#
RUNNER_ARGS="-parallel" ./test/run-integration-tests.sh
# This target is only intended for use in Netlify CI environment for generating preview pages on feature branches and pull requests.
# We need to obtain website repository (checked out under `site-build`) and place `site` directory into the context (`site-build/_weave_net_docs`).
# We then run make in `site-build` and Netlify will publish the output (`site-build/_site`).
netlify-site-preview:
@mkdir -p site-build
@curl --user $(WEBSITE_GITHUB_USER) --silent 'https://codeload.github.com/weaveworks/website-next/tar.gz/$(WEBSITE_BRANCH)' \
| tar --extract --gunzip --directory site-build --strip 1
@cp -r site site-build/_weave_net_docs
@$(MAKE) -C site-build netlify_ensure_install
@$(MAKE) -C site-build BUILD_ENV=netlify
-43
View File
@@ -1,43 +0,0 @@
#!/bin/bash
set -e
set -o pipefail
source "$STATE"
site_changes() {
curl -s https://api.github.com/repos/weaveworks/weave/pulls/$1/files |
jq -r '.[]|.status + " " + .filename' |
grep -oP '^(added|modified|removed) site/.*(?=\.md$)'
}
format_comment() {
if [ ! -d .git ] || ! BRANCH=$(git symbolic-ref --short HEAD) || [ -z "$BRANCH" ] ; then
echo "Could not determine branch" >&2
return 1
fi
echo "#### Documentation changes:"
while read ACTION PAGE; do
echo "$ACTION [${PAGE#site/}]($WP_DEV_URL/docs/net/${BRANCH#issues/}/${PAGE#site/}/)"
done | sort
}
post_comment() {
jq -s -R '. | tostring | { body: . }' |
curl -s -d @- \
-H "Authorization: Bearer $WP_GH_COMMENT_TOKEN" \
-H 'Content-Type: application/json' \
https://api.github.com/repos/weaveworks/weave/issues/$GH_PR/comments > /dev/null
}
cd $SRCDIR
bin/install-wordepress v1.0.0
bin/publish-site "$WP_DEV_URL" "$WP_DEV_USER" "$WP_DEV_PASSWORD"
if [ -n "$WP_GH_COMMENT_TOKEN" -a -n "$GH_PR" ] ; then
echo ">>> Adding doc changelog to GitHub PR $GH_PR"
if CHANGES=$(site_changes $GH_PR) && [ -n "$CHANGES" ] ; then
echo "$CHANGES" | format_comment | post_comment
fi
fi
-4
View File
@@ -11,7 +11,3 @@ if [ -n "$TEST_AND_PUBLISH" ] ; then
# CircleCI doesn't let us install the qemu module to do ARM docker builds
make publish ALL_ARCHITECTURES=amd64 UPDATE_LATEST=latest-only
fi
cd $SRCDIR
bin/install-wordepress v1.0.0
bin/publish-site "$WP_DEV_URL" "$WP_DEV_USER" "$WP_DEV_PASSWORD"
-7
View File
@@ -1,7 +0,0 @@
#!/bin/bash
set -e
cd $SRCDIR
bin/install-wordepress v1.0.0
bin/publish-site "$WP_LIVE_URL" "$WP_LIVE_USER" "$WP_LIVE_PASSWORD"
-12
View File
@@ -1,12 +0,0 @@
#!/bin/bash
if [ $# -ne 1 ] ; then
echo USAGE: install-wordepress [COMMIT-ISH] >&2
exit 1
fi
go get github.com/weaveworks/wordepress
cd /home/ubuntu/src/github.com/weaveworks/wordepress
git checkout $1
cd cmd/wordepress
go get
-46
View File
@@ -1,46 +0,0 @@
#!/bin/bash
set -e
set -o pipefail
PRODUCT=net
fatal() {
echo "$@" >&2
exit 1
}
if [ ! -d .git ] ; then
fatal "Current directory is not a git clone"
fi
if ! BRANCH=$(git symbolic-ref --short HEAD) || [ -z "$BRANCH" ] ; then
fatal "Could not determine branch"
fi
case "$BRANCH" in
issues/*)
VERSION="${BRANCH#issues/}"
TAGS="$VERSION"
;;
*)
if echo "$BRANCH" | grep -qE '^[0-9]+\.[0-9]+' ; then
DESCRIBE=$(git describe --match 'v*')
if ! VERSION=$(echo "$DESCRIBE" | grep -oP '(?<=^v)[0-9]+\.[0-9]+\.[0-9]+') ; then
fatal "Could not infer latest $BRANCH version from $DESCRIBE"
fi
TAGS="latest"
else
VERSION="$BRANCH"
TAGS="$VERSION"
fi
;;
esac
for TAG in $TAGS ; do
echo ">>> Publishing $PRODUCT $VERSION to $1/docs/$PRODUCT/$TAG"
wordepress \
--url "$1" --user "$2" --password "$3" \
--product "$PRODUCT" --version "$VERSION" --tag "$TAG" \
publish site
done
+8 -5
View File
@@ -20,13 +20,12 @@ ENV GCC_CROSSCOMPILERS \
# Temporarily add the Ubuntu repositories, because we're going to install gcc cross-compilers from there
# Install the build-essential and crossbuild-essential-ARCH packages
RUN echo "deb http://archive.ubuntu.com/ubuntu xenial main universe" > /etc/apt/sources.list.d/cgocrosscompiling.list \
&& apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 40976EAF437D05B5 3B4FE6ACC0B21F32 \
RUN echo "deb http://emdebian.org/tools/debian/ jessie main" > /etc/apt/sources.list.d/cgocrosscompiling.list \
&& curl http://emdebian.org/tools/debian/emdebian-toolchain-archive.key | apt-key add - \
&& for platform in ${DEB_CROSSPLATFORMS}; do dpkg --add-architecture $platform; done \
&& apt-get update \
&& apt-get install -y build-essential \
&& for platform in ${DEB_CROSSPLATFORMS}; do apt-get install -y crossbuild-essential-${platform}; done \
&& rm /etc/apt/sources.list.d/cgocrosscompiling.list \
&& apt-get update \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Install some required packages
@@ -41,11 +40,15 @@ RUN apt-get update \
flex \
bison
RUN curl -fsSLo shfmt https://github.com/mvdan/sh/releases/download/v1.3.0/shfmt_v1.3.0_linux_amd64 && \
echo "b1925c2c405458811f0c227266402cf1868b4de529f114722c2e3a5af4ac7bb2 shfmt" | sha256sum -c && \
chmod +x shfmt && \
mv shfmt /usr/bin
# Install common Go tools
RUN go get \
github.com/golang/lint/golint \
github.com/fzipp/gocyclo \
gopkg.in/mvdan/sh.v1/cmd/shfmt \
github.com/fatih/hclfmt \
github.com/client9/misspell/cmd/misspell
-10
View File
@@ -59,18 +59,8 @@ teardown:
parallel: true
deployment:
release:
branch: /[0-9]+\.[0-9]+/
owner: weaveworks
commands:
- "$SRCDIR/bin/circle-deploy-release"
master:
branch: master
owner: weaveworks
commands:
- "$SRCDIR/bin/circle-deploy-master"
issues:
branch: /.*/
owner: weaveworks
commands:
- "$SRCDIR/bin/circle-deploy-issues"
+2
View File
@@ -77,8 +77,10 @@ iptables -A WEAVE-NPC -m state --state NEW -j WEAVE-NPC-INGRESS
To direct traffic into the policy engine:
```
iptables -A FORWARD -o weave -m physdev ! --physdev-out vethwe-bridge -j WEAVE-NPC
iptables -A FORWARD -o weave -m physdev ! --physdev-out vethwe-bridge -j DROP
```
Note this only affects traffic which egresses the bridge on a physical
port which is not the Weave Net router - in other words, it is
+19
View File
@@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/weaveworks/weave/api"
"github.com/weaveworks/weave/common"
"github.com/weaveworks/weave/net/address"
"github.com/weaveworks/weave/testing/gossip"
@@ -30,6 +31,10 @@ func (alloc *Allocator) SimplyClaim(ident string, cidr address.CIDR) error {
return alloc.Claim(ident, cidr, true, true, returnFalse)
}
func (alloc *Allocator) AnonymousClaim(cidr address.CIDR) error {
return alloc.Claim(api.NoContainerID, cidr, false, true, returnFalse)
}
func TestAllocFree(t *testing.T) {
const (
container1 = "abcdef"
@@ -170,6 +175,8 @@ func TestAllocatorClaim(t *testing.T) {
universe = "10.0.3.0/24"
testAddr1 = "10.0.3.5/24"
testAddr2 = "10.0.4.2/24"
testAddr4 = "10.0.2.3/23"
subnet4 = "10.0.2.0/23"
testPre = "10.0.3.1/24"
)
@@ -203,6 +210,9 @@ func TestAllocatorClaim(t *testing.T) {
// claim for a different container should fail
err = alloc.SimplyClaim(container1, addr1)
require.Error(t, err)
// claim for an anonymous container, will assume it's the same one
err = alloc.AnonymousClaim(addr1)
require.NoError(t, err)
// claiming the address allocated on the other peer should fail
err = alloc.SimplyClaim(container1, address.MakeCIDR(subnet, addrx))
require.Error(t, err, "claiming address allocated on other peer should fail")
@@ -215,6 +225,15 @@ func TestAllocatorClaim(t *testing.T) {
addr2, _ := address.ParseCIDR(testAddr2)
err = alloc.SimplyClaim(container1, addr2)
require.NoError(t, err)
err = alloc.SimplyClaim(container3, addr2)
require.Error(t, err)
// Anonymous claim outside of our universe
addr4, _ := address.ParseCIDR(testAddr4)
subnet4cidr, _ := address.ParseCIDR(subnet4)
require.NoError(t, alloc.AnonymousClaim(addr4))
addr5, err := alloc.Allocate(api.NoContainerID, subnet4cidr, false, returnFalse)
require.NoError(t, err)
require.NotEqual(t, addr4.Start(), addr5)
}
func (alloc *Allocator) pause() func() {
+22 -7
View File
@@ -40,10 +40,29 @@ func (c *claim) Try(alloc *Allocator) bool {
return true
}
addOwned := func() {
if c.ident == api.NoContainerID {
alloc.addOwned(c.cidr.Addr.String(), c.cidr, c.isContainer)
} else {
alloc.addOwned(c.ident, c.cidr, c.isContainer)
}
}
if !alloc.ring.Contains(c.cidr.Addr) {
// Address not within our universe; assume user knows what they are doing
alloc.infof("Address %s claimed by %s - not in our range", c.cidr, c.ident)
alloc.addOwned(c.ident, c.cidr, c.isContainer)
previousOwner := alloc.findOwner(c.cidr.Addr)
switch {
case previousOwner == "":
addOwned()
case previousOwner == c.ident: // already owned by this ID
case c.ident == api.NoContainerID: // already owned by anonymous container
// do nothing (no automatic fall-through in Go)
case !alloc.dead[previousOwner].IsZero(): // already owned by dead container
alloc.removeOwned(previousOwner, c.cidr.Addr)
addOwned()
default:
c.sendResult(fmt.Errorf("address %s already in use by %s", c.cidr, previousOwner))
}
c.sendResult(nil)
return true
}
@@ -85,11 +104,7 @@ func (c *claim) Try(alloc *Allocator) bool {
// Unused address, we try to claim it:
if err := alloc.space.Claim(c.cidr.Addr); err == nil {
alloc.debugln("Claimed", c.cidr, "for", c.ident)
if c.ident == api.NoContainerID {
alloc.addOwned(c.cidr.Addr.String(), c.cidr, c.isContainer)
} else {
alloc.addOwned(c.ident, c.cidr, c.isContainer)
}
addOwned()
c.sendResult(nil)
} else {
c.sendResult(err)
+6 -2
View File
@@ -113,7 +113,7 @@ func interfaceExistsInNamespace(netNSPath string, ifName string) bool {
// NB: This function can be used only by a process that terminates immediately
// after calling the function as it changes netns via WithNetNSLinkUnsafe.
func AttachContainer(netNSPath, id, ifName, bridgeName string, mtu int, withMulticastRoute bool, cidrs []*net.IPNet, keepTXOn bool) error {
func AttachContainer(netNSPath, id, ifName, bridgeName string, mtu int, withMulticastRoute bool, cidrs []*net.IPNet, keepTXOn bool, hairpinMode bool) error {
ns, err := netns.GetFromPath(netNSPath)
if err != nil {
return err
@@ -131,7 +131,7 @@ func AttachContainer(netNSPath, id, ifName, bridgeName string, mtu int, withMult
id = id[:maxIDLen] // trim passed ID if too long
}
name, peerName := vethPrefix+"pl"+id, vethPrefix+"pg"+id
_, err := CreateAndAttachVeth(name, peerName, bridgeName, mtu, keepTXOn, func(veth netlink.Link) error {
veth, err := CreateAndAttachVeth(name, peerName, bridgeName, mtu, keepTXOn, func(veth netlink.Link) error {
if err := netlink.LinkSetNsFd(veth, int(ns)); err != nil {
return fmt.Errorf("failed to move veth to container netns: %s", err)
}
@@ -143,6 +143,10 @@ func AttachContainer(netNSPath, id, ifName, bridgeName string, mtu int, withMult
if err != nil {
return err
}
if err = netlink.LinkSetHairpin(veth, hairpinMode); err != nil {
return fmt.Errorf("unable to set hairpin mode to %t for bridge side of veth %s: %s", hairpinMode, name, err)
}
}
if err := WithNetNSLinkUnsafe(ns, ifName, func(veth netlink.Link) error {
+2
View File
@@ -8,4 +8,6 @@ const (
IngressChain = "WEAVE-NPC-INGRESS"
IpsetNamePrefix = "weave-"
LocalIpset = IpsetNamePrefix + "local-pods"
)
+25 -4
View File
@@ -29,6 +29,8 @@ type NetworkPolicyController interface {
type controller struct {
sync.Mutex
nodeName string // my node name
ipt *iptables.IPTables
ips ipset.Interface
@@ -36,11 +38,12 @@ type controller struct {
nsSelectors *selectorSet // selector string -> nsSelector
}
func New(ipt *iptables.IPTables, ips ipset.Interface) NetworkPolicyController {
func New(nodeName string, ipt *iptables.IPTables, ips ipset.Interface) NetworkPolicyController {
c := &controller{
ipt: ipt,
ips: ips,
nss: make(map[string]*ns)}
nodeName: nodeName,
ipt: ipt,
ips: ips,
nss: make(map[string]*ns)}
c.nsSelectors = newSelectorSet(ips, c.onNewNsSelector)
@@ -82,10 +85,21 @@ func (npc *controller) withNS(name string, f func(ns *ns) error) error {
return nil
}
func (npc *controller) checkLocalPod(obj *coreapi.Pod, event string) bool {
if obj.Spec.NodeName != npc.nodeName {
common.Log.Debugf("%s ignored for pod %s/%s on node %s", event, obj.ObjectMeta.Namespace, obj.ObjectMeta.Name, obj.Spec.NodeName)
return false
}
return true
}
func (npc *controller) AddPod(obj *coreapi.Pod) error {
npc.Lock()
defer npc.Unlock()
if !npc.checkLocalPod(obj, "AddPod") {
return nil
}
common.Log.Debugf("EVENT AddPod %s", js(obj))
return npc.withNS(obj.ObjectMeta.Namespace, func(ns *ns) error {
return errors.Wrap(ns.addPod(obj), "add pod")
@@ -96,6 +110,10 @@ func (npc *controller) UpdatePod(oldObj, newObj *coreapi.Pod) error {
npc.Lock()
defer npc.Unlock()
// Pods don't move across nodes so we only check the new version
if !npc.checkLocalPod(newObj, "UpdatePod") {
return nil
}
common.Log.Debugf("EVENT UpdatePod %s %s", js(oldObj), js(newObj))
return npc.withNS(oldObj.ObjectMeta.Namespace, func(ns *ns) error {
return errors.Wrap(ns.updatePod(oldObj, newObj), "update pod")
@@ -106,6 +124,9 @@ func (npc *controller) DeletePod(obj *coreapi.Pod) error {
npc.Lock()
defer npc.Unlock()
if !npc.checkLocalPod(obj, "DeletePod") {
return nil
}
common.Log.Debugf("EVENT DeletePod %s", js(obj))
return npc.withNS(obj.ObjectMeta.Namespace, func(ns *ns) error {
return errors.Wrap(ns.deletePod(obj), "delete pod")
+6 -2
View File
@@ -1,6 +1,7 @@
package ipset
import (
"log"
"os/exec"
"strings"
@@ -31,10 +32,11 @@ type Interface interface {
type ipset struct {
refCount
*log.Logger
}
func New() Interface {
return &ipset{refCount: newRefCount()}
func New(logger *log.Logger) Interface {
return &ipset{refCount: newRefCount(), Logger: logger}
}
func (i *ipset) Create(ipsetName Name, ipsetType Type) error {
@@ -42,6 +44,7 @@ func (i *ipset) Create(ipsetName Name, ipsetType Type) error {
}
func (i *ipset) AddEntry(ipsetName Name, entry string) error {
i.Logger.Printf("adding entry %s to %s", entry, ipsetName)
if i.inc(ipsetName, entry) > 1 { // already in the set
return nil
}
@@ -49,6 +52,7 @@ func (i *ipset) AddEntry(ipsetName Name, entry string) error {
}
func (i *ipset) DelEntry(ipsetName Name, entry string) error {
i.Logger.Printf("deleting entry %s from %s", entry, ipsetName)
if i.dec(ipsetName, entry) > 0 { // still needed
return nil
}
+4
View File
@@ -88,6 +88,7 @@ func (ns *ns) addPod(obj *coreapi.Pod) error {
return nil
}
ns.ips.AddEntry(LocalIpset, obj.Status.PodIP)
return ns.podSelectors.addToMatching(obj.ObjectMeta.Labels, obj.Status.PodIP)
}
@@ -100,10 +101,12 @@ func (ns *ns) updatePod(oldObj, newObj *coreapi.Pod) error {
}
if hasIP(oldObj) && !hasIP(newObj) {
ns.ips.DelEntry(LocalIpset, oldObj.Status.PodIP)
return ns.podSelectors.delFromMatching(oldObj.ObjectMeta.Labels, oldObj.Status.PodIP)
}
if !hasIP(oldObj) && hasIP(newObj) {
ns.ips.AddEntry(LocalIpset, newObj.Status.PodIP)
return ns.podSelectors.addToMatching(newObj.ObjectMeta.Labels, newObj.Status.PodIP)
}
@@ -139,6 +142,7 @@ func (ns *ns) deletePod(obj *coreapi.Pod) error {
return nil
}
ns.ips.DelEntry(LocalIpset, obj.Status.PodIP)
return ns.podSelectors.delFromMatching(obj.ObjectMeta.Labels, obj.Status.PodIP)
}
-2
View File
@@ -43,12 +43,10 @@ func (s *selector) matches(labelMap map[string]string) bool {
}
func (s *selector) addEntry(entry string) error {
common.Log.Infof("adding entry %s to %s", entry, s.spec.ipsetName)
return s.ips.AddEntry(s.spec.ipsetName, entry)
}
func (s *selector) delEntry(entry string) error {
common.Log.Infof("deleting entry %s from %s", entry, s.spec.ipsetName)
return s.ips.DelEntry(s.spec.ipsetName, entry)
}
+3 -2
View File
@@ -7,12 +7,13 @@ import (
const (
// This array:
// * Must include only printable UTF8 characters that are represented with a single byte
// * Must include only printable UTF8 characters that are represented with a single byte (http://www.utf8-chartable.de/)
// * Must be at least of length 85 (`len("weave-") + l(2^160)/l(85)` equals 31, the maximum ipset name length)
// * Must not include commas as those are treated specially by `ipset add` when adding a named set to a list:set
// * Should not include space for readability
// * Should not include invalid chars for XML `<>&"'`
// * Should not include single quote or backslash to be nice to shell users
ShortNameSymbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789(){}[]<>_$%^&*|/?.;:@#~"
ShortNameSymbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789(){}[]+=_$%^!*|/?.;:@#~"
)
// sha1 hash an arbitrary string and represent it using the full range of
+22 -16
View File
@@ -6,7 +6,6 @@ import (
"fmt"
"net"
"os"
"strings"
"syscall"
"github.com/containernetworking/cni/pkg/ipam"
@@ -35,7 +34,8 @@ func NewCNIPlugin(weave *weaveapi.Client) *CNIPlugin {
func loadNetConf(bytes []byte) (*NetConf, error) {
n := &NetConf{
BrName: weavenet.WeaveBridgeName,
BrName: weavenet.WeaveBridgeName,
HairpinMode: true,
}
if err := json.Unmarshal(bytes, n); err != nil {
return nil, fmt.Errorf("failed to load netconf: %v", err)
@@ -129,7 +129,7 @@ func (c *CNIPlugin) CmdAdd(args *skel.CmdArgs) error {
id = fmt.Sprintf("%x", data)
}
if err := weavenet.AttachContainer(args.Netns, id, args.IfName, conf.BrName, conf.MTU, false, []*net.IPNet{&ip.Address}, false); err != nil {
if err := weavenet.AttachContainer(args.Netns, id, args.IfName, conf.BrName, conf.MTU, false, []*net.IPNet{&ip.Address}, false, conf.HairpinMode); err != nil {
return err
}
if err := weavenet.WithNetNSLinkUnsafe(ns, args.IfName, func(link netlink.Link) error {
@@ -183,16 +183,21 @@ func assignBridgeIP(bridgeName string, ipnet net.IPNet) error {
return nil
}
// As of CNI 0.5 spec:
// "Plugins should generally complete a DEL action without error even if some resources are missing"
// this method should therefore return nil in most, if not all, cases.
func (c *CNIPlugin) CmdDel(args *skel.CmdArgs) error {
conf, err := loadNetConf(args.StdinData)
if err != nil {
return err
logOnStderr(err)
return nil
}
// As of CNI 0.3 spec, runtimes can send blank if they just want the address deallocated
if args.Netns != "" {
if _, err = weavenet.WithNetNS(args.Netns, "del-iface", args.IfName); err != nil {
return fmt.Errorf("error removing interface %q: %s", args.IfName, err)
// We log the error and carry on instead of returning nil, as there may still be resources to free in IPAM.
logOnStderr(fmt.Errorf("error removing interface %q: %s", args.IfName, err))
}
}
@@ -202,20 +207,21 @@ func (c *CNIPlugin) CmdDel(args *skel.CmdArgs) error {
} else {
err = ipam.ExecDel(conf.IPAM.Type, args.StdinData)
}
// Hack - don't know how we should detect this situation properly
if args.Netns == "" && strings.Contains(err.Error(), "no addresses") {
err = nil
}
if err != nil {
return fmt.Errorf("unable to release IP address: %s", err)
}
logOnStderr(fmt.Errorf("unable to release IP address: %s", err))
return nil
}
// Standard error is inherited from the caller (e.g. Kubelet, when running Weave Net's CNI plugin
// under Kubernetes) hence provided errors should eventually appear in the caller's log files.
func logOnStderr(err error) {
fmt.Fprintln(os.Stderr, "weave-cni:", err)
}
type NetConf struct {
types.NetConf
BrName string `json:"bridge"`
IsGW bool `json:"isGateway"`
IPMasq bool `json:"ipMasq"`
MTU int `json:"mtu"`
BrName string `json:"bridge"`
IsGW bool `json:"isGateway"`
IPMasq bool `json:"ipMasq"`
MTU int `json:"mtu"`
HairpinMode bool `json:"hairpinMode"`
}
+5
View File
@@ -8,6 +8,11 @@ modprobe_safe() {
# Check whether xt_set actually exists
xt_set_exists() {
# Clean everything up in advance, in case there's leftovers
iptables -F WEAVE-KUBE-TEST 2>/dev/null || true
iptables -X WEAVE-KUBE-TEST 2>/dev/null || true
ipset destroy weave-kube-test 2>/dev/null || true
ipset create weave-kube-test hash:ip
iptables -t filter -N WEAVE-KUBE-TEST
if ! iptables -A WEAVE-KUBE-TEST -m set --match-set weave-kube-test src -j DROP; then
@@ -92,6 +92,12 @@ spec:
cpu: 10m
securityContext:
privileged: true
env:
- name: HOSTNAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
restartPolicy: Always
tolerations:
- key: node-role.kubernetes.io/master
+6
View File
@@ -59,6 +59,12 @@ spec:
cpu: 10m
securityContext:
privileged: true
env:
- name: HOSTNAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
restartPolicy: Always
volumes:
- name: weavedb
+53 -21
View File
@@ -28,6 +28,7 @@ var (
metricsAddr string
logLevel string
allowMcast bool
nodeName string
)
func handleError(err error) { common.CheckFatal(err) }
@@ -53,6 +54,41 @@ func resetIPTables(ipt *iptables.IPTables) error {
return err
}
return nil
}
func resetIPSets(ips ipset.Interface) error {
// Remove ipsets prefixed `weave-` only
sets, err := ips.List(npc.IpsetNamePrefix)
if err != nil {
common.Log.Errorf("Failed to retrieve list of ipsets")
return err
}
common.Log.Debugf("Got list of ipsets: %v", sets)
// Must remove references to ipsets by other ipsets before they're destroyed
for _, s := range sets {
common.Log.Debugf("Flushing ipset '%s'", string(s))
if err := ips.Flush(s); err != nil {
common.Log.Errorf("Failed to flush ipset '%s'", string(s))
return err
}
}
for _, s := range sets {
common.Log.Debugf("Destroying ipset '%s'", string(s))
if err := ips.Destroy(s); err != nil {
common.Log.Errorf("Failed to destroy ipset '%s'", string(s))
return err
}
}
return nil
}
func createBaseRules(ipt *iptables.IPTables, ips ipset.Interface) error {
// Configure main chain static rules
if err := ipt.Append(npc.TableFilter, npc.MainChain,
"-m", "state", "--state", "RELATED,ESTABLISHED", "-j", "ACCEPT"); err != nil {
@@ -76,26 +112,13 @@ func resetIPTables(ipt *iptables.IPTables) error {
return err
}
return nil
}
func resetIPSets(ips ipset.Interface) error {
// Remove ipsets prefixed `weave-` only
sets, err := ips.List(npc.IpsetNamePrefix)
if err != nil {
common.Log.Errorf("Failed to retrieve list of ipsets")
// If the destination address is not any of the local pods, let it through
if err := ips.Create(npc.LocalIpset, ipset.HashIP); err != nil {
return err
}
common.Log.Debugf("Got list of ipsets: %v", sets)
for _, s := range sets {
common.Log.Debugf("Destroying ipsets '%s'", string(s))
if err := ips.Destroy(s); err != nil {
common.Log.Errorf("Failed to destroy ipset '%s'", string(s))
return err
}
if err := ipt.Append(npc.TableFilter, npc.MainChain,
"-m", "set", "!", "--match-set", npc.LocalIpset, "dst", "-j", "ACCEPT"); err != nil {
return err
}
return nil
@@ -103,7 +126,14 @@ func resetIPSets(ips ipset.Interface) error {
func root(cmd *cobra.Command, args []string) {
common.SetLogLevel(logLevel)
common.Log.Infof("Starting Weaveworks NPC %s", version)
if nodeName == "" {
// HOSTNAME is set by Kubernetes for pods in the host network namespace
nodeName = os.Getenv("HOSTNAME")
}
if nodeName == "" {
common.Log.Fatalf("Must set node name via --node-name or $HOSTNAME")
}
common.Log.Infof("Starting Weaveworks NPC %s; node name %q", version, nodeName)
if err := metrics.Start(metricsAddr); err != nil {
common.Log.Fatalf("Failed to start metrics: %v", err)
@@ -122,12 +152,13 @@ func root(cmd *cobra.Command, args []string) {
ipt, err := iptables.New()
handleError(err)
ips := ipset.New()
ips := ipset.New(common.LogLogger())
handleError(resetIPTables(ipt))
handleError(resetIPSets(ips))
handleError(createBaseRules(ipt, ips))
npc := npc.New(ipt, ips)
npc := npc.New(nodeName, ipt, ips)
nsController := makeController(client.Core().RESTClient(), "namespaces", &coreapi.Namespace{},
cache.ResourceEventHandlerFuncs{
@@ -207,6 +238,7 @@ func main() {
rootCmd.PersistentFlags().StringVar(&metricsAddr, "metrics-addr", ":6781", "metrics server bind address")
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "debug", "logging level (debug, info, warning, error)")
rootCmd.PersistentFlags().BoolVar(&allowMcast, "allow-mcast", true, "allow all multicast traffic")
rootCmd.PersistentFlags().StringVar(&nodeName, "node-name", "", "only generate rules that apply to this node")
handleError(rootCmd.Execute())
}
+6 -2
View File
@@ -14,11 +14,12 @@ import (
func attach(args []string) error {
if len(args) < 4 {
cmdUsage("attach-container", "[--no-multicast-route] [--keep-tx-on] <container-id> <bridge-name> <mtu> <cidr>...")
cmdUsage("attach-container", "[--no-multicast-route] [--keep-tx-on] [--hairpin-mode=true|false] <container-id> <bridge-name> <mtu> <cidr>...")
}
keepTXOn := false
withMulticastRoute := true
hairpinMode := true
for i := 0; i < len(args); {
switch args[i] {
case "--no-multicast-route":
@@ -27,6 +28,9 @@ func attach(args []string) error {
case "--keep-tx-on":
keepTXOn = true
args = append(args[:i], args[i+1:]...)
case "--hairpin-mode=false":
hairpinMode = false
args = append(args[:i], args[i+1:]...)
default:
i++
}
@@ -55,7 +59,7 @@ func attach(args []string) error {
return err
}
err = weavenet.AttachContainer(weavenet.NSPathByPid(pid), fmt.Sprint(pid), weavenet.VethName, args[1], mtu, withMulticastRoute, cidrs, keepTXOn)
err = weavenet.AttachContainer(weavenet.NSPathByPid(pid), fmt.Sprint(pid), weavenet.VethName, args[1], mtu, withMulticastRoute, cidrs, keepTXOn, hairpinMode)
// If we detected an error but the container has died, tell the user that instead.
if err != nil && !processExists(pid) {
err = fmt.Errorf("Container %s died", args[0])
+1 -1
View File
@@ -12,7 +12,7 @@ search_type: Documentation
CNI, the [_Container Network Interface_](https://github.com/containernetworking/cni),
is a proposed standard for configuring network interfaces for Linux
application containers. CNI is supported by
[Kubernetes](http://kubernetes.io/), [Apache Mesos](mesos.apache.org)
[Kubernetes](http://kubernetes.io/), [Apache Mesos](http://mesos.apache.org)
and
[others](https://github.com/containernetworking/cni#who-is-using-cni).
+1 -1
View File
@@ -51,7 +51,7 @@ To disable this check, run the following before launching Weave Net:
CoreOS users see [here](/guides/networking-docker-containers-with-weave-on-coreos/) for an example of installing Weave using cloud-config.
Amazon ECS users see [here](https://github.com/weaveworks/integrations/blob/master/aws/ecs/README.md)
for the latest Weave AMIs and [here](http://weave.works/guides/service-discovery-with-weave-aws-ecs.html) to get started with Weave Net on ECS.
for the latest Weave AMIs and [here](https://www.weave.works/docs/tutorials/old-guides/ecs/) to get started with Weave Net on ECS.
If you're on Amazon EC2, the standard installation instructions at the
top of this page, provide the simplest setup and the most flexibility.
+66 -1
View File
@@ -9,6 +9,8 @@ The following topics are discussed:
* [Installation](#install)
* [Upgrading Kubernetes to version 1.6](#kube-1.6-upgrade)
* [Upgrading the Daemon Sets](#daemon-sets)
* [CPU and Memory Requirements](#resources)
* [Pod Eviction](#eviction)
* [Network Policy Controller](#npc)
* [Troubleshooting Blocked Connections](#blocked-connections)
* [Changing Configuration Options](#configuration-options)
@@ -35,7 +37,8 @@ After a few seconds, a Weave Net pod should be running on each
Node and any further pods you create will be automatically attached to the Weave
network.
**Note:** This command requires Kubernetes 1.4 or later.
**Note:** This command requires Kubernetes 1.4 or later, and we
recommend your master node has at least two CPU cores.
> CNI, the [_Container Network Interface_](https://github.com/containernetworking/cni),
> is a proposed standard for configuring network interfaces for Linux
@@ -92,6 +95,64 @@ and so you will need to perform the procedure manually:
lose track of IP address range ownership, possibly leading to
duplicate IP addresses if you then start a new copy of Weave Net.
## <a name="resources"></a>CPU and Memory Requirements
Kubernetes manages
[resources](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/)
on each node, and only schedules pods to run on nodes that have enough
free resources.
The components of a typical Kubernetes installation (with the master
node running etcd, scheduler, api-server, etc.) take up about 95% of a
CPU, which leaves little room to run anything else. For all of Weave
Net's features to work, it must run on every node, including the
master.
The best way to resolve this issue is to use machines with at least
two CPU cores. However if you are installing Kubernetes and Weave Net
for the first time, you may not be aware of this requirement. For this
reason, Weave Net launches as a DaemonSet with a specification that
reserves at least 1% CPU for each container. This enables Weave Net to
start up seamlessly on a single-CPU node.
Depending on the workload, Weave Net may need more than 1% of the
CPU. The percentage set in the DaemonSet is the minimum and not a
limit. This minimum setting allows Weave Net to take advantage of
available CPU and "burst" above that limit if it needs to.
## <a name="eviction"></a>Pod Eviction
If a node runs out of CPU, memory or disk, Kubernetes may [decide to
evict](https://kubernetes.io/docs/concepts/cluster-administration/out-of-resource/)
one or more pods. It may choose to evict the Weave Net pod, which will
disrupt pod network operations.
You can reduce the chance of eviction by changing the DaemonSet to
have a much bigger request, and a limit of the same value.
This causes Kubernetes to apply a ["guaranteed" rather than a
"burstable" policy](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/resource-qos.md).
However a similar request for disk space can not
be made, and so please be aware of this issue and monitor your
resources to ensure that they stay below 100%.
You can see when pods have been evicted via the `kubectl get events` command
```
LASTSEEN COUNT NAME KIND TYPE REASON SOURCE MESSAGE
1m 1 mypod-09vkd Pod Warning Evicted kubelet, node-1 The node was low on resource: memory.
```
or `kubectl get pods`
```
NAME READY STATUS RESTARTS AGE IP NODE
mypod-09vkd 0/1 Evicted 0 1h <none> node-1
```
If you see this in your cluster, consider some of the above steps to
reduce disruption.
## <a name="npc"></a>Network Policy Controller
The addon also supports the [Kubernetes policy
@@ -180,3 +241,7 @@ The list of variables you can set is:
a larger size for better performance if your network supports jumbo
frames - see [here](/site/using-weave/fastdp.md#mtu) for more
details.
* `HAIRPIN_MODE` - Weave Net defaults to enabling hairpin on the bridge side of
the `veth` pair for containers attached. If you need to disable hairpin, e.g. your
kernel is one of those that can panic if hairpin is enabled, then you can disable it
by setting `HAIRPIN_MODE=false`.
+1 -1
View File
@@ -44,7 +44,7 @@ or possible:
In some cases you may already be aware of the problem, as you were
unable to execute `weave reset` successfully or because you know
through other channels that the host has died. In these cases you can
proceed straight to [Manually Reclaiming Lost Address Space](#reclaim-address-space).
proceed straight to [Manually Reclaiming Lost Address Space](#manually-reclaim-address-space).
However in some scenarios it may not be obvious that space has been
lost, in which case you can check for it periodically with the
-1
View File
@@ -6,7 +6,6 @@ search_type: Documentation
* [Launching Weave Net and Running Containers Using the Plugin](#launching)
* [Restarting the Plugin](#restarting)
* [Configuring the Plugin](#configuring)
Docker versions 1.9 and later have a plugin mechanism for adding
different network providers. Weave Net installs itself as a network
+1 -1
View File
@@ -23,7 +23,7 @@ If you do create additional networks using the `weavemesh` driver, containers at
There's no specific documentation from Docker on using a cluster
store, but the first part of
[Getting Started with Docker Multi-host Networking](https://github.com/docker/docker/blob/master/docs/userguide/networking/get-started-overlay.md) is a good place to start.
[Getting Started with Docker Multi-host Networking](https://docs.docker.com/engine/userguide/networking/get-started-overlay/) is a good place to start.
>**Note:** In the case of multiple networks using the `weave` driver, all containers are on the same virtual network but Docker allocates their addresses on different subnets so they cannot talk to each other directly.
+1 -1
View File
@@ -49,7 +49,7 @@ WeaveDNS removes the addresses of any container that dies. This offers
a simple way to implement redundancy. E.g. if in our example we stop
one of the `pingme` containers and re-run the ping tests, eventually
(within ~30s at most, since that is the weaveDNS
[cache expiry time](#ttl)) we will only be hitting the address of the
[cache expiry time](/site/weavedns/managing-entries-weavedns.md#ttl)) we will only be hitting the address of the
container that is still alive.
**See Also**
+1 -5
View File
@@ -4,17 +4,13 @@ menu_order: 40
search_type: Documentation
---
The following topics are discussed:
* [Adding and removing extra DNS entries](#add-remove)
* [Resolving WeaveDNS entries from the Host](#resolve-weavedns-entries-from-host)
* [Hot-swapping Service Containers](#hot-swapping)
* [Retaining DNS Entries When Containers Stop](#retain-stopped)
* [Configuring a Custom TTL](#ttl)
### <a name="add-remove"></a>Adding and Removing Extra DNS Entries
If you want to give the container a name in DNS *other* than its
@@ -82,6 +78,6 @@ weaveDNS instance will receive.
**See Also**
* [How Weave Finds Containers](/site/how-works-weavedns.md)
* [How Weave Finds Containers](/site/weavedns/how-works-weavedns.md)
* [Load Balancing and Fault Resilience with WeaveDNS](/site/weavedns/load-balance-fault-weavedns.md)
* [Managing Domains](/site/weavedns/managing-domains-weavedns.md)
+52 -1
View File
@@ -8,7 +8,7 @@ cni_connect() {
pid=$(container_pid $1 $2)
id=$(docker_on $1 inspect -f '{{.Id}}' $2)
run_on $1 sudo CNI_COMMAND=ADD CNI_CONTAINERID=$id CNI_IFNAME=eth0 \
CNI_NETNS=/proc/$pid/ns/net CNI_PATH=/opt/cni/bin /opt/cni/bin/weave-net
CNI_NETNS=/proc/$pid/ns/net CNI_PATH=/opt/cni/bin /opt/cni/bin/weave-net
}
run_on $HOST1 sudo mkdir -p /opt/cni/bin
@@ -19,6 +19,11 @@ weave_on $HOST1 launch
C0=$(docker_on $HOST1 run --net=none --name=c0 -dt $SMALL_IMAGE /bin/sh)
C1=$(docker_on $HOST1 run --net=none --privileged --name=c1 -dt $SMALL_IMAGE /bin/sh)
C2=$(docker_on $HOST1 run --net=none --name=c2 -dt $SMALL_IMAGE /bin/sh)
CH0=$(docker_on $HOST1 run --net=none --name=ch0 -dt $SMALL_IMAGE /bin/sh)
CH1=$(docker_on $HOST1 run --net=none --name=ch1 -dt $SMALL_IMAGE /bin/sh)
CH2=$(docker_on $HOST1 run --net=none --name=ch2 -dt $SMALL_IMAGE /bin/sh)
# Enable unsolicited ARPs so that ping after the address reuse does not time out
exec_on $HOST1 c1 sysctl -w net.ipv4.conf.all.arp_accept=1
@@ -52,6 +57,29 @@ cni_connect $HOST1 c2 <<EOF
}
EOF
# examples to test hairpin
cni_connect $HOST1 ch0 <<EOF
{
"name": "weave",
"type": "weave-net",
"hairpinMode": true
}
EOF
cni_connect $HOST1 ch1 <<EOF
{
"name": "weave",
"type": "weave-net",
"hairpinMode": false
}
EOF
cni_connect $HOST1 ch2 <<EOF
{
"name": "weave",
"type": "weave-net"
}
EOF
C0IP=$(container_ip $HOST1 c0)
C1IP=$(container_ip $HOST1 c1)
C2IP=$(container_ip $HOST1 c2)
@@ -85,6 +113,29 @@ assert_raises "[ $C2IP != $C3IP ]"
assert_raises "[ $BRIP != $C3IP ]"
assert_raises "exec_on $HOST1 c1 $PING $C3IP"
#####
#
# Hairpin mode tests
#
# here we check that the bridge side of the veth is set to hairpin mode (true or false) correctly
# check for each of
# - ch0 explicitly true
# - ch1 explicitly false
# - ch2 unset, which should default to true
#
# we take advantage of the veth name being constructed from the container ID)
#
# should this reliance ever fail and we need to get it from the system, do the following for each:
# CH0_PEER_ID=$(exec_on $HOST1 ch0 cat /sys/class/net/eth0/iflink)
# CH0_PEER=$($SSH $HOST1 ip link show | awk "/^${CH0_PEER_ID}:/"' {print $2}' | sed 's/@.*$//g' )
# CH0_HAIRPIN=$($SSH $HOST1 cat /sys/devices/virtual/net/weave/brif/$CH0_PEER/hairpin_mode)
# assert_raises "[ $CH0_HAIRPIN == 1 ]"
#
assert "$SSH $HOST1 cat /sys/devices/virtual/net/weave/brif/vethwepl${CH0:0:7}/hairpin_mode" "1"
assert "$SSH $HOST1 cat /sys/devices/virtual/net/weave/brif/vethwepl${CH1:0:7}/hairpin_mode" "0"
assert "$SSH $HOST1 cat /sys/devices/virtual/net/weave/brif/vethwepl${CH2:0:7}/hairpin_mode" "1"
# Ensure existing containers can reclaim their IP addresses after CNI has been used -- see #2548
stop_weave_on $HOST1
+1 -1
View File
@@ -284,7 +284,7 @@ function configure() {
local inventory_file=$(mktemp /tmp/ansible_inventory_XXXXX)
echo "[all]" >"$inventory_file"
# shellcheck disable=SC2001
echo "$2" | sed "s/$/:$3/" >>"$inventory_file"
echo "$2" | sed "s/\$/:$3/" >>"$inventory_file"
# Configure the provisioned machines using Ansible, allowing up to 3 retries upon failure (e.g. APT connectivity issues, etc.):
for i in $(seq 3); do
+1 -1
View File
@@ -23,4 +23,4 @@ if [ -n "$CIRCLECI" -o -n "$PARALLEL" ]; then
RUNNER_ARGS="$RUNNER_ARGS -parallel"
fi
HOSTS="$HOSTS" "${DIR}/../tools/runner/runner" $RUNNER_ARGS $TESTS
HOSTS="$HOSTS" "${DIR}/../tools/runner/runner" -timeout=240 $RUNNER_ARGS $TESTS
+5 -2
View File
@@ -1070,17 +1070,20 @@ create_cni_config() {
cat >"$1" <<EOF
{
"name": "weave",
"type": "weave-net"
"type": "weave-net",
"hairpinMode": $2
}
EOF
}
setup_cni() {
# if env var HAIRPIN_MODE is not set, default it to true
HAIRPIN_MODE=${HAIRPIN_MODE:-true}
if install_cni_plugin $CNI_PLUGIN_DIR ; then
upgrade_cni_plugin $CNI_PLUGIN_DIR
fi
if [ -d $HOST_ROOT/etc/cni/net.d -a ! -f $HOST_ROOT/etc/cni/net.d/10-weave.conf ] ; then
create_cni_config $HOST_ROOT/etc/cni/net.d/10-weave.conf
create_cni_config $HOST_ROOT/etc/cni/net.d/10-weave.conf $HAIRPIN_MODE
fi
}