// Run runs the specified ProxyServer. This should never exit (unless CleanupAndExit is set). func (s *ProxyServer) Run(_ []string) error { // remove iptables rules and exit if s.Config.CleanupAndExit { encounteredError := userspace.CleanupLeftovers(s.IptInterface) encounteredError = iptables.CleanupLeftovers(s.IptInterface) || encounteredError if encounteredError { return errors.New("Encountered an error while tearing down rules.") } return nil } // Birth Cry after the birth is successful s.birthCry() // Start up Healthz service if requested if s.Config.HealthzPort > 0 { go util.Until(func() { err := http.ListenAndServe(s.Config.HealthzBindAddress.String()+":"+strconv.Itoa(s.Config.HealthzPort), nil) if err != nil { glog.Errorf("Starting health server failed: %v", err) } }, 5*time.Second, util.NeverStop) } // Just loop forever for now... s.Proxier.SyncLoop() return nil }
// NewProxyServerDefault creates a new ProxyServer object with default parameters. func NewProxyServerDefault(config *ProxyServerConfig) (*ProxyServer, error) { protocol := utiliptables.ProtocolIpv4 if config.BindAddress.To4() == nil { protocol = utiliptables.ProtocolIpv6 } // We ommit creation of pretty much everything if we run in cleanup mode if config.CleanupAndExit { execer := exec.New() dbus := utildbus.New() IptInterface := utiliptables.New(execer, dbus, protocol) return &ProxyServer{ Config: config, IptInterface: IptInterface, }, nil } // TODO(vmarmol): Use container config for this. var oomAdjuster *oom.OomAdjuster if config.OOMScoreAdj != 0 { oomAdjuster := oom.NewOomAdjuster() if err := oomAdjuster.ApplyOomScoreAdj(0, config.OOMScoreAdj); err != nil { glog.V(2).Info(err) } } if config.ResourceContainer != "" { // Run in its own container. if err := util.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 } client, err := kubeclient.New(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}) eventBroadcaster.StartRecordingToSink(client.Events("")) // Create a iptables utils. execer := exec.New() dbus := utildbus.New() iptInterface := utiliptables.New(execer, dbus, protocol) var proxier proxy.ProxyProvider var endpointsHandler proxyconfig.EndpointsConfigHandler useIptablesProxy := false if mayTryIptablesProxy(config.ProxyMode, client.Nodes(), hostname) { var err error // guaranteed false on error, error only necessary for debugging useIptablesProxy, err = iptables.ShouldUseIptablesProxier() if err != nil { glog.Errorf("Can't determine whether to use iptables proxy, using userspace proxier: %v", err) } } if useIptablesProxy { glog.V(2).Info("Using iptables Proxier.") execer := exec.New() proxierIptables, err := iptables.NewProxier(iptInterface, execer, config.SyncPeriod, config.MasqueradeAll) 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(2).Info("Tearing down userspace rules. Errors here are acceptable.") userspace.CleanupLeftovers(iptInterface) } else { glog.V(2).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, config.BindAddress, iptInterface, config.PortRange, config.SyncPeriod, config.UDPIdleTimeout) if err != nil { glog.Fatalf("Unable to create proxier: %v", err) } proxier = proxierUserspace // Remove artifacts from the pure-iptables Proxier. glog.V(2).Info("Tearing down pure-iptables proxy rules. Errors here are acceptable.") 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, 30*time.Second, serviceConfig.Channel("api"), endpointsConfig.Channel("api"), ) config.nodeRef = &api.ObjectReference{ Kind: "Node", Name: hostname, UID: types.UID(hostname), Namespace: "", } return NewProxyServer(config, client, endpointsConfig, endpointsHandler, iptInterface, oomAdjuster, proxier, recorder, serviceConfig) }