From d669ab841db4d9adc44345c16d961b4ec33727a2 Mon Sep 17 00:00:00 2001 From: Ivan Shvedunov Date: Fri, 29 Sep 2017 12:18:35 +0300 Subject: [PATCH] Use configurable netmask for Calico --- deploy/virtlet-ds-dev.yaml | 6 ++++ deploy/virtlet-ds.yaml | 6 ++++ docs/networking.md | 5 ++- examples/ubuntu-vm.yaml | 8 +++++ pkg/tapmanager/tapfdsource.go | 30 ++++++++-------- pkg/tapmanager/tapfdsource_test.go | 55 ------------------------------ 6 files changed, 39 insertions(+), 71 deletions(-) delete mode 100644 pkg/tapmanager/tapfdsource_test.go diff --git a/deploy/virtlet-ds-dev.yaml b/deploy/virtlet-ds-dev.yaml index 6c15f88f2..5f292780d 100644 --- a/deploy/virtlet-ds-dev.yaml +++ b/deploy/virtlet-ds-dev.yaml @@ -164,6 +164,12 @@ spec: name: virtlet-config key: loglevel optional: true + - name: VIRTLET_CALICO_SUBNET + valueFrom: + configMapKeyRef: + name: virtlet-config + key: calico-subnet + optional: true - name: IMAGE_REGEXP_TRANSLATION valueFrom: configMapKeyRef: diff --git a/deploy/virtlet-ds.yaml b/deploy/virtlet-ds.yaml index c4f5ef128..b62a231e9 100644 --- a/deploy/virtlet-ds.yaml +++ b/deploy/virtlet-ds.yaml @@ -164,6 +164,12 @@ spec: name: virtlet-config key: loglevel optional: true + - name: VIRTLET_CALICO_SUBNET + valueFrom: + configMapKeyRef: + name: virtlet-config + key: calico-subnet + optional: true - name: IMAGE_REGEXP_TRANSLATION valueFrom: configMapKeyRef: diff --git a/docs/networking.md b/docs/networking.md index 5ce23bf14..59d25a24c 100644 --- a/docs/networking.md +++ b/docs/networking.md @@ -85,7 +85,10 @@ spawning it as a child process. as it tries to pass a routing configuration that cannot be passed over DHCP. For it to work Virtlet patches Calico-provided CNI result, replacing Calico's unreachable fake gateway with another fake gateway -with an IP address acquired from Calico IPAM. +with an IP address acquired from Calico IPAM. A proper node subnet must +be set for Calico-based virtlet installations. It's controlled by +`calico-subnet` key Virtlet configmap (denoting the number of 1s in +the netmask) and defaults to `24`. **NOTE:** Virtlet doesn't support `hostNetwork` pod setting because it cannot be impelemnted for VM in a meaningful way. diff --git a/examples/ubuntu-vm.yaml b/examples/ubuntu-vm.yaml index 4495a673c..9acd1987d 100644 --- a/examples/ubuntu-vm.yaml +++ b/examples/ubuntu-vm.yaml @@ -6,6 +6,14 @@ metadata: kubernetes.io/target-runtime: virtlet VirtletCloudInitUserData: | ssh_pwauth: True + users: + - name: testuser + gecos: User + primary-group: testuser + groups: users + lock_passwd: false + passwd: "$6$rounds=4096$wPs4Hz4tfs$a8ssMnlvH.3GX88yxXKF2cKMlVULsnydoOKgkuStTErTq2dzKZiIx9R/pPWWh5JLxzoZEx7lsSX5T2jW5WISi1" + sudo: ALL=(ALL) NOPASSWD:ALL VirtletSSHKeys: | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCaJEcFDXEK2ZbX0ZLS1EIYFZRbDAcRfuVjpstSc0De8+sV1aiu+dePxdkuDRwqFtCyk6dEZkssjOkBXtri00MECLkir6FcH3kKOJtbJ6vy3uaJc9w1ERo+wyl6SkAh/+JTJkp7QRXj8oylW5E20LsbnA/dIwWzAF51PPwF7A7FtNg9DnwPqMkxFo1Th/buOMKbP5ZA1mmNNtmzbMpMfJATvVyiv3ccsSJKOiyQr6UG+j7sc/7jMVz5Xk34Vd0l8GwcB0334MchHckmqDB142h/NCWTr8oLakDNvkfC1YneAfAO41hDkUbxPtVBG5M/o7P4fxoqiHEX+ZLfRxDtHB53 me@localhost spec: diff --git a/pkg/tapmanager/tapfdsource.go b/pkg/tapmanager/tapfdsource.go index c05266000..34d592c9c 100644 --- a/pkg/tapmanager/tapfdsource.go +++ b/pkg/tapmanager/tapfdsource.go @@ -21,6 +21,8 @@ import ( "errors" "fmt" "net" + "os" + "strconv" "sync" "time" @@ -36,7 +38,9 @@ import ( ) const ( - calicoNetType = "calico" + calicoNetType = "calico" + calicoDefaultSubnet = 24 + calicoSubnetVar = "VIRTLET_CALICO_SUBNET" ) // PodNetworkDesc contains the data that are required by TapFDSource @@ -154,6 +158,7 @@ func (s *TapFDSource) GetFD(key string, data []byte) (int, []byte, error) { if netConfig.IPs[0].Version != "4" { return 0, nil, errors.New("IPv4 config was expected") } + netConfig.IPs[0].Address.Mask = netmaskForCalico() netConfig.IPs[0].Gateway = s.dummyGateway netConfig.Routes = []*cnitypes.Route{ { @@ -313,20 +318,15 @@ func fixCNIResult(netConfig *cnicurrent.Result, csn *nettools.ContainerSideNetwo } } -func calcNetmaskForCalico(ipA, ipB net.IP) (net.IPMask, error) { - var a, b uint - for _, v := range ipA { - a = (a << 8) + uint(v) - } - for _, v := range ipB { - b = (b << 8) + uint(v) - } - for n := 30; n >= 0; n-- { - m := (uint(1) << uint(32-n)) - 1 - // avoid zero and broadcast addrs - if (a&^m) == (b&^m) && (a&m) != 0 && (b&m) != 0 && (a&m) != m && (b&m) != m { - return net.CIDRMask(n, 32), nil +func netmaskForCalico() net.IPMask { + n := calicoDefaultSubnet + subnetStr := os.Getenv(calicoSubnetVar) + if subnetStr != "" { + n, err := strconv.Atoi(subnetStr) + if err != nil || n <= 0 || n > 30 { + glog.Warningf("bad calico subnet %q, using /%d", subnetStr, calicoDefaultSubnet) + n = calicoDefaultSubnet } } - return nil, errors.New("addresses too different") + return net.CIDRMask(n, 32) } diff --git a/pkg/tapmanager/tapfdsource_test.go b/pkg/tapmanager/tapfdsource_test.go deleted file mode 100644 index 375389154..000000000 --- a/pkg/tapmanager/tapfdsource_test.go +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2017 Mirantis - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package tapmanager - -import ( - "net" - "testing" -) - -// TODO: add test for TapFDSource itself - -func verifyNetmaskForCalico(t *testing.T, a, b net.IP, expectedOnes int) { - mask, err := calcNetmaskForCalico(a, b) - if err != nil { - t.Fatalf("%v - %v: can't calculate netmask: %v", err) - } - ones, bits := mask.Size() - if bits != 32 { - t.Errorf("%v - %v: bad mask bit count %d (expected 32)", a, b, bits) - } - if ones != expectedOnes { - t.Errorf("%v - %v: bad mask ones count %d (expected %d)", a, b, ones, expectedOnes) - } -} - -func TestCalcNetmaskForCalico(t *testing.T) { - for _, tc := range []struct { - a, b net.IP - ones int - }{ - // byte 3: 10000101, 10000110 - {net.IP{192, 168, 135, 133}, net.IP{192, 168, 135, 134}, 30}, - // byte 3: 10000100, 10000101 - {net.IP{192, 168, 135, 132}, net.IP{192, 168, 135, 133}, 29}, - // byte 2: 10101001, 10000111 - {net.IP{192, 168, 169, 129}, net.IP{192, 168, 135, 133}, 18}, - } { - verifyNetmaskForCalico(t, tc.a, tc.b, tc.ones) - verifyNetmaskForCalico(t, tc.b, tc.a, tc.ones) - } -}