// RunProxy starts the proxy func (c *NodeConfig) RunProxy() { // initialize kube proxy serviceConfig := pconfig.NewServiceConfig() endpointsConfig := pconfig.NewEndpointsConfig() loadBalancer := proxy.NewLoadBalancerRR() endpointsConfig.RegisterHandler(loadBalancer) host, _, err := net.SplitHostPort(c.BindAddress) if err != nil { glog.Fatalf("The provided value to bind to must be an ip:port %q", c.BindAddress) } ip := net.ParseIP(host) if ip == nil { glog.Fatalf("The provided value to bind to must be an ip:port: %q", c.BindAddress) } protocol := iptables.ProtocolIpv4 if ip.To4() == nil { protocol = iptables.ProtocolIpv6 } go util.Forever(func() { proxier, err := proxy.NewProxier(loadBalancer, ip, iptables.New(kexec.New(), protocol), util.PortRange{}) if err != nil { switch { // conflicting use of iptables, retry case proxy.IsProxyLocked(err): glog.Errorf("Unable to start proxy, will retry: %v", err) return // on a system without iptables case strings.Contains(err.Error(), "executable file not found in path"): glog.V(4).Infof("kube-proxy initialization error: %v", err) glog.Warningf("WARNING: Could not find the iptables command. The service proxy requires iptables and will be disabled.") case err == proxy.ErrProxyOnLocalhost: glog.Warningf("WARNING: The service proxy cannot bind to localhost and will be disabled.") case strings.Contains(err.Error(), "you must be root"): glog.Warningf("WARNING: Could not modify iptables. You must run this process as root to use the service proxy.") default: glog.Warningf("WARNING: Could not modify iptables. You must run this process as root to use the service proxy: %v", err) } select {} } pconfig.NewSourceAPI( c.Client, 30*time.Second, serviceConfig.Channel("api"), endpointsConfig.Channel("api")) serviceConfig.RegisterHandler(proxier) glog.Infof("Started Kubernetes Proxy on %s", host) select {} }, 5*time.Second) }
// Run runs the specified ProxyServer. This should never exit. func (s *ProxyServer) Run(_ []string) error { // TODO(vmarmol): Use container config for this. if err := util.ApplyOomScoreAdj(0, s.OOMScoreAdj); err != nil { glog.V(2).Info(err) } // Run in its own container. if err := util.RunInResourceContainer(s.ResourceContainer); err != nil { glog.Warningf("Failed to start in resource-only container %q: %v", s.ResourceContainer, err) } else { glog.V(2).Infof("Running in resource-only container %q", s.ResourceContainer) } serviceConfig := config.NewServiceConfig() endpointsConfig := config.NewEndpointsConfig() protocol := iptables.ProtocolIpv4 if net.IP(s.BindAddress).To4() == nil { protocol = iptables.ProtocolIpv6 } loadBalancer := proxy.NewLoadBalancerRR() proxier, err := proxy.NewProxier(loadBalancer, net.IP(s.BindAddress), iptables.New(exec.New(), protocol), s.PortRange) if err != nil { glog.Fatalf("Unable to create proxer: %v", err) } // Wire proxier to handle changes to services serviceConfig.RegisterHandler(proxier) // And wire loadBalancer to handle changes to endpoints to services endpointsConfig.RegisterHandler(loadBalancer) // 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. // define api config source if s.Kubeconfig == "" && s.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: s.Kubeconfig}, &clientcmd.ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: s.Master}}).ClientConfig() if err != nil { return err } client, err := client.New(kubeconfig) if err != nil { glog.Fatalf("Invalid API configuration: %v", err) } config.NewSourceAPI( client, 30*time.Second, serviceConfig.Channel("api"), endpointsConfig.Channel("api"), ) if s.HealthzPort > 0 { go util.Forever(func() { err := http.ListenAndServe(s.HealthzBindAddress.String()+":"+strconv.Itoa(s.HealthzPort), nil) if err != nil { glog.Errorf("Starting health server failed: %v", err) } }, 5*time.Second) } // Just loop forever for now... proxier.SyncLoop() return nil }