func newEtcdClient(etcdServer string) (*etcd.Client, error) { var ( client *etcd.Client err error ) for attempt := 1; attempt <= maxConnectAttempts; attempt++ { if _, err = etcdutil.GetEtcdVersion(etcdServer); err == nil { break } if attempt == maxConnectAttempts { break } glog.Infof("[Attempt: %d] Attempting access to etcd after 5 second sleep", attempt) time.Sleep(5 * time.Second) } if err != nil { return nil, fmt.Errorf("failed to connect to etcd server: %v, error: %v", etcdServer, err) } glog.Infof("Etcd server found: %v", etcdServer) // loop until we have > 0 machines && machines[0] != "" poll, timeout := 1*time.Second, 10*time.Second if err := wait.Poll(poll, timeout, func() (bool, error) { if client = etcd.NewClient([]string{etcdServer}); client == nil { return false, fmt.Errorf("etcd.NewClient returned nil") } client.SyncCluster() machines := client.GetCluster() if len(machines) == 0 || len(machines[0]) == 0 { return false, nil } return true, nil }); err != nil { return nil, fmt.Errorf("Timed out after %s waiting for at least 1 synchronized etcd server in the cluster. Error: %v", timeout, err) } return client, nil }
func main() { util.InitFlags() util.InitLogs() defer util.FlushLogs() if err := util.ApplyOomScoreAdj(*oomScoreAdj); err != nil { glog.Info(err) } verflag.PrintAndExitIfRequested() serviceConfig := config.NewServiceConfig() endpointsConfig := config.NewEndpointsConfig() protocol := iptables.ProtocolIpv4 if net.IP(bindAddress).To4() == nil { protocol = iptables.ProtocolIpv6 } loadBalancer := proxy.NewLoadBalancerRR() proxier := proxy.NewProxier(loadBalancer, net.IP(bindAddress), iptables.New(exec.New(), protocol)) if proxier == nil { glog.Fatalf("failed to create proxier, aborting") } // 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 clientConfig.Host != "" { glog.Infof("Using api calls to get config %v", clientConfig.Host) client, err := client.New(clientConfig) if err != nil { glog.Fatalf("Invalid API configuration: %v", err) } config.NewSourceAPI( client.Services(api.NamespaceAll), client.Endpoints(api.NamespaceAll), 30*time.Second, serviceConfig.Channel("api"), endpointsConfig.Channel("api"), ) } else { var etcdClient *etcd.Client // Set up etcd client if len(etcdServerList) > 0 { // Set up logger for etcd client etcd.SetLogger(util.NewLogger("etcd ")) etcdClient = etcd.NewClient(etcdServerList) } else if *etcdConfigFile != "" { // Set up logger for etcd client etcd.SetLogger(util.NewLogger("etcd ")) var err error etcdClient, err = etcd.NewClientFromFile(*etcdConfigFile) if err != nil { glog.Fatalf("Error with etcd config file: %v", err) } } // Create a configuration source that handles configuration from etcd. if etcdClient != nil { glog.Infof("Using etcd servers %v", etcdClient.GetCluster()) config.NewConfigSourceEtcd(etcdClient, serviceConfig.Channel("etcd"), endpointsConfig.Channel("etcd")) } } if *healthz_port > 0 { go util.Forever(func() { err := http.ListenAndServe(bindAddress.String()+":"+strconv.Itoa(*healthz_port), nil) if err != nil { glog.Errorf("Starting health server failed: %v", err) } }, 5*time.Second) } // Just loop forever for now... proxier.SyncLoop() }
func main() { flag.Parse() util.InitLogs() defer util.FlushLogs() verflag.PrintAndExitIfRequested() serviceConfig := config.NewServiceConfig() endpointsConfig := config.NewEndpointsConfig() // define api config source if clientConfig.Host != "" { glog.Infof("Using api calls to get config %v", clientConfig.Host) client, err := client.New(clientConfig) if err != nil { glog.Fatalf("Invalid API configuration: %v", err) } config.NewSourceAPI( client.Services(api.NamespaceAll), client.Endpoints(api.NamespaceAll), 30*time.Second, serviceConfig.Channel("api"), endpointsConfig.Channel("api"), ) } else { var etcdClient *etcd.Client // Set up etcd client if len(etcdServerList) > 0 { // Set up logger for etcd client etcd.SetLogger(util.NewLogger("etcd ")) etcdClient = etcd.NewClient(etcdServerList) } else if *etcdConfigFile != "" { // Set up logger for etcd client etcd.SetLogger(util.NewLogger("etcd ")) var err error etcdClient, err = etcd.NewClientFromFile(*etcdConfigFile) if err != nil { glog.Fatalf("Error with etcd config file: %v", err) } } // Create a configuration source that handles configuration from etcd. if etcdClient != nil { glog.Infof("Using etcd servers %v", etcdClient.GetCluster()) config.NewConfigSourceEtcd(etcdClient, serviceConfig.Channel("etcd"), endpointsConfig.Channel("etcd")) } } loadBalancer := proxy.NewLoadBalancerRR() proxier := proxy.NewProxier(loadBalancer, net.IP(bindAddress), iptables.New(exec.New())) // Wire proxier to handle changes to services serviceConfig.RegisterHandler(proxier) // And wire loadBalancer to handle changes to endpoints to services endpointsConfig.RegisterHandler(loadBalancer) // Just loop forever for now... proxier.SyncLoop() }
func main() { flag.Parse() util.InitLogs() defer util.FlushLogs() rand.Seed(time.Now().UTC().UnixNano()) verflag.PrintAndExitIfRequested() if *runonce { exclusiveFlag := "invalid option: --runonce and %s are mutually exclusive" if len(etcdServerList) > 0 { glog.Fatalf(exclusiveFlag, "--etcd_servers") } if *enableServer { glog.Infof("--runonce is set, disabling server") *enableServer = false } } etcd.SetLogger(util.NewLogger("etcd ")) // Log the events locally too. record.StartLogging(glog.Infof) capabilities.Initialize(capabilities.Capabilities{ AllowPrivileged: *allowPrivileged, }) dockerClient, err := docker.NewClient(getDockerEndpoint()) if err != nil { glog.Fatal("Couldn't connect to docker.") } hostname := getHostname() if *rootDirectory == "" { glog.Fatal("Invalid root directory path.") } *rootDirectory = path.Clean(*rootDirectory) if err := os.MkdirAll(*rootDirectory, 0750); err != nil { glog.Fatalf("Error creating root directory: %v", err) } // source of all configuration cfg := kconfig.NewPodConfig(kconfig.PodConfigNotificationSnapshotAndUpdates) // define file config source if *config != "" { kconfig.NewSourceFile(*config, *fileCheckFrequency, cfg.Channel("file")) } // define url config source if *manifestURL != "" { kconfig.NewSourceURL(*manifestURL, *httpCheckFrequency, cfg.Channel("http")) } // define etcd config source and initialize etcd client var etcdClient *etcd.Client if len(etcdServerList) > 0 { etcdClient = etcd.NewClient(etcdServerList) } else if *etcdConfigFile != "" { var err error etcdClient, err = etcd.NewClientFromFile(*etcdConfigFile) if err != nil { glog.Fatalf("Error with etcd config file: %v", err) } } if etcdClient != nil { glog.Infof("Watching for etcd configs at %v", etcdClient.GetCluster()) kconfig.NewSourceEtcd(kconfig.EtcdKeyForHost(hostname), etcdClient, cfg.Channel("etcd")) } // TODO: block until all sources have delivered at least one update to the channel, or break the sync loop // up into "per source" synchronizations k := kubelet.NewMainKubelet( getHostname(), dockerClient, etcdClient, *rootDirectory, *networkContainerImage, *syncFrequency, float32(*registryPullQPS), *registryBurst, *minimumGCAge, *maxContainerCount) k.BirthCry() go func() { util.Forever(func() { err := k.GarbageCollectContainers() if err != nil { glog.Errorf("Garbage collect failed: %v", err) } }, time.Minute*1) }() go func() { defer util.HandleCrash() // TODO: Monitor this connection, reconnect if needed? glog.V(1).Infof("Trying to create cadvisor client.") cadvisorClient, err := cadvisor.NewClient("http://127.0.0.1:4194") if err != nil { glog.Errorf("Error on creating cadvisor client: %v", err) return } glog.V(1).Infof("Successfully created cadvisor client.") k.SetCadvisorClient(cadvisorClient) }() // TODO: These should probably become more plugin-ish: register a factory func // in each checker's init(), iterate those here. health.AddHealthChecker(health.NewExecHealthChecker(k)) health.AddHealthChecker(health.NewHTTPHealthChecker(&http.Client{})) health.AddHealthChecker(&health.TCPHealthChecker{}) // process pods and exit. if *runonce { if _, err := k.RunOnce(cfg.Updates()); err != nil { glog.Fatalf("--runonce failed: %v", err) } return } // start the kubelet go util.Forever(func() { k.Run(cfg.Updates()) }, 0) // start the kubelet server if *enableServer { go util.Forever(func() { kubelet.ListenAndServeKubeletServer(k, cfg.Channel("http"), net.IP(address), *port, *enableDebuggingHandlers) }, 0) } // runs forever select {} }