// shaper retrieves the bandwidth shaper and, if it hasn't been fetched before, // initializes it and ensures the bridge is appropriately configured // This function should only be called while holding the `plugin.mu` lock func (plugin *kubenetNetworkPlugin) shaper() bandwidth.BandwidthShaper { if plugin.bandwidthShaper == nil { plugin.bandwidthShaper = bandwidth.NewTCShaper(BridgeName) plugin.bandwidthShaper.ReconcileInterface() } return plugin.bandwidthShaper }
func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID) error { pod, ok := plugin.host.GetPodByName(namespace, name) if !ok { return fmt.Errorf("pod %q cannot be found", name) } ingress, egress, err := bandwidth.ExtractPodBandwidthResources(pod.Annotations) if err != nil { return fmt.Errorf("Error reading pod bandwidth annotations: %v", err) } // Can't set up pods if we don't have a PodCIDR yet if plugin.netConfig == nil { return fmt.Errorf("Kubenet needs a PodCIDR to set up pods") } runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager) if !ok { return fmt.Errorf("Kubenet execution called on non-docker runtime") } netnsPath, err := runtime.GetNetNS(id) if err != nil { return fmt.Errorf("Kubenet failed to retrieve network namespace path: %v", err) } rt := buildCNIRuntimeConf(name, namespace, id, netnsPath) if err != nil { return fmt.Errorf("Error building CNI config: %v", err) } glog.V(3).Infof("Calling cni plugins to add container to network with cni runtime: %+v", rt) res, err := plugin.cniConfig.AddNetwork(plugin.netConfig, rt) if err != nil { return fmt.Errorf("Error adding container to network: %v", err) } if res.IP4 == nil { return fmt.Errorf("CNI plugin reported no IPv4 address for container %v.", id) } plugin.podCIDRs[id] = res.IP4.IP.String() // The first SetUpPod call creates the bridge; ensure shaping is enabled if plugin.shaper == nil { plugin.shaper = bandwidth.NewTCShaper(BridgeName) if plugin.shaper == nil { return fmt.Errorf("Failed to create bandwidth shaper!") } plugin.shaper.ReconcileInterface() } if egress != nil || ingress != nil { ipAddr, _, _ := net.ParseCIDR(plugin.podCIDRs[id]) if err = plugin.shaper.ReconcileCIDR(fmt.Sprintf("%s/32", ipAddr.String()), egress, ingress); err != nil { return fmt.Errorf("Failed to add pod to shaper: %v", err) } } return nil }
func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID) error { pod, ok := plugin.host.GetPodByName(namespace, name) if !ok { return fmt.Errorf("pod %q cannot be found", name) } ingress, egress, err := bandwidth.ExtractPodBandwidthResources(pod.Annotations) if err != nil { return fmt.Errorf("Error reading pod bandwidth annotations: %v", err) } if err := plugin.Status(); err != nil { return fmt.Errorf("Kubenet cannot SetUpPod: %v", err) } runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager) if !ok { return fmt.Errorf("Kubenet execution called on non-docker runtime") } netnsPath, err := runtime.GetNetNS(id) if err != nil { return fmt.Errorf("Kubenet failed to retrieve network namespace path: %v", err) } rt := buildCNIRuntimeConf(name, namespace, id, netnsPath) if err != nil { return fmt.Errorf("Error building CNI config: %v", err) } if err = plugin.addContainerToNetwork(id, rt); err != nil { return err } // The first SetUpPod call creates the bridge; ensure shaping is enabled if plugin.shaper == nil { plugin.shaper = bandwidth.NewTCShaper(BridgeName) if plugin.shaper == nil { return fmt.Errorf("Failed to create bandwidth shaper!") } plugin.ensureBridgeTxQueueLen() plugin.shaper.ReconcileInterface() } if egress != nil || ingress != nil { ipAddr, _, _ := net.ParseCIDR(plugin.podCIDRs[id]) if err = plugin.shaper.ReconcileCIDR(fmt.Sprintf("%s/32", ipAddr.String()), egress, ingress); err != nil { return fmt.Errorf("Failed to add pod to shaper: %v", err) } } return nil }
func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID) error { // Can't set up pods if we don't have a PodCIDR yet if plugin.netConfig == nil { return fmt.Errorf("Kubenet needs a PodCIDR to set up pods") } runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager) if !ok { return fmt.Errorf("Kubenet execution called on non-docker runtime") } netnsPath, err := runtime.GetNetNS(id) if err != nil { return err } rt := buildCNIRuntimeConf(name, namespace, id, netnsPath) if err != nil { return fmt.Errorf("Error building CNI config: %v", err) } glog.V(3).Infof("Calling cni plugins to add container to network with cni runtime: %+v", rt) res, err := plugin.cniConfig.AddNetwork(plugin.netConfig, rt) if err != nil { return fmt.Errorf("Error adding container to network: %v", err) } if res.IP4 == nil { return fmt.Errorf("CNI plugin reported no IPv4 address for container %v.", id) } plugin.podCIDRs[id] = res.IP4.IP.String() // The first SetUpPod call creates the bridge; ensure shaping is enabled if plugin.shaper == nil { plugin.shaper = bandwidth.NewTCShaper(BridgeName) if plugin.shaper == nil { return fmt.Errorf("Failed to create bandwidth shaper!") } plugin.shaper.ReconcileInterface() } // TODO: get ingress/egress from Pod.Spec and add pod CIDR to shaper return nil }
// TODO: remove when kubenet plugin is ready // NOTE!!! if you make changes here, also make them to kubenet func (kl *Kubelet) reconcileCBR0(podCIDR string) error { if podCIDR == "" { glog.V(5).Info("PodCIDR not set. Will not configure cbr0.") return nil } glog.V(5).Infof("PodCIDR is set to %q", podCIDR) _, cidr, err := net.ParseCIDR(podCIDR) if err != nil { return err } // Set cbr0 interface address to first address in IPNet cidr.IP.To4()[3] += 1 if err := ensureCbr0(cidr, kl.hairpinMode == componentconfig.PromiscuousBridge, kl.babysitDaemons); err != nil { return err } if kl.shapingEnabled() { if kl.shaper == nil { glog.V(5).Info("Shaper is nil, creating") kl.shaper = bandwidth.NewTCShaper("cbr0") } return kl.shaper.ReconcileInterface() } return nil }
func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID) error { plugin.mu.Lock() defer plugin.mu.Unlock() start := time.Now() defer func() { glog.V(4).Infof("SetUpPod took %v for %s/%s", time.Since(start), namespace, name) }() pod, ok := plugin.host.GetPodByName(namespace, name) if !ok { return fmt.Errorf("pod %q cannot be found", name) } ingress, egress, err := bandwidth.ExtractPodBandwidthResources(pod.Annotations) if err != nil { return fmt.Errorf("Error reading pod bandwidth annotations: %v", err) } if err := plugin.Status(); err != nil { return fmt.Errorf("Kubenet cannot SetUpPod: %v", err) } // Bring up container loopback interface if _, err := plugin.addContainerToNetwork(plugin.loConfig, "lo", namespace, name, id); err != nil { return err } // Hook container up with our bridge res, err := plugin.addContainerToNetwork(plugin.netConfig, network.DefaultInterfaceName, namespace, name, id) if err != nil { return err } if res.IP4 == nil || res.IP4.IP.String() == "" { return fmt.Errorf("CNI plugin reported no IPv4 address for container %v.", id) } plugin.podCIDRs[id] = res.IP4.IP.String() // Put the container bridge into promiscuous mode to force it to accept hairpin packets. // TODO: Remove this once the kernel bug (#20096) is fixed. // TODO: check and set promiscuous mode with netlink once vishvananda/netlink supports it if plugin.hairpinMode == componentconfig.PromiscuousBridge { output, err := plugin.execer.Command("ip", "link", "show", "dev", BridgeName).CombinedOutput() if err != nil || strings.Index(string(output), "PROMISC") < 0 { _, err := plugin.execer.Command("ip", "link", "set", BridgeName, "promisc", "on").CombinedOutput() if err != nil { return fmt.Errorf("Error setting promiscuous mode on %s: %v", BridgeName, err) } } } // The first SetUpPod call creates the bridge; ensure shaping is enabled if plugin.shaper == nil { plugin.shaper = bandwidth.NewTCShaper(BridgeName) if plugin.shaper == nil { return fmt.Errorf("Failed to create bandwidth shaper!") } plugin.ensureBridgeTxQueueLen() plugin.shaper.ReconcileInterface() } if egress != nil || ingress != nil { ipAddr, _, _ := net.ParseCIDR(plugin.podCIDRs[id]) if err = plugin.shaper.ReconcileCIDR(fmt.Sprintf("%s/32", ipAddr.String()), egress, ingress); err != nil { return fmt.Errorf("Failed to add pod to shaper: %v", err) } } return nil }
func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID) error { plugin.mu.Lock() defer plugin.mu.Unlock() start := time.Now() defer func() { glog.V(4).Infof("TearDownPod took %v for %s/%s", time.Since(start), namespace, name) }() pod, ok := plugin.host.GetPodByName(namespace, name) if !ok { return fmt.Errorf("pod %q cannot be found", name) } ingress, egress, err := bandwidth.ExtractPodBandwidthResources(pod.Annotations) if err != nil { return fmt.Errorf("Error reading pod bandwidth annotations: %v", err) } if err := plugin.Status(); err != nil { return fmt.Errorf("Kubenet cannot SetUpPod: %v", err) } runtime, ok := plugin.host.GetRuntime().(*dockertools.DockerManager) if !ok { return fmt.Errorf("Kubenet execution called on non-docker runtime") } netnsPath, err := runtime.GetNetNS(id) if err != nil { return fmt.Errorf("Kubenet failed to retrieve network namespace path: %v", err) } rt := buildCNIRuntimeConf(name, namespace, id, netnsPath) if err != nil { return fmt.Errorf("Error building CNI config: %v", err) } if err = plugin.addContainerToNetwork(id, rt); err != nil { return err } // Put the container bridge into promiscuous mode to force it to accept hairpin packets. // TODO: Remove this once the kernel bug (#20096) is fixed. // TODO: check and set promiscuous mode with netlink once vishvananda/netlink supports it if plugin.hairpinMode == componentconfig.PromiscuousBridge { output, err := plugin.execer.Command("ip", "link", "show", "dev", BridgeName).CombinedOutput() if err != nil || strings.Index(string(output), "PROMISC") < 0 { _, err := plugin.execer.Command("ip", "link", "set", BridgeName, "promisc", "on").CombinedOutput() if err != nil { return fmt.Errorf("Error setting promiscuous mode on %s: %v", BridgeName, err) } } } // The first SetUpPod call creates the bridge; ensure shaping is enabled if plugin.shaper == nil { plugin.shaper = bandwidth.NewTCShaper(BridgeName) if plugin.shaper == nil { return fmt.Errorf("Failed to create bandwidth shaper!") } plugin.ensureBridgeTxQueueLen() plugin.shaper.ReconcileInterface() } if egress != nil || ingress != nil { ipAddr, _, _ := net.ParseCIDR(plugin.podCIDRs[id]) if err = plugin.shaper.ReconcileCIDR(fmt.Sprintf("%s/32", ipAddr.String()), egress, ingress); err != nil { return fmt.Errorf("Failed to add pod to shaper: %v", err) } } return nil }