Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e0348233af | ||
|
|
495bea8890 | ||
|
|
3d79b07dba | ||
|
|
27f8f9092f | ||
|
|
7174738d9d | ||
|
|
9be65b466b | ||
|
|
c7a235a54a | ||
|
|
bef50d3730 | ||
|
|
d45579bf82 | ||
|
|
a46d18da0c | ||
|
|
95c020fbe0 | ||
|
|
7c2084b9af | ||
|
|
f78c4dacc5 | ||
|
|
9245b73913 | ||
|
|
6ee961b068 | ||
|
|
1f920513de | ||
|
|
15f21f1899 | ||
|
|
09a204b978 | ||
|
|
77fbb2c12b | ||
|
|
6ad3e69faf | ||
|
|
e2088ef401 | ||
|
|
0f3864968e | ||
|
|
2f235daa1c | ||
|
|
438a5f5fd1 | ||
|
|
b051ef0878 | ||
|
|
48015aa7be | ||
|
|
14730f8572 | ||
|
|
e7a24eaf0a | ||
|
|
15ad210bec | ||
|
|
6bc0e5e71c | ||
|
|
0ca831f50b | ||
|
|
57bca8e955 | ||
|
|
709f820ab6 | ||
|
|
599b99a6c4 | ||
|
|
4e3acfdc02 | ||
|
|
11915948a2 | ||
|
|
bb51a4f36d | ||
|
|
5d0e44bb6f | ||
|
|
6e7a469a62 | ||
|
|
ca0498b860 | ||
|
|
bbfa682083 | ||
|
|
f763c40c10 | ||
|
|
67037b43b0 | ||
|
|
861395011c | ||
|
|
8bdfcd3042 | ||
|
|
83024b946f | ||
|
|
4f48670345 | ||
|
|
4b30d97d4e | ||
|
|
c9e813cfcb | ||
|
|
c97c50b76e | ||
|
|
f919d06e2c | ||
|
|
526538d9d1 | ||
|
|
f43f3fc2e8 | ||
|
|
8b220f6383 | ||
|
|
d44e34584a | ||
|
|
6d2366ca4c | ||
|
|
7c1b615c98 | ||
|
|
390a4099d0 | ||
|
|
01237446eb | ||
|
|
18deb42df1 | ||
|
|
5c508f837e | ||
|
|
e000472af7 | ||
|
|
6d70284c21 |
No files matched your search
+1
-1
@@ -1 +1 @@
|
||||
2.3.0
|
||||
2.6.2
|
||||
@@ -1,3 +1,52 @@
|
||||
## Release 2.6.5
|
||||
|
||||
Fixes a bug that would leak memory every time a fast-datapath connection
|
||||
was stopped. #3808
|
||||
Also avoid a crash when the machine has ipv6 disabled. #3815
|
||||
|
||||
|
||||
## Release 2.6.4
|
||||
|
||||
Improves the iptables rule added in 2.6.3 to block just the Weave Net
|
||||
control port and avoid blocking other uses of 127.0.0.1. #3811
|
||||
|
||||
|
||||
## Release 2.6.3
|
||||
|
||||
This release has a couple of security improvements, and some other fixes.
|
||||
|
||||
* Block non-local traffic to the Weave control port #3805
|
||||
* Tell Linux not to accept router advisory messages #3801
|
||||
* Network Policy Controller: add a metric to show errors while operating #3804
|
||||
* Network Policy Controller: don't treat named port as a fatal error #3790
|
||||
|
||||
## Release 2.6.2
|
||||
|
||||
This release fixes a regression found in 2.6.1 release and removes a possible case
|
||||
of CPU spinning when pcap is used in sleeve mode
|
||||
|
||||
### Bug fixes
|
||||
|
||||
* Weave Net can not be used in fastdp mode and always falls back to sleeve mode #3781, #3783
|
||||
* Restrict timeout value passed to pcap library to a value less than 2^31 microseconds to
|
||||
prevent CPU spinning #3782
|
||||
|
||||
## Release 2.6.1
|
||||
|
||||
This release fixes a bug discovered since the release of Weave Net 2.6.0 and
|
||||
an improvement to support iptables 1.8
|
||||
|
||||
### Bug fixes
|
||||
|
||||
* Weave Net on node restart unable to form connections to peers and connections get stuck in
|
||||
pending state and stops responding to API endpoint #3762 #3763
|
||||
|
||||
### Other improvements
|
||||
|
||||
* Weave Net Kubernetes images by default uses iptables 1.8 with legacy (netfilter) backend with
|
||||
option to choose netfilter as backend #3465, #3747
|
||||
|
||||
|
||||
## Release 2.6.0
|
||||
|
||||
This release reduces CPU and memory usage in larger clusters, by
|
||||
|
||||
@@ -25,7 +25,7 @@ ifeq ($(ARCH),amd64)
|
||||
WEAVEEXEC_DOCKER_ARCH?=x86_64
|
||||
|
||||
# The name of the alpine baseimage to use as the base for weave images
|
||||
ALPINE_BASEIMAGE?=alpine:3.8
|
||||
ALPINE_BASEIMAGE?=alpine:3.10
|
||||
|
||||
# The extension for the made images
|
||||
# Specifying none means for example weaveworks/weave:latest
|
||||
|
||||
@@ -10,14 +10,7 @@ function signal_failure() {
|
||||
trap signal_failure ERR
|
||||
|
||||
function install_terraform() {
|
||||
curl -fsS https://releases.hashicorp.com/terraform/0.8.5/terraform_0.8.5_linux_amd64.zip | gunzip >terraform && chmod +x terraform && sudo mv terraform /usr/bin
|
||||
}
|
||||
|
||||
function install_ansible() {
|
||||
sudo apt-get update || true
|
||||
sudo apt-get install -qq -y python-pip python-dev libffi-dev libssl-dev \
|
||||
&& pip install --user -U setuptools cffi \
|
||||
&& pip install --user ansible
|
||||
curl -fsS https://releases.hashicorp.com/terraform/0.11.14/terraform_0.11.14_linux_amd64.zip | gunzip >terraform && chmod +x terraform && sudo mv terraform /usr/bin
|
||||
}
|
||||
|
||||
[ -n "$SECRET_KEY" ] || {
|
||||
@@ -28,7 +21,6 @@ function install_ansible() {
|
||||
source "$SRCDIR/bin/circle-env"
|
||||
|
||||
install_terraform
|
||||
install_ansible
|
||||
|
||||
# Only attempt to create GCP image in first container, wait for it to be created otherwise:
|
||||
[ "$CIRCLE_NODE_INDEX" != "0" ] && export CREATE_IMAGE=0
|
||||
|
||||
+15
@@ -93,6 +93,7 @@ build() {
|
||||
sed -i.bak -e "s/:latest/:$VERSION/" -e "/imagePullPolicy: Always/d" ./prog/weave-kube/weave-daemonset-k8s-1.7.yaml
|
||||
sed -i.bak -e "s/:latest/:$VERSION/" -e "/imagePullPolicy: Always/d" ./prog/weave-kube/weave-daemonset-k8s-1.8.yaml
|
||||
sed -i.bak -e "s/:latest/:$VERSION/" -e "/imagePullPolicy: Always/d" ./prog/weave-kube/weave-daemonset-k8s-1.9.yaml
|
||||
sed -i.bak -e "s/:latest/:$VERSION/" -e "/imagePullPolicy: Always/d" ./prog/weave-kube/weave-daemonset-k8s-1.11.yaml
|
||||
make SUDO=$SUDO WEAVE_VERSION=$VERSION DOCKERHUB_USER=$DOCKERHUB_USER
|
||||
|
||||
if make tests; then
|
||||
@@ -189,6 +190,13 @@ draft() {
|
||||
--name "weave-daemonset-k8s-1.9.yaml" \
|
||||
--file "./prog/weave-kube/weave-daemonset-k8s-1.9.yaml"
|
||||
|
||||
github-release upload \
|
||||
--user $GITHUB_USER \
|
||||
--repo weave \
|
||||
--tag $LATEST_TAG \
|
||||
--name "weave-daemonset-k8s-1.11.yaml" \
|
||||
--file "./prog/weave-kube/weave-daemonset-k8s-1.11.yaml"
|
||||
|
||||
echo "** Draft $TYPE $RELEASE_NAME $VERSION created at"
|
||||
echo -e "\thttps://github.com/$GITHUB_USER/weave/releases/$LATEST_TAG"
|
||||
}
|
||||
@@ -304,6 +312,13 @@ publish() {
|
||||
--name "weave-daemonset-k8s-1.9.yaml" \
|
||||
--file "./prog/weave-kube/weave-daemonset-k8s-1.9.yaml"
|
||||
|
||||
github-release upload \
|
||||
--user $GITHUB_USER \
|
||||
--repo weave \
|
||||
--tag latest_release \
|
||||
--name "weave-daemonset-k8s-1.11.yaml" \
|
||||
--file "./prog/weave-kube/weave-daemonset-k8s-1.11.yaml"
|
||||
|
||||
echo "** Release $RELEASE_NAME $VERSION published at"
|
||||
echo -e "\thttps://github.com/$GITHUB_USER/weave/releases/$LATEST_TAG"
|
||||
echo -e "\thttps://github.com/$GITHUB_USER/weave/releases/latest_release"
|
||||
|
||||
@@ -54,6 +54,12 @@ func SetLogLevel(levelname string) {
|
||||
Log.Level = level
|
||||
}
|
||||
|
||||
func CheckError(e error) {
|
||||
if e != nil {
|
||||
Log.Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
func CheckFatal(e error) {
|
||||
if e != nil {
|
||||
Log.Fatal(e)
|
||||
|
||||
@@ -41,3 +41,11 @@ func sysctl(procPath, variable, value string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func sysctlIfExists(procPath, variable, value string) error {
|
||||
err := sysctl(procPath, variable, value)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
err = nil // ignore 'not found' errors
|
||||
}
|
||||
return err
|
||||
}
|
||||
+28
-11
@@ -63,10 +63,10 @@ const (
|
||||
)
|
||||
|
||||
type Bridge interface {
|
||||
init(config *BridgeConfig) error // create and initialise bridge device(s)
|
||||
attach(veth *netlink.Veth) error // attach veth to bridge
|
||||
IsFastdp() bool // does this bridge use fastdp?
|
||||
String() string // human-readable type string
|
||||
init(procPath string, config *BridgeConfig) error // create and initialise bridge device(s)
|
||||
attach(veth *netlink.Veth) error // attach veth to bridge
|
||||
IsFastdp() bool // does this bridge use fastdp?
|
||||
String() string // human-readable type string
|
||||
}
|
||||
|
||||
// Used to indicate a fallback to the Bridge type
|
||||
@@ -221,6 +221,7 @@ type BridgeConfig struct {
|
||||
MTU int
|
||||
Mac string
|
||||
Port int
|
||||
ControlPort string
|
||||
NoMasqLocal bool
|
||||
}
|
||||
|
||||
@@ -250,7 +251,7 @@ func EnsureBridge(procPath string, config *BridgeConfig, log *logrus.Logger, ips
|
||||
}
|
||||
|
||||
for {
|
||||
if err := bridgeType.init(config); err != nil {
|
||||
if err := bridgeType.init(procPath, config); err != nil {
|
||||
if errors.Cause(err) == errBridgeNotSupported {
|
||||
log.Warnf("Skipping bridge creation of %q due to: %s", bridgeType, err)
|
||||
bridgeType = bridgeImpl{}
|
||||
@@ -279,6 +280,10 @@ func EnsureBridge(procPath string, config *BridgeConfig, log *logrus.Logger, ips
|
||||
return bridgeType, errors.Wrap(err, "setting proxy_arp")
|
||||
}
|
||||
}
|
||||
// No ipv6 router advertisments please
|
||||
if err := sysctlIfExists(procPath, "net/ipv6/conf/"+config.WeaveBridgeName+"/accept_ra", "0"); err != nil {
|
||||
return bridgeType, errors.Wrap(err, "setting accept_ra to 0")
|
||||
}
|
||||
|
||||
if err := linkSetUpByName(config.WeaveBridgeName); err != nil {
|
||||
return bridgeType, err
|
||||
@@ -345,11 +350,11 @@ func (b bridgeImpl) initPrep(config *BridgeConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b bridgeImpl) init(config *BridgeConfig) error {
|
||||
func (b bridgeImpl) init(procPath string, config *BridgeConfig) error {
|
||||
if err := b.initPrep(config); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := CreateAndAttachVeth(BridgeIfName, PcapIfName, config.WeaveBridgeName, config.MTU, true, false, func(veth netlink.Link) error {
|
||||
if _, err := CreateAndAttachVeth(procPath, BridgeIfName, PcapIfName, config.WeaveBridgeName, config.MTU, true, false, func(veth netlink.Link) error {
|
||||
return netlink.LinkSetUp(veth)
|
||||
}); err != nil {
|
||||
return errors.Wrap(err, "creating pcap veth pair")
|
||||
@@ -361,7 +366,7 @@ func (b bridgeImpl) init(config *BridgeConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f fastdpImpl) init(config *BridgeConfig) error {
|
||||
func (f fastdpImpl) init(procPath string, config *BridgeConfig) error {
|
||||
odpSupported, err := odp.CreateDatapath(f.datapathName)
|
||||
if !odpSupported {
|
||||
msg := ""
|
||||
@@ -392,14 +397,14 @@ func (f fastdpImpl) init(config *BridgeConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (bf bridgedFastdpImpl) init(config *BridgeConfig) error {
|
||||
if err := bf.fastdpImpl.init(config); err != nil {
|
||||
func (bf bridgedFastdpImpl) init(procPath string, config *BridgeConfig) error {
|
||||
if err := bf.fastdpImpl.init(procPath, config); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := bf.bridgeImpl.initPrep(config); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := CreateAndAttachVeth(BridgeIfName, DatapathIfName, config.WeaveBridgeName, config.MTU, true, false, func(veth netlink.Link) error {
|
||||
if _, err := CreateAndAttachVeth(procPath, BridgeIfName, DatapathIfName, config.WeaveBridgeName, config.MTU, true, false, func(veth netlink.Link) error {
|
||||
if err := netlink.LinkSetUp(veth); err != nil {
|
||||
return errors.Wrapf(err, "setting link up on %q", veth.Attrs().Name)
|
||||
}
|
||||
@@ -465,6 +470,18 @@ func configureIPTables(config *BridgeConfig, ips ipset.Interface) error {
|
||||
}
|
||||
}
|
||||
|
||||
if config.ControlPort != "" {
|
||||
if err = ipt.AppendUnique("filter", "INPUT", "-p", "tcp", "--dst", "127.0.0.1", "--dport", config.ControlPort,
|
||||
"-m", "addrtype", "!", "--src-type", "LOCAL",
|
||||
"-m", "conntrack", "!", "--ctstate", "RELATED,ESTABLISHED",
|
||||
"-m", "comment", "--comment", "Block non-local access to Weave Net control port",
|
||||
"-j", "DROP"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// Remove the rule from Weave Net 2.6.3 which dropped too much.
|
||||
_ = ipt.Delete("filter", "INPUT", "-p", "tcp", "--dst", "127.0.0.1", "-m", "addrtype", "!", "--src-type", "LOCAL", "-m", "conntrack", "!", "--ctstate", "RELATED,ESTABLISHED", "-j", "DROP")
|
||||
|
||||
if config.NPC {
|
||||
// Steer traffic via the NPC.
|
||||
|
||||
|
||||
+9
-13
@@ -85,7 +85,7 @@ func New(log *logrus.Logger) (*IPSec, error) {
|
||||
|
||||
// InitSALocal initializes inbound ipsec from remotePeer and triggers
|
||||
// the initialization on remotePeer.
|
||||
func (ipsec *IPSec) InitSALocal(localPeer, remotePeer mesh.PeerName, connUID uint64, localIP, remoteIP net.IP, udpPort int, sessionKey *[32]byte, initRemote func([]byte) error) error {
|
||||
func (ipsec *IPSec) InitSALocal(localPeer, remotePeer mesh.PeerName, connUID uint64, localIP, remoteIP net.IP, udpPort int, sessionKey *[32]byte) ([]byte, error) {
|
||||
// ID of inbound SPI
|
||||
spiID := getSPIId(remotePeer, localPeer, connUID)
|
||||
|
||||
@@ -95,17 +95,17 @@ func (ipsec *IPSec) InitSALocal(localPeer, remotePeer mesh.PeerName, connUID uin
|
||||
// Derive SA key
|
||||
nonce, err := genNonce()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "generate nonce")
|
||||
return nil, errors.Wrap(err, "generate nonce")
|
||||
}
|
||||
key, err := deriveKey(sessionKey[:], nonce, localPeer)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "derive key")
|
||||
return nil, errors.Wrap(err, "derive key")
|
||||
}
|
||||
|
||||
// Allocate SA
|
||||
sa, err := netlink.XfrmStateAllocSpi(xfrmAllocSpiState(remoteIP, localIP))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("ip xfrm state allocspi (in, %s, %s)", remoteIP, localIP))
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("ip xfrm state allocspi (in, %s, %s)", remoteIP, localIP))
|
||||
}
|
||||
|
||||
// Use SPI generated by the kernel. The kernel ensures {dstIP, spi} to
|
||||
@@ -117,28 +117,24 @@ func (ipsec *IPSec) InitSALocal(localPeer, remotePeer mesh.PeerName, connUID uin
|
||||
// Create SA
|
||||
if sa, err := xfrmState(remoteIP, localIP, spi, false, key); err == nil {
|
||||
if err := netlink.XfrmStateUpdate(sa); err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("xfrm state update (in, %s, %s, 0x%x)", sa.Src, sa.Dst, sa.Spi))
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("xfrm state update (in, %s, %s, 0x%x)", sa.Src, sa.Dst, sa.Spi))
|
||||
}
|
||||
} else {
|
||||
return errors.Wrap(err, "new xfrm state (in)")
|
||||
return nil, errors.Wrap(err, "new xfrm state (in)")
|
||||
}
|
||||
|
||||
// Install iptables rules
|
||||
if err := ipsec.installDropNonEncrypted(localIP, remoteIP, udpPort, spi); err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("install protecting rules (%s, %s, %d, 0x%x)", localIP, remoteIP, udpPort, spi))
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("install protecting rules (%s, %s, %d, 0x%x)", localIP, remoteIP, udpPort, spi))
|
||||
}
|
||||
|
||||
si := spiInfo{spi: spi, isDirOut: false}
|
||||
ipsec.spiInfo[spiID] = si
|
||||
ipsec.spis[spi] = &si
|
||||
|
||||
// Trigger the initialization on the remote peer
|
||||
// Generate the message to trigger initialization on the remote peer
|
||||
msg := &msgInitSARemote{nonce, spi}
|
||||
if err := initRemote(msg.serialize()); err != nil {
|
||||
return errors.Wrap(err, "send InitSARemote")
|
||||
}
|
||||
|
||||
return nil
|
||||
return msg.serialize(), nil
|
||||
}
|
||||
|
||||
// InitSARemote initializes outbound ipsec to remotePeer.
|
||||
|
||||
+3
-3
@@ -55,9 +55,9 @@ func WithNetNSByPath(path string, work func() error) error {
|
||||
}
|
||||
|
||||
func NSPathByPid(pid int) string {
|
||||
return NSPathByPidWithRoot("/", pid)
|
||||
return NSPathByPidWithProc("/proc", pid)
|
||||
}
|
||||
|
||||
func NSPathByPidWithRoot(root string, pid int) string {
|
||||
return filepath.Join(root, fmt.Sprintf("/proc/%d/ns/net", pid))
|
||||
func NSPathByPidWithProc(procPath string, pid int) string {
|
||||
return filepath.Join(procPath, fmt.Sprint(pid), "/ns/net")
|
||||
}
|
||||
+17
-8
@@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
// create and attach a veth to the Weave bridge
|
||||
func CreateAndAttachVeth(name, peerName, bridgeName string, mtu int, keepTXOn bool, errIfLinkExist bool, init func(peer netlink.Link) error) (*netlink.Veth, error) {
|
||||
func CreateAndAttachVeth(procPath, name, peerName, bridgeName string, mtu int, keepTXOn bool, errIfLinkExist bool, init func(peer netlink.Link) error) (*netlink.Veth, error) {
|
||||
bridge, err := netlink.LinkByName(bridgeName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(`bridge "%s" not present; did you launch weave?`, bridgeName)
|
||||
@@ -49,6 +49,13 @@ func CreateAndAttachVeth(name, peerName, bridgeName string, mtu int, keepTXOn bo
|
||||
if err := bridgeType.attach(veth); err != nil {
|
||||
return cleanup("attaching veth %q to %q: %s", name, bridgeName, err)
|
||||
}
|
||||
// No ipv6 router advertisments please
|
||||
if err := sysctlIfExists(procPath, "net/ipv6/conf/"+name+"/accept_ra", "0"); err != nil {
|
||||
return cleanup("setting accept_ra to 0: %s", err)
|
||||
}
|
||||
if err := sysctlIfExists(procPath, "net/ipv6/conf/"+peerName+"/accept_ra", "0"); err != nil {
|
||||
return cleanup("setting accept_ra to 0: %s", err)
|
||||
}
|
||||
if !bridgeType.IsFastdp() && !keepTXOn {
|
||||
if err := EthtoolTXOff(veth.PeerName); err != nil {
|
||||
return cleanup(`unable to set tx off on %q: %s`, peerName, err)
|
||||
@@ -112,6 +119,9 @@ func interfaceExistsInNamespace(netNSPath string, ifName string) bool {
|
||||
}
|
||||
|
||||
func AttachContainer(netNSPath, id, ifName, bridgeName string, mtu int, withMulticastRoute bool, cidrs []*net.IPNet, keepTXOn bool, hairpinMode bool) error {
|
||||
// AttachContainer expects to be called in host pid namespace
|
||||
const procPath = "/proc"
|
||||
|
||||
ns, err := netns.GetFromPath(netNSPath)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -124,12 +134,12 @@ func AttachContainer(netNSPath, id, ifName, bridgeName string, mtu int, withMult
|
||||
id = id[:maxIDLen] // trim passed ID if too long
|
||||
}
|
||||
name, peerName := vethPrefix+"pl"+id, vethPrefix+"pg"+id
|
||||
veth, err := CreateAndAttachVeth(name, peerName, bridgeName, mtu, keepTXOn, true, func(veth netlink.Link) error {
|
||||
veth, err := CreateAndAttachVeth(procPath, name, peerName, bridgeName, mtu, keepTXOn, true, func(veth netlink.Link) error {
|
||||
if err := netlink.LinkSetNsFd(veth, int(ns)); err != nil {
|
||||
return fmt.Errorf("failed to move veth to container netns: %s", err)
|
||||
}
|
||||
if err := WithNetNS(ns, func() error {
|
||||
return setupIface(peerName, ifName)
|
||||
return setupIface(procPath, peerName, ifName)
|
||||
}); err != nil {
|
||||
return fmt.Errorf("error setting up interface: %s", err)
|
||||
}
|
||||
@@ -206,7 +216,7 @@ func setupIfaceAddrs(veth netlink.Link, withMulticastRoute bool, cidrs []*net.IP
|
||||
}
|
||||
|
||||
// setupIface expects to be called in the container's netns
|
||||
func setupIface(ifaceName, newIfName string) error {
|
||||
func setupIface(procPath, ifaceName, newIfName string) error {
|
||||
ipt, err := iptables.New()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -219,15 +229,14 @@ func setupIface(ifaceName, newIfName string) error {
|
||||
if err := netlink.LinkSetName(link, newIfName); err != nil {
|
||||
return err
|
||||
}
|
||||
// This is only called by AttachContainer which is only called in host pid namespace
|
||||
if err := configureARPCache("/proc", newIfName); err != nil {
|
||||
if err := configureARPCache(procPath, newIfName); err != nil {
|
||||
return err
|
||||
}
|
||||
return ipt.Append("filter", "INPUT", "-i", newIfName, "-d", "224.0.0.0/4", "-j", "DROP")
|
||||
}
|
||||
|
||||
// configureARP is a helper for the Docker plugin which doesn't set the addresses itself
|
||||
func ConfigureARP(prefix, rootPath string) error {
|
||||
func ConfigureARP(prefix, procPath string) error {
|
||||
links, err := netlink.LinkList()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -235,7 +244,7 @@ func ConfigureARP(prefix, rootPath string) error {
|
||||
for _, link := range links {
|
||||
ifName := link.Attrs().Name
|
||||
if strings.HasPrefix(ifName, prefix) {
|
||||
configureARPCache(rootPath+"/proc", ifName)
|
||||
configureARPCache(procPath, ifName)
|
||||
if addrs, err := netlink.AddrList(link, netlink.FAMILY_V4); err == nil {
|
||||
for _, addr := range addrs {
|
||||
arping.GratuitousArpOverIfaceByName(addr.IPNet.IP, ifName)
|
||||
|
||||
@@ -22,6 +22,12 @@ var (
|
||||
},
|
||||
[]string{"protocol", "dport"},
|
||||
)
|
||||
PolicyEnforcementErrors = prometheus.NewCounter(
|
||||
prometheus.CounterOpts{
|
||||
Name: "weavenpc_policy_enforcement_errors",
|
||||
Help: "Errors occured in enforcing the network policies.",
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
func gatherMetrics() {
|
||||
@@ -95,6 +101,9 @@ func Start(addr string) error {
|
||||
if err := prometheus.Register(blockedConnections); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := prometheus.Register(PolicyEnforcementErrors); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
http.Handle("/metrics", promhttp.Handler())
|
||||
|
||||
|
||||
@@ -39,9 +39,10 @@ type driver struct {
|
||||
// used only by plugin-v2
|
||||
forceMulticast bool
|
||||
networks map[string]network
|
||||
procPath string
|
||||
}
|
||||
|
||||
func New(client *docker.Client, weave *weaveapi.Client, name, scope string, dns, isPluginV2, forceMulticast bool) (skel.Driver, error) {
|
||||
func New(client *docker.Client, weave *weaveapi.Client, name, scope string, dns, isPluginV2, forceMulticast bool, procPath string) (skel.Driver, error) {
|
||||
driver := &driver{
|
||||
name: name,
|
||||
scope: scope,
|
||||
@@ -51,6 +52,7 @@ func New(client *docker.Client, weave *weaveapi.Client, name, scope string, dns,
|
||||
// make sure that it's used only by plugin-v2
|
||||
forceMulticast: isPluginV2 && forceMulticast,
|
||||
networks: make(map[string]network),
|
||||
procPath: procPath,
|
||||
}
|
||||
|
||||
// Do not start watcher in the case of plugin v2, which prevents us from
|
||||
@@ -134,7 +136,7 @@ func (driver *driver) CreateEndpoint(create *api.CreateEndpointRequest) (*api.Cr
|
||||
|
||||
// create veths. note we assume endpoint IDs are unique in the first 9 chars
|
||||
name, peerName := vethPair(create.EndpointID)
|
||||
if _, err := weavenet.CreateAndAttachVeth(name, peerName, weavenet.WeaveBridgeName, 0, false, true, nil); err != nil {
|
||||
if _, err := weavenet.CreateAndAttachVeth(driver.procPath, name, peerName, weavenet.WeaveBridgeName, 0, false, true, nil); err != nil {
|
||||
return nil, driver.error("JoinEndpoint", "%s", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -43,14 +43,9 @@ func (w *watcher) ContainerStarted(id string) {
|
||||
w.driver.warn("ContainerStarted", "unable to register %s with weaveDNS: %s", id, err)
|
||||
}
|
||||
}
|
||||
rootDir := "/"
|
||||
if w.driver.isPluginV2 {
|
||||
// We bind mount host's /proc to /host/proc for plugin-v2
|
||||
rootDir = "/host"
|
||||
}
|
||||
netNSPath := weavenet.NSPathByPidWithRoot(rootDir, info.State.Pid)
|
||||
netNSPath := weavenet.NSPathByPidWithProc(w.driver.procPath, info.State.Pid)
|
||||
if err := weavenet.WithNetNSByPath(netNSPath, func() error {
|
||||
return weavenet.ConfigureARP(weavenet.VethName, rootDir)
|
||||
return weavenet.ConfigureARP(weavenet.VethName, w.driver.procPath)
|
||||
}); err != nil {
|
||||
w.driver.warn("ContainerStarted", "unable to configure interfaces: %s", err)
|
||||
}
|
||||
|
||||
+5
-4
@@ -32,6 +32,7 @@ type Config struct {
|
||||
EnableV2Multicast bool
|
||||
DNS bool
|
||||
DefaultSubnet string
|
||||
ProcPath string // path to reach host /proc filesystem
|
||||
}
|
||||
|
||||
type Plugin struct {
|
||||
@@ -62,7 +63,7 @@ func (plugin *Plugin) run(dockerClient *docker.Client, weave *weaveapi.Client, r
|
||||
endChan := make(chan error, 1)
|
||||
|
||||
if plugin.Socket != "" {
|
||||
globalListener, err := listenAndServe(dockerClient, weave, plugin.Socket, endChan, "global", false, plugin.DNS, plugin.EnableV2, plugin.EnableV2Multicast)
|
||||
globalListener, err := listenAndServe(dockerClient, weave, plugin.Socket, endChan, "global", false, plugin.DNS, plugin.EnableV2, plugin.EnableV2Multicast, plugin.ProcPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -70,7 +71,7 @@ func (plugin *Plugin) run(dockerClient *docker.Client, weave *weaveapi.Client, r
|
||||
defer globalListener.Close()
|
||||
}
|
||||
if plugin.MeshSocket != "" {
|
||||
meshListener, err := listenAndServe(dockerClient, weave, plugin.MeshSocket, endChan, "local", true, plugin.DNS, plugin.EnableV2, plugin.EnableV2Multicast)
|
||||
meshListener, err := listenAndServe(dockerClient, weave, plugin.MeshSocket, endChan, "local", true, plugin.DNS, plugin.EnableV2, plugin.EnableV2Multicast, plugin.ProcPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -87,7 +88,7 @@ func (plugin *Plugin) run(dockerClient *docker.Client, weave *weaveapi.Client, r
|
||||
return <-endChan
|
||||
}
|
||||
|
||||
func listenAndServe(dockerClient *docker.Client, weave *weaveapi.Client, address string, endChan chan<- error, scope string, withIpam, dns bool, isPluginV2, forceMulticast bool) (net.Listener, error) {
|
||||
func listenAndServe(dockerClient *docker.Client, weave *weaveapi.Client, address string, endChan chan<- error, scope string, withIpam, dns bool, isPluginV2, forceMulticast bool, procPath string) (net.Listener, error) {
|
||||
var name string
|
||||
if isPluginV2 {
|
||||
name = pluginV2Name
|
||||
@@ -95,7 +96,7 @@ func listenAndServe(dockerClient *docker.Client, weave *weaveapi.Client, address
|
||||
name = pluginNameFromAddress(address)
|
||||
}
|
||||
|
||||
d, err := netplugin.New(dockerClient, weave, name, scope, dns, isPluginV2, forceMulticast)
|
||||
d, err := netplugin.New(dockerClient, weave, name, scope, dns, isPluginV2, forceMulticast, procPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -6,6 +6,34 @@ modprobe_safe() {
|
||||
modprobe $1 || echo "Ignore the error if \"$1\" is built-in in the kernel" >&2
|
||||
}
|
||||
|
||||
# Setup iptables backend to be legacy or nftable
|
||||
setup_iptables_backend() {
|
||||
if [ -n "${IPTABLES_BACKEND}" ]; then
|
||||
mode=$IPTABLES_BACKEND
|
||||
else
|
||||
# auto-detect if iptables backend mode to use if not specified explicitly
|
||||
num_legacy_lines=$( (iptables-legacy-save || true) 2>/dev/null | grep '^-' | wc -l)
|
||||
num_nft_lines=$( (iptables-nft-save || true) 2>/dev/null | grep '^-' | wc -l)
|
||||
if [ "${num_legacy_lines}" -ge 10 ]; then
|
||||
mode="legacy"
|
||||
else
|
||||
if [ "${num_legacy_lines}" -ge "${num_nft_lines}" ]; then
|
||||
mode="legacy"
|
||||
else
|
||||
mode="nft"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ $mode = "nft" ]; then
|
||||
rm /sbin/iptables
|
||||
rm /sbin/iptables-save
|
||||
rm /sbin/iptables-restore
|
||||
ln -s /sbin/iptables-nft /sbin/iptables
|
||||
ln -s /sbin/iptables-nft-save /sbin/iptables-save
|
||||
ln -s /sbin/iptables-nft-restore /sbin/iptables-restore
|
||||
fi
|
||||
}
|
||||
|
||||
# Check whether xt_set actually exists
|
||||
xt_set_exists() {
|
||||
# Clean everything up in advance, in case there's leftovers
|
||||
@@ -24,6 +52,8 @@ xt_set_exists() {
|
||||
[ -z "$NOT_EXIST" ] || (echo "\"xt_set\" does not exist" >&2 && return 1)
|
||||
}
|
||||
|
||||
setup_iptables_backend
|
||||
|
||||
# Default if not supplied - same as weave net default
|
||||
IPALLOC_RANGE=${IPALLOC_RANGE:-10.32.0.0/12}
|
||||
HTTP_ADDR=${WEAVE_HTTP_ADDR:-127.0.0.1:6784}
|
||||
|
||||
@@ -8,7 +8,7 @@ items:
|
||||
labels:
|
||||
name: weave-net
|
||||
namespace: kube-system
|
||||
- apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
- apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: weave-net
|
||||
@@ -48,7 +48,7 @@ items:
|
||||
verbs:
|
||||
- patch
|
||||
- update
|
||||
- apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
- apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: weave-net
|
||||
@@ -62,7 +62,7 @@ items:
|
||||
- kind: ServiceAccount
|
||||
name: weave-net
|
||||
namespace: kube-system
|
||||
- apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
- apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: weave-net
|
||||
@@ -85,7 +85,7 @@ items:
|
||||
- configmaps
|
||||
verbs:
|
||||
- create
|
||||
- apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
- apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: weave-net
|
||||
@@ -137,7 +137,7 @@ items:
|
||||
port: 6784
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
cpu: 50m
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
@@ -168,7 +168,7 @@ items:
|
||||
#npc-args
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
cpu: 50m
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
@@ -176,6 +176,7 @@ items:
|
||||
mountPath: /run/xtables.lock
|
||||
readOnly: false
|
||||
hostNetwork: true
|
||||
dnsPolicy: ClusterFirstWithHostNet
|
||||
hostPID: true
|
||||
restartPolicy: Always
|
||||
securityContext:
|
||||
|
||||
@@ -117,7 +117,7 @@ items:
|
||||
port: 6784
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
cpu: 50m
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
@@ -144,7 +144,7 @@ items:
|
||||
imagePullPolicy: Always
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
cpu: 50m
|
||||
securityContext:
|
||||
privileged: true
|
||||
hostNetwork: true
|
||||
|
||||
@@ -126,7 +126,7 @@ items:
|
||||
port: 6784
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
cpu: 50m
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
@@ -156,7 +156,7 @@ items:
|
||||
imagePullPolicy: Always
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
cpu: 50m
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
|
||||
@@ -8,7 +8,7 @@ items:
|
||||
labels:
|
||||
name: weave-net
|
||||
namespace: kube-system
|
||||
- apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
- apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: weave-net
|
||||
@@ -48,7 +48,7 @@ items:
|
||||
verbs:
|
||||
- patch
|
||||
- update
|
||||
- apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
- apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: weave-net
|
||||
@@ -62,7 +62,7 @@ items:
|
||||
- kind: ServiceAccount
|
||||
name: weave-net
|
||||
namespace: kube-system
|
||||
- apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
- apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: weave-net
|
||||
@@ -85,7 +85,7 @@ items:
|
||||
- configmaps
|
||||
verbs:
|
||||
- create
|
||||
- apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
- apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: weave-net
|
||||
@@ -134,7 +134,7 @@ items:
|
||||
port: 6784
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
cpu: 50m
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
@@ -165,7 +165,7 @@ items:
|
||||
#npc-args
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
cpu: 50m
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
|
||||
@@ -8,7 +8,7 @@ items:
|
||||
labels:
|
||||
name: weave-net
|
||||
namespace: kube-system
|
||||
- apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
- apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: weave-net
|
||||
@@ -48,7 +48,7 @@ items:
|
||||
verbs:
|
||||
- patch
|
||||
- update
|
||||
- apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
- apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: weave-net
|
||||
@@ -62,7 +62,7 @@ items:
|
||||
- kind: ServiceAccount
|
||||
name: weave-net
|
||||
namespace: kube-system
|
||||
- apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
- apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: weave-net
|
||||
@@ -85,7 +85,7 @@ items:
|
||||
- configmaps
|
||||
verbs:
|
||||
- create
|
||||
- apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
- apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: weave-net
|
||||
@@ -137,7 +137,7 @@ items:
|
||||
port: 6784
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
cpu: 50m
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
@@ -168,7 +168,7 @@ items:
|
||||
#npc-args
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
cpu: 50m
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
|
||||
@@ -2,5 +2,35 @@
|
||||
|
||||
set -e
|
||||
|
||||
# Setup iptables backend to be legacy or nftable
|
||||
setup_iptables_backend() {
|
||||
if [ -n "${IPTABLES_BACKEND}" ]; then
|
||||
mode=$IPTABLES_BACKEND
|
||||
else
|
||||
# auto-detect if iptables backend mode to use if not specified explicitly
|
||||
num_legacy_lines=$( (iptables-legacy-save || true) 2>/dev/null | grep '^-' | wc -l)
|
||||
num_nft_lines=$( (iptables-nft-save || true) 2>/dev/null | grep '^-' | wc -l)
|
||||
if [ "${num_legacy_lines}" -ge 10 ]; then
|
||||
mode="legacy"
|
||||
else
|
||||
if [ "${num_legacy_lines}" -ge "${num_nft_lines}" ]; then
|
||||
mode="legacy"
|
||||
else
|
||||
mode="nft"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ $mode = "nft" ]; then
|
||||
rm /sbin/iptables
|
||||
rm /sbin/iptables-save
|
||||
rm /sbin/iptables-restore
|
||||
ln -s /sbin/iptables-nft /sbin/iptables
|
||||
ln -s /sbin/iptables-nft-save /sbin/iptables-save
|
||||
ln -s /sbin/iptables-nft-restore /sbin/iptables-restore
|
||||
fi
|
||||
}
|
||||
|
||||
setup_iptables_backend
|
||||
|
||||
# Start weave-npc with any flags specified in $EXTRA_ARGS as well as any flags passed to this container (for backwards compatibility)
|
||||
exec /usr/bin/weave-npc $EXTRA_ARGS $@
|
||||
+15
-8
@@ -34,7 +34,14 @@ var (
|
||||
bridgePortName string
|
||||
)
|
||||
|
||||
func handleError(err error) { common.CheckFatal(err) }
|
||||
func handleError(err error) {
|
||||
if err != nil {
|
||||
metrics.PolicyEnforcementErrors.Inc()
|
||||
common.Log.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func handleFatal(err error) { common.CheckFatal(err) }
|
||||
|
||||
func makeController(getter cache.Getter, resource string,
|
||||
objType runtime.Object, handlers cache.ResourceEventHandlerFuncs) cache.Controller {
|
||||
@@ -240,19 +247,19 @@ func root(cmd *cobra.Command, args []string) {
|
||||
}
|
||||
|
||||
config, err := rest.InClusterConfig()
|
||||
handleError(err)
|
||||
handleFatal(err)
|
||||
|
||||
client, err := kubernetes.NewForConfig(config)
|
||||
handleError(err)
|
||||
handleFatal(err)
|
||||
|
||||
ipt, err := iptables.New()
|
||||
handleError(err)
|
||||
handleFatal(err)
|
||||
|
||||
ips := ipset.New(common.LogLogger(), maxList)
|
||||
|
||||
handleError(resetIPTables(ipt))
|
||||
handleError(resetIPSets(ips))
|
||||
handleError(createBaseRules(ipt, ips))
|
||||
handleFatal(resetIPTables(ipt))
|
||||
handleFatal(resetIPSets(ips))
|
||||
handleFatal(createBaseRules(ipt, ips))
|
||||
|
||||
npc := npc.New(nodeName, ipt, ips, client)
|
||||
|
||||
@@ -339,5 +346,5 @@ func main() {
|
||||
rootCmd.PersistentFlags().IntVar(&maxList, "max-list-size", 1024, "maximum size of ipset list (for namespaces)")
|
||||
rootCmd.PersistentFlags().StringVar(&bridgePortName, "bridge-port-name", "vethwe-bridge", "name of the brige port on which packets are received and sent")
|
||||
|
||||
handleError(rootCmd.Execute())
|
||||
handleFatal(rootCmd.Execute())
|
||||
}
|
||||
@@ -307,6 +307,11 @@ func main() {
|
||||
|
||||
bridgeConfig.Mac = name.String()
|
||||
bridgeConfig.Port = config.Port
|
||||
if httpAddr != "" {
|
||||
if _, port, err := net.SplitHostPort(httpAddr); err == nil {
|
||||
bridgeConfig.ControlPort = port
|
||||
}
|
||||
}
|
||||
ips := ipset.New(common.LogLogger(), 0)
|
||||
bridgeType, err := weavenet.EnsureBridge(procPath, &bridgeConfig, Log, ips)
|
||||
checkFatal(err)
|
||||
@@ -453,6 +458,7 @@ func main() {
|
||||
|
||||
pluginConfig.DNS = !noDNS
|
||||
pluginConfig.DefaultSubnet = defaultSubnet.String()
|
||||
pluginConfig.ProcPath = procPath
|
||||
plugin := plugin.NewPlugin(pluginConfig)
|
||||
|
||||
// The weave script always waits for a status call to succeed,
|
||||
|
||||
+16
-6
@@ -482,7 +482,7 @@ func (fastdp *FastDatapath) getVxlanVportID(udpPort int) (odp.VportID, error) {
|
||||
// The netdev interface is down, so most likely bringing it up
|
||||
// has failed due to the UDP port being in use.
|
||||
if err := fastdp.dp.DeleteVport(vxlanVportID); err != nil {
|
||||
log.Warning("Unable to remove vxlan vport %d: %s", vxlanVportID, err)
|
||||
log.Warningf("Unable to remove vxlan vport %d: %s", vxlanVportID, err)
|
||||
}
|
||||
return 0, odp.NetlinkError(syscall.EADDRINUSE)
|
||||
}
|
||||
@@ -654,27 +654,26 @@ func (fwd *fastDatapathForwarder) logPrefix() string {
|
||||
|
||||
func (fwd *fastDatapathForwarder) Confirm() {
|
||||
fwd.lock.Lock()
|
||||
defer fwd.lock.Unlock()
|
||||
|
||||
if fwd.confirmed {
|
||||
log.Fatal(fwd.logPrefix(), "already confirmed")
|
||||
}
|
||||
|
||||
var controlMsg []byte
|
||||
if fwd.fastdp.ipsec != nil && fwd.sessionKey != nil {
|
||||
fwd.isEncrypted = true
|
||||
log.Info("Setting up IPsec between ", fwd.fastdp.localPeer, " and ", fwd.remotePeer)
|
||||
err := fwd.fastdp.ipsec.InitSALocal(
|
||||
var err error
|
||||
controlMsg, err = fwd.fastdp.ipsec.InitSALocal(
|
||||
fwd.fastdp.localPeer.Name, fwd.remotePeer.Name, fwd.connUID,
|
||||
net.IP(fwd.localIP[:]), fwd.remoteAddr.IP,
|
||||
fwd.remoteAddr.Port,
|
||||
fwd.sessionKey,
|
||||
func(msg []byte) error {
|
||||
return fwd.sendControlMsg(FastDatapathCryptoInitSARemote, msg)
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
log.Error(fwd.logPrefix(), "ipsec init SA local failed: ", err)
|
||||
fwd.handleError(err)
|
||||
fwd.lock.Unlock()
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -692,6 +691,17 @@ func (fwd *fastDatapathForwarder) Confirm() {
|
||||
}
|
||||
|
||||
fwd.heartbeatTimeout = time.NewTimer(HeartbeatTimeout)
|
||||
|
||||
fwd.lock.Unlock() // unlock before calling send() which may block
|
||||
|
||||
if len(controlMsg) > 0 {
|
||||
if err := fwd.sendControlMsg(FastDatapathCryptoInitSARemote, controlMsg); err != nil {
|
||||
log.Error(fwd.logPrefix(), "ipsec send InitSARemote failed: ", err)
|
||||
fwd.handleError(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
go fwd.doHeartbeats()
|
||||
}
|
||||
|
||||
|
||||
@@ -452,6 +452,7 @@ func (fwd *overlaySwitchForwarder) Stop() {
|
||||
fwd.lock.Lock()
|
||||
defer fwd.lock.Unlock()
|
||||
fwd.stopFrom(0)
|
||||
close(fwd.stopChan)
|
||||
}
|
||||
|
||||
func (fwd *overlaySwitchForwarder) ControlMessage(tag byte, msg []byte) {
|
||||
|
||||
+5
-1
@@ -4,10 +4,14 @@ import (
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/gopacket/pcap"
|
||||
)
|
||||
|
||||
// Must be less than 2^31 usec - see https://github.com/google/gopacket/issues/708
|
||||
const longTimeout = time.Duration(30 * time.Minute)
|
||||
|
||||
type Pcap struct {
|
||||
NonDiscardingFlowOp
|
||||
|
||||
@@ -77,7 +81,7 @@ func newPcapHandle(ifName string, promisc bool, snaplen int, bufSz int) (handle
|
||||
if err = inactive.SetSnapLen(snaplen); err != nil {
|
||||
return
|
||||
}
|
||||
if err = inactive.SetTimeout(MaxDuration); err != nil {
|
||||
if err = inactive.SetTimeout(longTimeout); err != nil {
|
||||
return
|
||||
}
|
||||
if err = inactive.SetImmediateMode(true); err != nil {
|
||||
|
||||
@@ -7,6 +7,8 @@ search_type: Documentation
|
||||
The following topics are discussed:
|
||||
|
||||
* [Installation](#install)
|
||||
* [Installing on GKE](#gke)
|
||||
* [Installing on EKS](#eks)
|
||||
* [Upgrading the Daemon Sets](#daemon-sets)
|
||||
* [CPU and Memory Requirements](#resources)
|
||||
* [Pod Eviction](#eviction)
|
||||
@@ -71,10 +73,26 @@ Shut down Kubernetes, and _on all nodes_ perform the following:
|
||||
Then relaunch Kubernetes and install the addon as described
|
||||
above.
|
||||
|
||||
**Note:** Installing on GKE
|
||||
### <a name="gke"></a> Installing on GKE
|
||||
Please note that you must grant the user the ability to create roles in Kubernetes before launching Weave Net.
|
||||
This is a prerequisite to use use role-based access control on GKE. Please see the GKE [instructions](https://cloud.google.com/kubernetes-engine/docs/how-to/role-based-access-control).
|
||||
|
||||
### <a name="gke"></a> Installing on EKS
|
||||
|
||||
EKS by default installs `amazon-vpc-cni-k8s` CNI. Please follow below steps to use Weave-net as CNI
|
||||
|
||||
- create EKS cluster in any of [prescribed](https://docs.aws.amazon.com/eks/latest/userguide/create-cluster.html) way
|
||||
- delete `amazon-vpc-cni-k8s` deamonset by running `kubectl delete ds aws-node -n kube-system` command
|
||||
- delete `/etc/cni/net.d/10-aws.conflist` on each of the node
|
||||
- edit instance security group to allow TCP 6783 and UDP 6783/6784 ports
|
||||
- flush iptables nat, mangle, filter tables to clear any iptables configurations done by `amazon-vpc-cni-k8s`
|
||||
- restart kube-proxy pods to reconfigure iptables
|
||||
- apply weave-net daemoset by following above installation steps
|
||||
- delete existing pods so they get recreated in Weave pod CIDR's address-space.
|
||||
|
||||
Please note that while pods can connect to the Kubernetes API server for your cluser, API server will not be able to connect to the pods as API server nodes are not connected to Weave Net (they run on network managed by EKS).
|
||||
|
||||
|
||||
### <a name="daemon-sets"></a> Upgrading the Daemon Sets
|
||||
|
||||
The DaemonSet definition specifies [Rolling
|
||||
@@ -89,23 +107,18 @@ Kubernetes manages
|
||||
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.
|
||||
In the example manifests we request 10% of a CPU, which will be enough
|
||||
for small installations, but you should monitor how much it uses in
|
||||
your production clusters and adjust the requests to suit.
|
||||
|
||||
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.
|
||||
We do not recommend that you set a CPU or memory _limit_ unless you
|
||||
are very experienced in such matters, because the implementation of
|
||||
limits in the Linux kernel sometimes behaves in a surprising way.
|
||||
|
||||
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.
|
||||
On a 1-node single-CPU cluster you may find Weave Net does not install
|
||||
at all, because other Kubernetes components already take 95% of the
|
||||
CPU. The best way to resolve this issue is to use machines with at
|
||||
least two CPU cores.
|
||||
|
||||
## <a name="eviction"></a>Pod Eviction
|
||||
|
||||
@@ -231,8 +244,7 @@ You may also set the `--log-level` flag to `warning` or `error` if you
|
||||
prefer to only log exceptional conditions.
|
||||
|
||||
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/)
|
||||
The [Kubernetes Service Debugging Guide](https://kubernetes.io/docs/tasks/debug-application-cluster/debug-service/)
|
||||
has a detailed step-by-step guide.
|
||||
|
||||
Once it is up and running, the status of Weave Net can be checked by
|
||||
@@ -384,7 +396,7 @@ The list of variables you can set is:
|
||||
* `CHECKPOINT_DISABLE` - if set to 1, disable checking for new Weave Net
|
||||
versions (default is blank, i.e. check is enabled)
|
||||
* `CONN_LIMIT` - soft limit on the number of connections between
|
||||
peers. Defaults to 100.
|
||||
peers. Defaults to 200.
|
||||
* `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
|
||||
@@ -412,6 +424,7 @@ The list of variables you can set is:
|
||||
* `NO_MASQ_LOCAL` - set to 1 to preserve the client source IP address when
|
||||
accessing Service annotated with `service.spec.externalTrafficPolicy=Local`.
|
||||
The feature works only with Weave IPAM (default).
|
||||
* `IPTABLES_BACKEND` - set to `nft` to use `nftables` backend for `iptables` (default is `iptables`)
|
||||
|
||||
Example:
|
||||
```
|
||||
@@ -458,3 +471,11 @@ You must pass the `password-secret` option as noted in the previous section to e
|
||||
A different option is to use `trusted-subnets` and whitelist only the subnets that host your k8s nodes. Mind that depending on your circumstances that might allow a malicious container running in your cluster to access the weave dataplane, still.
|
||||
|
||||
Read on the [Securing Connections Across Untrusted Networks](/site/tasks/manage/security-untrusted-networks/) document to see the alternatives.
|
||||
|
||||
To improve security drop `CAP_NET_RAW` from pod capabilities: by default pods can forge packets from anywhere on the network, which enables attacks such as DNS spoofing.
|
||||
|
||||
```
|
||||
securityContext:
|
||||
capabilities:
|
||||
drop: ["NET_RAW"]
|
||||
```
|
||||
@@ -13,7 +13,22 @@ Weave Net detects when a container has exited and releases its allocated address
|
||||
|
||||
See the [Automatic IP Address Management](/site/tasks/ipam/ipam.md) and also an explanation of [the basics of IP addressing](/site/concepts/ip-addresses.md) for further details.
|
||||
|
||||
Instead of allowing Weave Net to allocate IP addresses automatically (using IPAM), there may be instances where you need to control a particular container or a cluster by setting an IP address for it.
|
||||
Instead of allowing Weave Net to allocate IP addresses automatically (using IPAM), there may be instances where you need to control a particular container or a cluster by setting an IP address for it. The way to do this varies according to how containers are attached to Weave Net.
|
||||
|
||||
## Manually specifying an IP address when using CNI
|
||||
|
||||
The software making a call to CNI has to specify an allocator that allows static IPs.
|
||||
For instance the [static allocator](https://github.com/containernetworking/plugins/tree/master/plugins/ipam/static)
|
||||
|
||||
(At the time of writing there is no straightforward way to ask Kubernetes to do this.)
|
||||
|
||||
## Manually specifying an IP address when using the Weave Net Docker Plugin
|
||||
|
||||
Docker has a flag `--ip` to specify an address, e.g.:
|
||||
|
||||
$ docker run --network=mynetwork --ip=172.18.0.22 ...
|
||||
|
||||
## Manually specifying an IP address when using the Weave Net Docker Proxy
|
||||
|
||||
You can specify an IP address and a network explicitly, using Classless Inter-Domain Routing or [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing).
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ sed -e "s%imagePullPolicy: Always%imagePullPolicy: Never%" \
|
||||
-e "s%env:%$WEAVE_ENV_VARS%" \
|
||||
"$(dirname "$0")/../prog/weave-kube/weave-daemonset-k8s-1.9.yaml" | run_on "$HOST1" "$KUBECTL apply -n kube-system -f -"
|
||||
|
||||
sleep 5
|
||||
sleep 2
|
||||
|
||||
check_connections() {
|
||||
run_on $HOST1 "curl -sS http://127.0.0.1:6784/status | grep \"$SUCCESS\""
|
||||
@@ -247,6 +247,9 @@ spec:
|
||||
- namespaceSelector: {}
|
||||
EOF
|
||||
|
||||
# Allow some time for the policy change to take effect
|
||||
sleep 2
|
||||
|
||||
# Should be able to access from the "deny" pod now
|
||||
assert_raises "$SSH $HOST1 $KUBECTL exec $denyPodName -- curl -s -S -f -m 2 http://$DOMAIN:8080/status >/dev/null"
|
||||
|
||||
@@ -270,6 +273,7 @@ spec:
|
||||
cidr: $HOST1EXPIP/32
|
||||
EOF
|
||||
|
||||
# Allow some time for the policy change to take effect
|
||||
sleep 2
|
||||
|
||||
assert_raises "$SSH $HOST1 curl -s -S -f -m 2 http://$VIRTUAL_IP/status >/dev/null"
|
||||
@@ -289,6 +293,9 @@ spec:
|
||||
- {}
|
||||
EOF
|
||||
|
||||
# Allow some time for the policy change to take effect
|
||||
sleep 2
|
||||
|
||||
# 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"
|
||||
@@ -314,6 +321,9 @@ spec:
|
||||
- 8.8.8.4/32
|
||||
EOF
|
||||
|
||||
# Allow some time for the policy change to take effect
|
||||
sleep 2
|
||||
|
||||
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 -- dig @8.8.8.4 google.com >/dev/null"
|
||||
assert_raises "$SSH $HOST1 $KUBECTL exec $denyPodName -- dig @8.8.8.8 google.com >/dev/null"
|
||||
@@ -346,6 +356,9 @@ spec:
|
||||
name: kube-system
|
||||
EOF
|
||||
|
||||
# Allow some time for the policy change to take effect
|
||||
sleep 2
|
||||
|
||||
assert_raises "$SSH $HOST1 $KUBECTL exec $denyPodName -- curl -s -S -f -m 2 http://$DOMAIN:8080/status >/dev/null"
|
||||
|
||||
# Passing --no-masq-local and setting externalTrafficPolicy to Local must preserve
|
||||
@@ -359,10 +372,12 @@ sed -e "s%imagePullPolicy: Always%imagePullPolicy: Never%" \
|
||||
-e "s%env:%$WEAVE_ENV_VARS%" \
|
||||
"$(dirname "$0")/../prog/weave-kube/weave-daemonset-k8s-1.9.yaml" | run_on "$HOST1" "$KUBECTL apply -n kube-system -f -"
|
||||
|
||||
sleep 5
|
||||
sleep 2
|
||||
assert_raises 'wait_for_x check_connections "connections to establish"'
|
||||
|
||||
run_on $HOST1 "$KUBECTL patch svc netvirt -p '{\"spec\":{\"externalTrafficPolicy\":\"Local\"}}'"
|
||||
|
||||
sleep 2
|
||||
CLIENT_IP_NO_MASQ="$($SSH $HOST1 curl -sS http://$HOST2:31138/client_ip)"
|
||||
|
||||
assert_raises "[ $CLIENT_IP_NO_MASQ != $CLIENT_IP_MASQ ]"
|
||||
|
||||
@@ -66,7 +66,7 @@ function print_vars() {
|
||||
}
|
||||
|
||||
function verify_dependencies() {
|
||||
local deps=(python terraform ansible-playbook gcloud)
|
||||
local deps=(python terraform gcloud)
|
||||
for dep in "${deps[@]}"; do
|
||||
if [ ! "$(which "$dep")" ]; then
|
||||
echo >&2 "$dep is not installed or not in PATH."
|
||||
@@ -141,9 +141,18 @@ function wait_for_image() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
function install_ansible() {
|
||||
sudo apt-get update || true
|
||||
sudo apt-get install -qq -y python-pip python-dev libffi-dev libssl-dev \
|
||||
&& pip install --user -U setuptools cffi \
|
||||
&& pip install --user ansible
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2155
|
||||
function create_image() {
|
||||
if [[ "$CREATE_IMAGE" == 1 ]]; then
|
||||
install_ansible
|
||||
|
||||
greenly echo "> Creating GCP image $IMAGE_NAME..."
|
||||
local begin_img=$(date +%s)
|
||||
local num_hosts=1
|
||||
@@ -206,7 +215,8 @@ function set_hosts() {
|
||||
function provision_remotely() {
|
||||
case "$1" in
|
||||
on)
|
||||
terraform apply -input=false -parallelism="$NUM_HOSTS" -var "app=$APP" -var "name=$NAME" -var "num_hosts=$NUM_HOSTS" "$DIR/../tools/provisioning/$2"
|
||||
terraform init "$DIR/../tools/provisioning/gcp"
|
||||
terraform apply -auto-approve -input=false -parallelism="$NUM_HOSTS" -var "app=$APP" -var "name=$NAME" -var "num_hosts=$NUM_HOSTS" "$DIR/../tools/provisioning/$2"
|
||||
local status=$?
|
||||
ssh_user=$(terraform output username)
|
||||
ssh_id_file=$(terraform output private_key_path)
|
||||
|
||||
+1
-1
Submodule tools updated: f041a74ffb...2a2df52789.
@@ -483,6 +483,7 @@ destroy_bridge() {
|
||||
|
||||
[ -n "$DOCKER_BRIDGE_IP" ] || DOCKER_BRIDGE_IP=$(util_op bridge-ip $DOCKER_BRIDGE)
|
||||
|
||||
run_iptables -t filter -D INPUT -d 127.0.0.1/32 -p tcp --dport 6784 -m addrtype ! --src-type LOCAL -m conntrack ! --ctstate RELATED,ESTABLISHED -m comment --comment "Block non-local access to Weave Net control port" -j DROP >/dev/null 2>&1 || true
|
||||
run_iptables -t filter -D INPUT -i $DOCKER_BRIDGE -p udp --dport 53 -j ACCEPT >/dev/null 2>&1 || true
|
||||
run_iptables -t filter -D INPUT -i $DOCKER_BRIDGE -p tcp --dport 53 -j ACCEPT >/dev/null 2>&1 || true
|
||||
|
||||
|
||||
Reference in new issue
Block a user