func (lkct LinuxKernelCompatTester) IsCompatible() error { // Check for the required sysctls. We don't care about the value, just // that it exists. If this Proxier is chosen, we'll initialize it as we // need. _, err := utilsysctl.New().GetSysctl(sysctlRouteLocalnet) return err }
// sysctlSomaxconn returns the value of net.core.somaxconn, i.e. // maximum number of connections that can be queued for acceptance // http://nginx.org/en/docs/http/ngx_http_core_module.html#listen func sysctlSomaxconn() int { maxConns, err := sysctl.New().GetSysctl("net/core/somaxconn") if err != nil || maxConns < 512 { glog.Warningf("system net.core.somaxconn=%v. Using NGINX default (511)", maxConns) return 511 } return maxConns }
// sysctlSomaxconn returns the value of net.core.somaxconn, i.e. // maximum number of connections that can be queued for acceptance // http://nginx.org/en/docs/http/ngx_http_core_module.html#listen func sysctlSomaxconn() int { maxConns, err := sysctl.New().GetSysctl("net/core/somaxconn") if err != nil || maxConns < 512 { glog.V(3).Infof("system net.core.somaxconn=%v (using system default)", maxConns) return 511 } return maxConns }
func (realConntracker) setIntSysCtl(name string, value int) error { entry := "net/netfilter/" + name glog.Infof("Set sysctl '%v' to %v", entry, value) if err := sysctl.New().SetSysctl(entry, value); err != nil { return err } return nil }
// changeSysctl changes the required network setting in /proc to get // keepalived working in the local system. func changeSysctl() error { sys := sysctl.New() for k, v := range sysctlAdjustments { if err := sys.SetSysctl(k, v); err != nil { return err } } return nil }
func (plugin *NoopNetworkPlugin) Init(host Host, hairpinMode componentconfig.HairpinMode, nonMasqueradeCIDR string, mtu int) error { // Set bridge-nf-call-iptables=1 to maintain compatibility with older // kubernetes versions to ensure the iptables-based kube proxy functions // correctly. Other plugins are responsible for setting this correctly // depending on whether or not they connect containers to Linux bridges // or use some other mechanism (ie, SDN vswitch). // Ensure the netfilter module is loaded on kernel >= 3.18; previously // it was built-in. utilexec.New().Command("modprobe", "br-netfilter").CombinedOutput() if err := utilsysctl.New().SetSysctl(sysctlBridgeCallIPTables, 1); err != nil { glog.Warningf("can't set sysctl %s: %v", sysctlBridgeCallIPTables, err) } return nil }
func NewPlugin(networkPluginDir string) network.NetworkPlugin { protocol := utiliptables.ProtocolIpv4 execer := utilexec.New() dbus := utildbus.New() sysctl := utilsysctl.New() iptInterface := utiliptables.New(execer, dbus, protocol) return &kubenetNetworkPlugin{ podIPs: make(map[kubecontainer.ContainerID]string), execer: utilexec.New(), iptables: iptInterface, sysctl: sysctl, vendorDir: networkPluginDir, hostportHandler: hostport.NewHostportHandler(), nonMasqueradeCIDR: "10.0.0.0/8", } }
func (realConntracker) SetMax(max int) error { glog.Infof("Setting nf_conntrack_max to %d", max) if err := sysctl.New().SetSysctl("net/netfilter/nf_conntrack_max", max); err != nil { return err } // sysfs is expected to be mounted as 'rw'. However, it may be unexpectedly mounted as // 'ro' by docker because of a known docker issue (https://github.com/docker/docker/issues/24000). // Setting conntrack will fail when sysfs is readonly. When that happens, we don't set conntrack // hashsize and return a special error readOnlySysFSError here. The caller should deal with // readOnlySysFSError differently. writable, err := isSysFSWritable() if err != nil { return err } if !writable { return readOnlySysFSError } // TODO: generify this and sysctl to a new sysfs.WriteInt() glog.Infof("Setting conntrack hashsize to %d", max/4) return ioutil.WriteFile("/sys/module/nf_conntrack/parameters/hashsize", []byte(strconv.Itoa(max/4)), 0640) }
// setupKernelTunables validates kernel tunable flags are set as expected // depending upon the specified option, it will either warn, error, or modify the kernel tunable flags func setupKernelTunables(option KernelTunableBehavior) error { desiredState := map[string]int{ utilsysctl.VmOvercommitMemory: utilsysctl.VmOvercommitMemoryAlways, utilsysctl.VmPanicOnOOM: utilsysctl.VmPanicOnOOMInvokeOOMKiller, utilsysctl.KernelPanic: utilsysctl.KernelPanicRebootTimeout, utilsysctl.KernelPanicOnOops: utilsysctl.KernelPanicOnOopsAlways, } sysctl := utilsysctl.New() errList := []error{} for flag, expectedValue := range desiredState { val, err := sysctl.GetSysctl(flag) if err != nil { errList = append(errList, err) continue } if val == expectedValue { continue } switch option { case KernelTunableError: errList = append(errList, fmt.Errorf("Invalid kernel flag: %v, expected value: %v, actual value: %v", flag, expectedValue, val)) case KernelTunableWarn: glog.V(2).Infof("Invalid kernel flag: %v, expected value: %v, actual value: %v", flag, expectedValue, val) case KernelTunableModify: glog.V(2).Infof("Updating kernel flag: %v, expected value: %v, actual value: %v", flag, expectedValue, val) err = sysctl.SetSysctl(flag, expectedValue) if err != nil { errList = append(errList, err) } } } return utilerrors.NewAggregate(errList) }
func (plugin *OsdnNode) SetupSDN() (bool, error) { clusterNetworkCIDR := plugin.networkInfo.ClusterNetwork.String() serviceNetworkCIDR := plugin.networkInfo.ServiceNetwork.String() localSubnetCIDR := plugin.localSubnetCIDR _, ipnet, err := net.ParseCIDR(localSubnetCIDR) localSubnetMaskLength, _ := ipnet.Mask.Size() localSubnetGateway := netutils.GenerateDefaultGateway(ipnet).String() glog.V(5).Infof("[SDN setup] node pod subnet %s gateway %s", ipnet.String(), localSubnetGateway) exec := kexec.New() if plugin.clearLbr0IptablesRule { // Delete docker's left-over lbr0 rule; cannot do this from // NewNodePlugin (where docker is cleaned up) because we need // localSubnetCIDR which is only valid after plugin start ipt := iptables.New(exec, utildbus.New(), iptables.ProtocolIpv4) ipt.DeleteRule(iptables.TableNAT, iptables.ChainPostrouting, "-s", localSubnetCIDR, "!", "-o", "lbr0", "-j", "MASQUERADE") } gwCIDR := fmt.Sprintf("%s/%d", localSubnetGateway, localSubnetMaskLength) if plugin.alreadySetUp(gwCIDR, clusterNetworkCIDR) { glog.V(5).Infof("[SDN setup] no SDN setup required") return false, nil } glog.V(5).Infof("[SDN setup] full SDN setup required") if err := os.MkdirAll("/run/openshift-sdn", 0700); err != nil { return false, err } config := fmt.Sprintf("export OPENSHIFT_CLUSTER_SUBNET=%s", clusterNetworkCIDR) err = ioutil.WriteFile("/run/openshift-sdn/config.env", []byte(config), 0644) if err != nil { return false, err } err = plugin.ovs.AddBridge("fail-mode=secure", "protocols=OpenFlow13") if err != nil { return false, err } _ = plugin.ovs.DeletePort(VXLAN) _, err = plugin.ovs.AddPort(VXLAN, 1, "type=vxlan", `options:remote_ip="flow"`, `options:key="flow"`) if err != nil { return false, err } _ = plugin.ovs.DeletePort(TUN) _, err = plugin.ovs.AddPort(TUN, 2, "type=internal") if err != nil { return false, err } otx := plugin.ovs.NewTransaction() // Table 0: initial dispatch based on in_port // vxlan0 otx.AddFlow("table=0, priority=200, in_port=1, arp, nw_src=%s, nw_dst=%s, actions=move:NXM_NX_TUN_ID[0..31]->NXM_NX_REG0[],goto_table:1", clusterNetworkCIDR, localSubnetCIDR) otx.AddFlow("table=0, priority=200, in_port=1, ip, nw_src=%s, nw_dst=%s, actions=move:NXM_NX_TUN_ID[0..31]->NXM_NX_REG0[],goto_table:1", clusterNetworkCIDR, localSubnetCIDR) otx.AddFlow("table=0, priority=150, in_port=1, actions=drop") // tun0 otx.AddFlow("table=0, priority=200, in_port=2, arp, nw_src=%s, nw_dst=%s, actions=goto_table:5", localSubnetGateway, clusterNetworkCIDR) otx.AddFlow("table=0, priority=200, in_port=2, ip, actions=goto_table:5") otx.AddFlow("table=0, priority=150, in_port=2, actions=drop") // else, from a container otx.AddFlow("table=0, priority=100, arp, actions=goto_table:2") otx.AddFlow("table=0, priority=100, ip, actions=goto_table:2") otx.AddFlow("table=0, priority=0, actions=drop") // Table 1: VXLAN ingress filtering; filled in by AddHostSubnetRules() // eg, "table=1, priority=100, tun_src=${remote_node_ip}, actions=goto_table:5" otx.AddFlow("table=1, priority=0, actions=drop") // Table 2: from OpenShift container; validate IP/MAC, assign tenant-id; filled in by openshift-sdn-ovs // eg, "table=2, priority=100, in_port=${ovs_port}, arp, nw_src=${ipaddr}, arp_sha=${macaddr}, actions=load:${tenant_id}->NXM_NX_REG0[], goto_table:5" // "table=2, priority=100, in_port=${ovs_port}, ip, nw_src=${ipaddr}, actions=load:${tenant_id}->NXM_NX_REG0[], goto_table:3" // (${tenant_id} is always 0 for single-tenant) otx.AddFlow("table=2, priority=0, actions=drop") // Table 3: from OpenShift container; service vs non-service otx.AddFlow("table=3, priority=100, ip, nw_dst=%s, actions=goto_table:4", serviceNetworkCIDR) otx.AddFlow("table=3, priority=0, actions=goto_table:5") // Table 4: from OpenShift container; service dispatch; filled in by AddServiceRules() otx.AddFlow("table=4, priority=200, reg0=0, actions=output:2") // eg, "table=4, priority=100, reg0=${tenant_id}, ${service_proto}, nw_dst=${service_ip}, tp_dst=${service_port}, actions=output:2" otx.AddFlow("table=4, priority=0, actions=drop") // Table 5: general routing otx.AddFlow("table=5, priority=300, arp, nw_dst=%s, actions=output:2", localSubnetGateway) otx.AddFlow("table=5, priority=300, ip, nw_dst=%s, actions=output:2", localSubnetGateway) otx.AddFlow("table=5, priority=200, arp, nw_dst=%s, actions=goto_table:6", localSubnetCIDR) otx.AddFlow("table=5, priority=200, ip, nw_dst=%s, actions=goto_table:7", localSubnetCIDR) otx.AddFlow("table=5, priority=100, arp, nw_dst=%s, actions=goto_table:8", clusterNetworkCIDR) otx.AddFlow("table=5, priority=100, ip, nw_dst=%s, actions=goto_table:8", clusterNetworkCIDR) otx.AddFlow("table=5, priority=0, ip, actions=goto_table:9") otx.AddFlow("table=5, priority=0, arp, actions=drop") // Table 6: ARP to container, filled in by openshift-sdn-ovs // eg, "table=6, priority=100, arp, nw_dst=${container_ip}, actions=output:${ovs_port}" otx.AddFlow("table=6, priority=0, actions=drop") // Table 7: IP to container; filled in by openshift-sdn-ovs // eg, "table=7, priority=100, reg0=0, ip, nw_dst=${ipaddr}, actions=output:${ovs_port}" // eg, "table=7, priority=100, reg0=${tenant_id}, ip, nw_dst=${ipaddr}, actions=output:${ovs_port}" otx.AddFlow("table=7, priority=0, actions=drop") // Table 8: to remote container; filled in by AddHostSubnetRules() // eg, "table=8, priority=100, arp, nw_dst=${remote_subnet_cidr}, actions=move:NXM_NX_REG0[]->NXM_NX_TUN_ID[0..31], set_field:${remote_node_ip}->tun_dst,output:1" // eg, "table=8, priority=100, ip, nw_dst=${remote_subnet_cidr}, actions=move:NXM_NX_REG0[]->NXM_NX_TUN_ID[0..31], set_field:${remote_node_ip}->tun_dst,output:1" otx.AddFlow("table=8, priority=0, actions=drop") // Table 9: egress network policy dispatch; edited by updateEgressNetworkPolicyRules() // eg, "table=9, reg0=${tenant_id}, priority=2, ip, nw_dst=${external_cidr}, actions=drop otx.AddFlow("table=9, priority=0, actions=output:2") err = otx.EndTransaction() if err != nil { return false, err } itx := ipcmd.NewTransaction(exec, TUN) itx.AddAddress(gwCIDR) defer deleteLocalSubnetRoute(TUN, localSubnetCIDR) itx.SetLink("mtu", fmt.Sprint(plugin.mtu)) itx.SetLink("up") itx.AddRoute(clusterNetworkCIDR, "proto", "kernel", "scope", "link") itx.AddRoute(serviceNetworkCIDR) err = itx.EndTransaction() if err != nil { return false, err } sysctl := sysctl.New() // Enable IP forwarding for ipv4 packets err = sysctl.SetSysctl("net/ipv4/ip_forward", 1) if err != nil { return false, fmt.Errorf("Could not enable IPv4 forwarding: %s", err) } err = sysctl.SetSysctl(fmt.Sprintf("net/ipv4/conf/%s/forwarding", TUN), 1) if err != nil { return false, fmt.Errorf("Could not enable IPv4 forwarding on %s: %s", TUN, err) } // Table 253: rule version; note action is hex bytes separated by '.' otx = plugin.ovs.NewTransaction() pluginVersion := getPluginVersion(plugin.multitenant) otx.AddFlow("%s, %s%s.%s", VERSION_TABLE, VERSION_ACTION, pluginVersion[0], pluginVersion[1]) err = otx.EndTransaction() if err != nil { return false, err } return true, nil }
// NewProxyServerDefault creates a new ProxyServer object with default parameters. func NewProxyServerDefault(config *options.ProxyServerConfig) (*ProxyServer, error) { if c, err := configz.New("componentconfig"); err == nil { c.Set(config.KubeProxyConfiguration) } else { glog.Errorf("unable to register configz: %s", err) } protocol := utiliptables.ProtocolIpv4 if net.ParseIP(config.BindAddress).To4() == nil { protocol = utiliptables.ProtocolIpv6 } // Create a iptables utils. execer := exec.New() dbus := utildbus.New() iptInterface := utiliptables.New(execer, dbus, protocol) // We omit creation of pretty much everything if we run in cleanup mode if config.CleanupAndExit { return &ProxyServer{ Config: config, IptInterface: iptInterface, }, nil } // TODO(vmarmol): Use container config for this. var oomAdjuster *oom.OOMAdjuster if config.OOMScoreAdj != nil { oomAdjuster = oom.NewOOMAdjuster() if err := oomAdjuster.ApplyOOMScoreAdj(0, int(*config.OOMScoreAdj)); err != nil { glog.V(2).Info(err) } } if config.ResourceContainer != "" { // Run in its own container. if err := resourcecontainer.RunInResourceContainer(config.ResourceContainer); err != nil { glog.Warningf("Failed to start in resource-only container %q: %v", config.ResourceContainer, err) } else { glog.V(2).Infof("Running in resource-only container %q", config.ResourceContainer) } } // Create a Kube Client // define api config source if config.Kubeconfig == "" && config.Master == "" { glog.Warningf("Neither --kubeconfig nor --master was specified. Using default API client. This might not work.") } // This creates a client, first loading any specified kubeconfig // file, and then overriding the Master flag, if non-empty. kubeconfig, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( &clientcmd.ClientConfigLoadingRules{ExplicitPath: config.Kubeconfig}, &clientcmd.ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: config.Master}}).ClientConfig() if err != nil { return nil, err } kubeconfig.ContentType = config.ContentType // Override kubeconfig qps/burst settings from flags kubeconfig.QPS = config.KubeAPIQPS kubeconfig.Burst = int(config.KubeAPIBurst) client, err := clientset.NewForConfig(kubeconfig) if err != nil { glog.Fatalf("Invalid API configuration: %v", err) } // Create event recorder hostname := nodeutil.GetHostname(config.HostnameOverride) eventBroadcaster := record.NewBroadcaster() recorder := eventBroadcaster.NewRecorder(api.EventSource{Component: "kube-proxy", Host: hostname}) var proxier proxy.ProxyProvider var endpointsHandler proxyconfig.EndpointsConfigHandler proxyMode := getProxyMode(string(config.Mode), client.Core().Nodes(), hostname, iptInterface, iptables.LinuxKernelCompatTester{}) if proxyMode == proxyModeIPTables { glog.V(0).Info("Using iptables Proxier.") if config.IPTablesMasqueradeBit == nil { // IPTablesMasqueradeBit must be specified or defaulted. return nil, fmt.Errorf("Unable to read IPTablesMasqueradeBit from config") } proxierIPTables, err := iptables.NewProxier(iptInterface, utilsysctl.New(), execer, config.IPTablesSyncPeriod.Duration, config.MasqueradeAll, int(*config.IPTablesMasqueradeBit), config.ClusterCIDR, hostname, getNodeIP(client, hostname)) if err != nil { glog.Fatalf("Unable to create proxier: %v", err) } proxier = proxierIPTables endpointsHandler = proxierIPTables // No turning back. Remove artifacts that might still exist from the userspace Proxier. glog.V(0).Info("Tearing down userspace rules.") userspace.CleanupLeftovers(iptInterface) } else { glog.V(0).Info("Using userspace Proxier.") // This is a proxy.LoadBalancer which NewProxier needs but has methods we don't need for // our config.EndpointsConfigHandler. loadBalancer := userspace.NewLoadBalancerRR() // set EndpointsConfigHandler to our loadBalancer endpointsHandler = loadBalancer proxierUserspace, err := userspace.NewProxier( loadBalancer, net.ParseIP(config.BindAddress), iptInterface, *utilnet.ParsePortRangeOrDie(config.PortRange), config.IPTablesSyncPeriod.Duration, config.UDPIdleTimeout.Duration, ) if err != nil { glog.Fatalf("Unable to create proxier: %v", err) } proxier = proxierUserspace // Remove artifacts from the pure-iptables Proxier. glog.V(0).Info("Tearing down pure-iptables proxy rules.") iptables.CleanupLeftovers(iptInterface) } iptInterface.AddReloadFunc(proxier.Sync) // Create configs (i.e. Watches for Services and Endpoints) // Note: RegisterHandler() calls need to happen before creation of Sources because sources // only notify on changes, and the initial update (on process start) may be lost if no handlers // are registered yet. serviceConfig := proxyconfig.NewServiceConfig() serviceConfig.RegisterHandler(proxier) endpointsConfig := proxyconfig.NewEndpointsConfig() endpointsConfig.RegisterHandler(endpointsHandler) proxyconfig.NewSourceAPI( client.Core().RESTClient(), config.ConfigSyncPeriod, serviceConfig.Channel("api"), endpointsConfig.Channel("api"), ) config.NodeRef = &api.ObjectReference{ Kind: "Node", Name: hostname, UID: types.UID(hostname), Namespace: "", } conntracker := realConntracker{} return NewProxyServer(client, config, iptInterface, proxier, eventBroadcaster, recorder, conntracker, proxyMode) }
func (plugin *OsdnNode) SetupSDN() (bool, error) { localSubnetCIDR, err := plugin.getLocalSubnet() if err != nil { return false, err } clusterNetworkCIDR := plugin.networkInfo.ClusterNetwork.String() serviceNetworkCIDR := plugin.networkInfo.ServiceNetwork.String() _, ipnet, err := net.ParseCIDR(localSubnetCIDR) localSubnetMaskLength, _ := ipnet.Mask.Size() localSubnetGateway := netutils.GenerateDefaultGateway(ipnet).String() glog.V(5).Infof("[SDN setup] node pod subnet %s gateway %s", ipnet.String(), localSubnetGateway) gwCIDR := fmt.Sprintf("%s/%d", localSubnetGateway, localSubnetMaskLength) if plugin.alreadySetUp(gwCIDR, clusterNetworkCIDR) { glog.V(5).Infof("[SDN setup] no SDN setup required") return false, nil } glog.V(5).Infof("[SDN setup] full SDN setup required") mtuStr := fmt.Sprint(plugin.mtu) exec := kexec.New() itx := ipcmd.NewTransaction(exec, LBR) itx.SetLink("down") itx.IgnoreError() itx.DeleteLink() itx.IgnoreError() itx.AddLink("type", "bridge") itx.AddAddress(gwCIDR) itx.SetLink("up") err = itx.EndTransaction() if err != nil { glog.Errorf("Failed to configure docker bridge: %v", err) return false, err } defer deleteLocalSubnetRoute(LBR, localSubnetCIDR) glog.V(5).Infof("[SDN setup] docker setup %s mtu %s", LBR, mtuStr) out, err := exec.Command("openshift-sdn-docker-setup.sh", LBR, mtuStr).CombinedOutput() if err != nil { glog.Errorf("Failed to configure docker networking: %v\n%s", err, out) return false, err } else { glog.V(5).Infof("[SDN setup] docker setup success:\n%s", out) } config := fmt.Sprintf("export OPENSHIFT_CLUSTER_SUBNET=%s", clusterNetworkCIDR) err = ioutil.WriteFile("/run/openshift-sdn/config.env", []byte(config), 0644) if err != nil { return false, err } itx = ipcmd.NewTransaction(exec, VLINUXBR) itx.DeleteLink() itx.IgnoreError() itx.AddLink("mtu", mtuStr, "type", "veth", "peer", "name", VOVSBR, "mtu", mtuStr) itx.SetLink("up") itx.SetLink("txqueuelen", "0") err = itx.EndTransaction() if err != nil { return false, err } itx = ipcmd.NewTransaction(exec, VOVSBR) itx.SetLink("up") itx.SetLink("txqueuelen", "0") err = itx.EndTransaction() if err != nil { return false, err } itx = ipcmd.NewTransaction(exec, LBR) itx.AddSlave(VLINUXBR) err = itx.EndTransaction() if err != nil { return false, err } err = plugin.ovs.AddBridge("fail-mode=secure", "protocols=OpenFlow13") if err != nil { return false, err } _ = plugin.ovs.DeletePort(VXLAN) _, err = plugin.ovs.AddPort(VXLAN, 1, "type=vxlan", `options:remote_ip="flow"`, `options:key="flow"`) if err != nil { return false, err } _ = plugin.ovs.DeletePort(TUN) _, err = plugin.ovs.AddPort(TUN, 2, "type=internal") if err != nil { return false, err } _, err = plugin.ovs.AddPort(VOVSBR, 3) if err != nil { return false, err } otx := plugin.ovs.NewTransaction() // Table 0: initial dispatch based on in_port // vxlan0 otx.AddFlow("table=0, priority=200, in_port=1, arp, nw_src=%s, nw_dst=%s, actions=move:NXM_NX_TUN_ID[0..31]->NXM_NX_REG0[],goto_table:1", clusterNetworkCIDR, localSubnetCIDR) otx.AddFlow("table=0, priority=200, in_port=1, ip, nw_src=%s, nw_dst=%s, actions=move:NXM_NX_TUN_ID[0..31]->NXM_NX_REG0[],goto_table:1", clusterNetworkCIDR, localSubnetCIDR) otx.AddFlow("table=0, priority=150, in_port=1, actions=drop") // tun0 otx.AddFlow("table=0, priority=200, in_port=2, arp, nw_src=%s, nw_dst=%s, actions=goto_table:5", localSubnetGateway, clusterNetworkCIDR) otx.AddFlow("table=0, priority=200, in_port=2, ip, actions=goto_table:5") otx.AddFlow("table=0, priority=150, in_port=2, actions=drop") // vovsbr otx.AddFlow("table=0, priority=200, in_port=3, arp, nw_src=%s, actions=goto_table:5", localSubnetCIDR) otx.AddFlow("table=0, priority=200, in_port=3, ip, nw_src=%s, actions=goto_table:5", localSubnetCIDR) otx.AddFlow("table=0, priority=150, in_port=3, actions=drop") // else, from a container otx.AddFlow("table=0, priority=100, arp, actions=goto_table:2") otx.AddFlow("table=0, priority=100, ip, actions=goto_table:2") otx.AddFlow("table=0, priority=0, actions=drop") // Table 1: VXLAN ingress filtering; filled in by AddHostSubnetRules() // eg, "table=1, priority=100, tun_src=${remote_node_ip}, actions=goto_table:5" otx.AddFlow("table=1, priority=0, actions=drop") // Table 2: from OpenShift container; validate IP/MAC, assign tenant-id; filled in by openshift-sdn-ovs // eg, "table=2, priority=100, in_port=${ovs_port}, arp, nw_src=${ipaddr}, arp_sha=${macaddr}, actions=load:${tenant_id}->NXM_NX_REG0[], goto_table:5" // "table=2, priority=100, in_port=${ovs_port}, ip, nw_src=${ipaddr}, actions=load:${tenant_id}->NXM_NX_REG0[], goto_table:3" // (${tenant_id} is always 0 for single-tenant) otx.AddFlow("table=2, priority=0, actions=drop") // Table 3: from OpenShift container; service vs non-service otx.AddFlow("table=3, priority=100, ip, nw_dst=%s, actions=goto_table:4", serviceNetworkCIDR) otx.AddFlow("table=3, priority=0, actions=goto_table:5") // Table 4: from OpenShift container; service dispatch; filled in by AddServiceRules() otx.AddFlow("table=4, priority=200, reg0=0, actions=output:2") // eg, "table=4, priority=100, reg0=${tenant_id}, ${service_proto}, nw_dst=${service_ip}, tp_dst=${service_port}, actions=output:2" otx.AddFlow("table=4, priority=0, actions=drop") // Table 5: general routing otx.AddFlow("table=5, priority=300, arp, nw_dst=%s, actions=output:2", localSubnetGateway) otx.AddFlow("table=5, priority=300, ip, nw_dst=%s, actions=output:2", localSubnetGateway) otx.AddFlow("table=5, priority=200, arp, nw_dst=%s, actions=goto_table:6", localSubnetCIDR) otx.AddFlow("table=5, priority=200, ip, nw_dst=%s, actions=goto_table:7", localSubnetCIDR) otx.AddFlow("table=5, priority=100, arp, nw_dst=%s, actions=goto_table:8", clusterNetworkCIDR) otx.AddFlow("table=5, priority=100, ip, nw_dst=%s, actions=goto_table:8", clusterNetworkCIDR) otx.AddFlow("table=5, priority=0, ip, actions=goto_table:9") otx.AddFlow("table=5, priority=0, arp, actions=drop") // Table 6: ARP to container, filled in by openshift-sdn-ovs // eg, "table=6, priority=100, arp, nw_dst=${container_ip}, actions=output:${ovs_port}" otx.AddFlow("table=6, priority=0, actions=output:3") // Table 7: IP to container; filled in by openshift-sdn-ovs // eg, "table=7, priority=100, reg0=0, ip, nw_dst=${ipaddr}, actions=output:${ovs_port}" // eg, "table=7, priority=100, reg0=${tenant_id}, ip, nw_dst=${ipaddr}, actions=output:${ovs_port}" otx.AddFlow("table=7, priority=0, actions=output:3") // Table 8: to remote container; filled in by AddHostSubnetRules() // eg, "table=8, priority=100, arp, nw_dst=${remote_subnet_cidr}, actions=move:NXM_NX_REG0[]->NXM_NX_TUN_ID[0..31], set_field:${remote_node_ip}->tun_dst,output:1" // eg, "table=8, priority=100, ip, nw_dst=${remote_subnet_cidr}, actions=move:NXM_NX_REG0[]->NXM_NX_TUN_ID[0..31], set_field:${remote_node_ip}->tun_dst,output:1" otx.AddFlow("table=8, priority=0, actions=drop") // Table 9: egress network policy dispatch; edited by updateEgressNetworkPolicyRules() // eg, "table=9, reg0=${tenant_id}, priority=2, ip, nw_dst=${external_cidr}, actions=drop otx.AddFlow("table=9, priority=0, actions=output:2") err = otx.EndTransaction() if err != nil { return false, err } itx = ipcmd.NewTransaction(exec, TUN) itx.AddAddress(gwCIDR) defer deleteLocalSubnetRoute(TUN, localSubnetCIDR) itx.SetLink("mtu", mtuStr) itx.SetLink("up") itx.AddRoute(clusterNetworkCIDR, "proto", "kernel", "scope", "link") itx.AddRoute(serviceNetworkCIDR) err = itx.EndTransaction() if err != nil { return false, err } // Clean up docker0 since docker won't itx = ipcmd.NewTransaction(exec, "docker0") itx.SetLink("down") itx.IgnoreError() itx.DeleteLink() itx.IgnoreError() _ = itx.EndTransaction() sysctl := sysctl.New() // Disable iptables for linux bridges (and in particular lbr0), ignoring errors. // (This has to have been performed in advance for docker-in-docker deployments, // since this will fail there). _, _ = exec.Command("modprobe", "br_netfilter").CombinedOutput() err = sysctl.SetSysctl("net/bridge/bridge-nf-call-iptables", 0) if err != nil { glog.Warningf("Could not set net.bridge.bridge-nf-call-iptables sysctl: %s", err) } else { glog.V(5).Infof("[SDN setup] set net.bridge.bridge-nf-call-iptables to 0") } // Enable IP forwarding for ipv4 packets err = sysctl.SetSysctl("net/ipv4/ip_forward", 1) if err != nil { return false, fmt.Errorf("Could not enable IPv4 forwarding: %s", err) } err = sysctl.SetSysctl(fmt.Sprintf("net/ipv4/conf/%s/forwarding", TUN), 1) if err != nil { return false, fmt.Errorf("Could not enable IPv4 forwarding on %s: %s", TUN, err) } // Table 253: rule version; note action is hex bytes separated by '.' otx = plugin.ovs.NewTransaction() pluginVersion := getPluginVersion(plugin.multitenant) otx.AddFlow("%s, %s%s.%s", VERSION_TABLE, VERSION_ACTION, pluginVersion[0], pluginVersion[1]) err = otx.EndTransaction() if err != nil { return false, err } return true, nil }
func (realConntracker) SetTCPEstablishedTimeout(seconds int) error { glog.Infof("Setting nf_conntrack_tcp_timeout_established to %d", seconds) return sysctl.New().SetSysctl("net/netfilter/nf_conntrack_tcp_timeout_established", seconds) }
// RunProxy starts the proxy func (c *NodeConfig) RunProxy() { protocol := utiliptables.ProtocolIpv4 bindAddr := net.ParseIP(c.ProxyConfig.BindAddress) if bindAddr.To4() == nil { protocol = utiliptables.ProtocolIpv6 } portRange := utilnet.ParsePortRangeOrDie(c.ProxyConfig.PortRange) hostname := utilnode.GetHostname(c.KubeletServer.HostnameOverride) eventBroadcaster := record.NewBroadcaster() eventBroadcaster.StartRecordingToSink(c.Client.Events("")) recorder := eventBroadcaster.NewRecorder(kapi.EventSource{Component: "kube-proxy", Host: hostname}) execer := kexec.New() dbus := utildbus.New() iptInterface := utiliptables.New(execer, dbus, protocol) var proxier proxy.ProxyProvider var endpointsHandler pconfig.EndpointsConfigHandler switch c.ProxyConfig.Mode { case componentconfig.ProxyModeIPTables: glog.V(0).Info("Using iptables Proxier.") if c.ProxyConfig.IPTablesMasqueradeBit == nil { // IPTablesMasqueradeBit must be specified or defaulted. glog.Fatalf("Unable to read IPTablesMasqueradeBit from config") } proxierIptables, err := iptables.NewProxier( iptInterface, utilsysctl.New(), execer, c.ProxyConfig.IPTablesSyncPeriod.Duration, c.ProxyConfig.MasqueradeAll, int(*c.ProxyConfig.IPTablesMasqueradeBit), c.ProxyConfig.ClusterCIDR, hostname, getNodeIP(c.Client, hostname), ) if err != nil { if c.Containerized { glog.Fatalf("error: Could not initialize Kubernetes Proxy: %v\n When running in a container, you must run the container in the host network namespace with --net=host and with --privileged", err) } else { glog.Fatalf("error: Could not initialize Kubernetes Proxy. You must run this process as root to use the service proxy: %v", err) } } proxier = proxierIptables endpointsHandler = proxierIptables // No turning back. Remove artifacts that might still exist from the userspace Proxier. glog.V(0).Info("Tearing down userspace rules.") userspace.CleanupLeftovers(iptInterface) case componentconfig.ProxyModeUserspace: glog.V(0).Info("Using userspace Proxier.") // This is a proxy.LoadBalancer which NewProxier needs but has methods we don't need for // our config.EndpointsConfigHandler. loadBalancer := userspace.NewLoadBalancerRR() // set EndpointsConfigHandler to our loadBalancer endpointsHandler = loadBalancer proxierUserspace, err := userspace.NewProxier( loadBalancer, bindAddr, iptInterface, *portRange, c.ProxyConfig.IPTablesSyncPeriod.Duration, c.ProxyConfig.UDPIdleTimeout.Duration, ) if err != nil { if c.Containerized { glog.Fatalf("error: Could not initialize Kubernetes Proxy: %v\n When running in a container, you must run the container in the host network namespace with --net=host and with --privileged", err) } else { glog.Fatalf("error: Could not initialize Kubernetes Proxy. You must run this process as root to use the service proxy: %v", err) } } proxier = proxierUserspace // Remove artifacts from the pure-iptables Proxier. glog.V(0).Info("Tearing down pure-iptables proxy rules.") iptables.CleanupLeftovers(iptInterface) default: glog.Fatalf("Unknown proxy mode %q", c.ProxyConfig.Mode) } // Create configs (i.e. Watches for Services and Endpoints) // Note: RegisterHandler() calls need to happen before creation of Sources because sources // only notify on changes, and the initial update (on process start) may be lost if no handlers // are registered yet. serviceConfig := pconfig.NewServiceConfig() if c.EnableUnidling { unidlingLoadBalancer := ouserspace.NewLoadBalancerRR() signaler := unidler.NewEventSignaler(recorder) unidlingUserspaceProxy, err := unidler.NewUnidlerProxier(unidlingLoadBalancer, bindAddr, iptInterface, execer, *portRange, c.ProxyConfig.IPTablesSyncPeriod.Duration, c.ProxyConfig.UDPIdleTimeout.Duration, signaler) if err != nil { if c.Containerized { glog.Fatalf("error: Could not initialize Kubernetes Proxy: %v\n When running in a container, you must run the container in the host network namespace with --net=host and with --privileged", err) } else { glog.Fatalf("error: Could not initialize Kubernetes Proxy. You must run this process as root to use the service proxy: %v", err) } } hybridProxier, err := hybrid.NewHybridProxier(unidlingLoadBalancer, unidlingUserspaceProxy, endpointsHandler, proxier, c.ProxyConfig.IPTablesSyncPeriod.Duration, serviceConfig) if err != nil { if c.Containerized { glog.Fatalf("error: Could not initialize Kubernetes Proxy: %v\n When running in a container, you must run the container in the host network namespace with --net=host and with --privileged", err) } else { glog.Fatalf("error: Could not initialize Kubernetes Proxy. You must run this process as root to use the service proxy: %v", err) } } endpointsHandler = hybridProxier proxier = hybridProxier } iptInterface.AddReloadFunc(proxier.Sync) serviceConfig.RegisterHandler(proxier) endpointsConfig := pconfig.NewEndpointsConfig() // customized handling registration that inserts a filter if needed if c.FilteringEndpointsHandler != nil { if err := c.FilteringEndpointsHandler.Start(endpointsHandler); err != nil { glog.Fatalf("error: node proxy plugin startup failed: %v", err) } endpointsHandler = c.FilteringEndpointsHandler } endpointsConfig.RegisterHandler(endpointsHandler) c.ServiceStore = pconfig.NewServiceStore(c.ServiceStore, serviceConfig.Channel("api")) c.EndpointsStore = pconfig.NewEndpointsStore(c.EndpointsStore, endpointsConfig.Channel("api")) // will be started by RunServiceStores recorder.Eventf(c.ProxyConfig.NodeRef, kapi.EventTypeNormal, "Starting", "Starting kube-proxy.") // periodically sync k8s iptables rules go utilwait.Forever(proxier.SyncLoop, 0) glog.Infof("Started Kubernetes Proxy on %s", c.ProxyConfig.BindAddress) }