// NewSourceAPIserver creates config source that watches for changes to the services and endpoints. func NewSourceAPI(c *client.Client, period time.Duration, servicesChan chan<- ServiceUpdate, endpointsChan chan<- EndpointsUpdate) { servicesLW := cache.NewListWatchFromClient(c, "services", api.NamespaceAll, fields.Everything()) endpointsLW := cache.NewListWatchFromClient(c, "endpoints", api.NamespaceAll, fields.Everything()) newServicesSourceApiFromLW(servicesLW, period, servicesChan) newEndpointsSourceApiFromLW(endpointsLW, period, endpointsChan) }
// NewClient returns a usable Client. Don't forget to Stop it. func NewClient(addr string, resyncPeriod time.Duration) (Client, error) { c, err := unversioned.New(&unversioned.Config{Host: addr}) if err != nil { return nil, err } podListWatch := cache.NewListWatchFromClient(c, "pods", api.NamespaceAll, fields.Everything()) podStore := cache.NewStore(cache.MetaNamespaceKeyFunc) podReflector := cache.NewReflector(podListWatch, &api.Pod{}, podStore, resyncPeriod) serviceListWatch := cache.NewListWatchFromClient(c, "services", api.NamespaceAll, fields.Everything()) serviceStore := cache.NewStore(cache.MetaNamespaceKeyFunc) serviceReflector := cache.NewReflector(serviceListWatch, &api.Service{}, serviceStore, resyncPeriod) quit := make(chan struct{}) podReflector.RunUntil(quit) serviceReflector.RunUntil(quit) return &client{ quit: quit, client: c, podReflector: podReflector, podStore: &cache.StoreToPodLister{Store: podStore}, serviceReflector: serviceReflector, serviceStore: &cache.StoreToServiceLister{Store: serviceStore}, }, nil }
// newIPVSController creates a new controller from the given config. func newIPVSController(kubeClient *unversioned.Client, namespace string, useUnicast bool, password string) *ipvsControllerController { ipvsc := ipvsControllerController{ client: kubeClient, queue: workqueue.New(), reloadRateLimiter: util.NewTokenBucketRateLimiter(reloadQPS, int(reloadQPS)), reloadLock: &sync.Mutex{}, } clusterNodes := getClusterNodesIP(kubeClient) nodeInfo, err := getNodeInfo(clusterNodes) if err != nil { glog.Fatalf("Error getting local IP from nodes in the cluster: %v", err) } neighbors := getNodeNeighbors(nodeInfo, clusterNodes) ipvsc.keepalived = &keepalived{ iface: nodeInfo.iface, ip: nodeInfo.ip, netmask: nodeInfo.netmask, nodes: clusterNodes, neighbors: neighbors, priority: getNodePriority(nodeInfo.ip, clusterNodes), useUnicast: useUnicast, password: password, } enqueue := func(obj interface{}) { key, err := keyFunc(obj) if err != nil { glog.Infof("Couldn't get key for object %+v: %v", obj, err) return } ipvsc.queue.Add(key) } eventHandlers := framework.ResourceEventHandlerFuncs{ AddFunc: enqueue, DeleteFunc: enqueue, UpdateFunc: func(old, cur interface{}) { if !reflect.DeepEqual(old, cur) { enqueue(cur) } }, } ipvsc.svcLister.Store, ipvsc.svcController = framework.NewInformer( cache.NewListWatchFromClient( ipvsc.client, "services", namespace, fields.Everything()), &api.Service{}, resyncPeriod, eventHandlers) ipvsc.epLister.Store, ipvsc.epController = framework.NewInformer( cache.NewListWatchFromClient( ipvsc.client, "endpoints", namespace, fields.Everything()), &api.Endpoints{}, resyncPeriod, eventHandlers) return &ipvsc }
// NewSourceAPI creates config source that watches for changes to the services and endpoints. func NewSourceAPI(c cache.Getter, period time.Duration, servicesChan chan<- ServiceUpdate, endpointsChan chan<- EndpointsUpdate) { servicesLW := cache.NewListWatchFromClient(c, "services", api.NamespaceAll, fields.Everything()) cache.NewReflector(servicesLW, &api.Service{}, NewServiceStore(nil, servicesChan), period).Run() endpointsLW := cache.NewListWatchFromClient(c, "endpoints", api.NamespaceAll, fields.Everything()) cache.NewReflector(endpointsLW, &api.Endpoints{}, NewEndpointsStore(nil, endpointsChan), period).Run() }
// newLoadBalancerController creates a new controller from the given config. func newLoadBalancerController(cfg *loadBalancerConfig, kubeClient *unversioned.Client, namespace string) *loadBalancerController { lbc := loadBalancerController{ cfg: cfg, client: kubeClient, queue: workqueue.New(), reloadRateLimiter: util.NewTokenBucketRateLimiter( reloadQPS, int(reloadQPS)), targetService: *targetService, forwardServices: *forwardServices, httpPort: *httpPort, tcpServices: map[string]int{}, } for _, service := range strings.Split(*tcpServices, ",") { portSplit := strings.Split(service, ":") if len(portSplit) != 2 { glog.Errorf("Ignoring misconfigured TCP service %v", service) continue } if port, err := strconv.Atoi(portSplit[1]); err != nil { glog.Errorf("Ignoring misconfigured TCP service %v: %v", service, err) continue } else { lbc.tcpServices[portSplit[0]] = port } } enqueue := func(obj interface{}) { key, err := keyFunc(obj) if err != nil { glog.Infof("Couldn't get key for object %+v: %v", obj, err) return } lbc.queue.Add(key) } eventHandlers := framework.ResourceEventHandlerFuncs{ AddFunc: enqueue, DeleteFunc: enqueue, UpdateFunc: func(old, cur interface{}) { if !reflect.DeepEqual(old, cur) { enqueue(cur) } }, } lbc.svcLister.Store, lbc.svcController = framework.NewInformer( cache.NewListWatchFromClient( lbc.client, "services", namespace, fields.Everything()), &api.Service{}, resyncPeriod, eventHandlers) lbc.epLister.Store, lbc.epController = framework.NewInformer( cache.NewListWatchFromClient( lbc.client, "endpoints", namespace, fields.Everything()), &api.Endpoints{}, resyncPeriod, eventHandlers) return &lbc }
// newIPVSController creates a new controller from the given config. func newIPVSController(kubeClient *unversioned.Client, namespace string, useUnicast bool, configMapName string) *ipvsControllerController { ipvsc := ipvsControllerController{ client: kubeClient, reloadRateLimiter: util.NewTokenBucketRateLimiter(reloadQPS, int(reloadQPS)), ruCfg: []vip{}, configMapName: configMapName, } clusterNodes := getClusterNodesIP(kubeClient) nodeInfo, err := getNodeInfo(clusterNodes) if err != nil { glog.Fatalf("Error getting local IP from nodes in the cluster: %v", err) } neighbors := getNodeNeighbors(nodeInfo, clusterNodes) execer := exec.New() dbus := utildbus.New() iptInterface := utiliptables.New(execer, dbus, utiliptables.ProtocolIpv4) ipvsc.keepalived = &keepalived{ iface: nodeInfo.iface, ip: nodeInfo.ip, netmask: nodeInfo.netmask, nodes: clusterNodes, neighbors: neighbors, priority: getNodePriority(nodeInfo.ip, clusterNodes), useUnicast: useUnicast, ipt: iptInterface, } err = ipvsc.keepalived.loadTemplate() if err != nil { glog.Fatalf("Error loading keepalived template: %v", err) } eventHandlers := framework.ResourceEventHandlerFuncs{} ipvsc.svcLister.Store, ipvsc.svcController = framework.NewInformer( cache.NewListWatchFromClient( ipvsc.client, "services", namespace, fields.Everything()), &api.Service{}, resyncPeriod, eventHandlers) ipvsc.epLister.Store, ipvsc.epController = framework.NewInformer( cache.NewListWatchFromClient( ipvsc.client, "endpoints", namespace, fields.Everything()), &api.Endpoints{}, resyncPeriod, eventHandlers) return &ipvsc }
func newPodsApi(client *kclient.Client) podsApi { // Extend the selector to include specific nodes to monitor // or provide an API to update the nodes to monitor. selector, err := kSelector.ParseSelector("spec.nodeName!=") if err != nil { panic(err) } lw := kcache.NewListWatchFromClient(client, "pods", kapi.NamespaceAll, selector) podLister := &kcache.StoreToPodLister{Store: kcache.NewStore(kcache.MetaNamespaceKeyFunc)} // Watch and cache all running pods. reflector := kcache.NewReflector(lw, &kapi.Pod{}, podLister.Store, 0) stopChan := make(chan struct{}) reflector.RunUntil(stopChan) nStore, nController := kframework.NewInformer( createNamespaceLW(client), &kapi.Namespace{}, resyncPeriod, kframework.ResourceEventHandlerFuncs{}) go nController.Run(util.NeverStop) podsApi := &realPodsApi{ client: client, podLister: podLister, stopChan: stopChan, reflector: reflector, namespaceStore: nStore, } return podsApi }
func NewKubeletProvider(uri *url.URL) (MetricsSourceProvider, error) { // create clients kubeConfig, kubeletConfig, err := GetKubeConfigs(uri) if err != nil { return nil, err } kubeClient := kube_client.NewOrDie(kubeConfig) kubeletClient, err := NewKubeletClient(kubeletConfig) if err != nil { return nil, err } // Get nodes to test if the client is configured well. Watch gives less error information. if _, err := kubeClient.Nodes().List(kube_api.ListOptions{ LabelSelector: labels.Everything(), FieldSelector: fields.Everything()}); err != nil { glog.Errorf("Failed to load nodes: %v", err) } // watch nodes lw := cache.NewListWatchFromClient(kubeClient, "nodes", kube_api.NamespaceAll, fields.Everything()) nodeLister := &cache.StoreToNodeLister{Store: cache.NewStore(cache.MetaNamespaceKeyFunc)} reflector := cache.NewReflector(lw, &kube_api.Node{}, nodeLister.Store, time.Hour) reflector.Run() return &kubeletProvider{ nodeLister: nodeLister, reflector: reflector, kubeletClient: kubeletClient, }, nil }
// Run event queue for the given resource func (registry *Registry) RunEventQueue(resourceName ResourceName) *oscache.EventQueue { var client cache.Getter var expectedType interface{} switch resourceName { case HostSubnets: expectedType = &osapi.HostSubnet{} client = registry.oClient case NetNamespaces: expectedType = &osapi.NetNamespace{} client = registry.oClient case Nodes: expectedType = &kapi.Node{} client = registry.kClient case Namespaces: expectedType = &kapi.Namespace{} client = registry.kClient case Services: expectedType = &kapi.Service{} client = registry.kClient case Pods: expectedType = &kapi.Pod{} client = registry.kClient default: log.Fatalf("Unknown resource %s during initialization of event queue", resourceName) } lw := cache.NewListWatchFromClient(client, strings.ToLower(string(resourceName)), kapi.NamespaceAll, fields.Everything()) eventQueue := oscache.NewEventQueue(cache.MetaNamespaceKeyFunc) // Repopulate event queue every 30 mins // Existing items in the event queue will have watch.Modified event type cache.NewReflector(lw, expectedType, eventQueue, 30*time.Minute).Run() return eventQueue }
func getNodeLister(kubeClient *kube_client.Client) (*cache.StoreToNodeLister, error) { lw := cache.NewListWatchFromClient(kubeClient, "nodes", kube_api.NamespaceAll, fields.Everything()) nodeLister := &cache.StoreToNodeLister{Store: cache.NewStore(cache.MetaNamespaceKeyFunc)} reflector := cache.NewReflector(lw, &kube_api.Node{}, nodeLister.Store, time.Hour) reflector.Run() return nodeLister, nil }
// Run event queue for the given resource func (registry *Registry) runEventQueue(resourceName string) *oscache.EventQueue { var client cache.Getter var expectedType interface{} switch strings.ToLower(resourceName) { case "hostsubnets": expectedType = &osapi.HostSubnet{} client = registry.oClient case "netnamespaces": expectedType = &osapi.NetNamespace{} client = registry.oClient case "nodes": expectedType = &kapi.Node{} client = registry.kClient case "namespaces": expectedType = &kapi.Namespace{} client = registry.kClient case "services": expectedType = &kapi.Service{} client = registry.kClient case "pods": expectedType = &kapi.Pod{} client = registry.kClient default: log.Fatalf("Unknown resource %s during initialization of event queue", resourceName) } lw := cache.NewListWatchFromClient(client, strings.ToLower(resourceName), kapi.NamespaceAll, fields.Everything()) eventQueue := oscache.NewEventQueue(cache.MetaNamespaceKeyFunc) cache.NewReflector(lw, expectedType, eventQueue, 0).Run() return eventQueue }
func getPodLister(kubeClient *kube_client.Client) (*cache.StoreToPodLister, error) { lw := cache.NewListWatchFromClient(kubeClient, "pods", kube_api.NamespaceAll, fields.Everything()) store := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) podLister := &cache.StoreToPodLister{Indexer: store} reflector := cache.NewReflector(lw, &kube_api.Pod{}, store, time.Hour) reflector.Run() return podLister, nil }
// NewNodeLister builds a node lister. func NewNodeLister(kubeClient client.Interface) *ReadyNodeLister { listWatcher := cache.NewListWatchFromClient(kubeClient.Core().RESTClient(), "nodes", apiv1.NamespaceAll, fields.Everything()) nodeLister := &cache.StoreToNodeLister{Store: cache.NewStore(cache.MetaNamespaceKeyFunc)} reflector := cache.NewReflector(listWatcher, &apiv1.Node{}, nodeLister.Store, time.Hour) reflector.Run() return &ReadyNodeLister{ nodeLister: nodeLister, } }
// NewNodeLister builds a node lister. func NewNodeLister(kubeClient *kube_client.Client) *ReadyNodeLister { listWatcher := cache.NewListWatchFromClient(kubeClient, "nodes", kube_api.NamespaceAll, fields.Everything()) nodeLister := &cache.StoreToNodeLister{Store: cache.NewStore(cache.MetaNamespaceKeyFunc)} reflector := cache.NewReflector(listWatcher, &kube_api.Node{}, nodeLister.Store, time.Hour) reflector.Run() return &ReadyNodeLister{ nodeLister: nodeLister, } }
// newLoadBalancerController creates a new controller from the given config. func newLoadBalancerController(cfg *loadBalancerConfig, kubeClient *unversioned.Client, namespace string, tcpServices map[string]int) *loadBalancerController { lbc := loadBalancerController{ cfg: cfg, client: kubeClient, queue: workqueue.New(), reloadRateLimiter: util.NewTokenBucketRateLimiter( reloadQPS, int(reloadQPS)), targetService: *targetService, forwardServices: *forwardServices, httpPort: *httpPort, tcpServices: tcpServices, } enqueue := func(obj interface{}) { key, err := keyFunc(obj) if err != nil { glog.Infof("Couldn't get key for object %+v: %v", obj, err) return } lbc.queue.Add(key) } eventHandlers := framework.ResourceEventHandlerFuncs{ AddFunc: enqueue, DeleteFunc: enqueue, UpdateFunc: func(old, cur interface{}) { if !reflect.DeepEqual(old, cur) { enqueue(cur) } }, } lbc.svcLister.Store, lbc.svcController = framework.NewInformer( cache.NewListWatchFromClient( lbc.client, "services", namespace, fields.Everything()), &api.Service{}, resyncPeriod, eventHandlers) lbc.epLister.Store, lbc.epController = framework.NewInformer( cache.NewListWatchFromClient( lbc.client, "endpoints", namespace, fields.Everything()), &api.Endpoints{}, resyncPeriod, eventHandlers) return &lbc }
// Run starts a background goroutine that watches for changes to services that // have (or had) LoadBalancers=true and ensures that they have // load balancers created and deleted appropriately. // serviceSyncPeriod controls how often we check the cluster's services to // ensure that the correct load balancers exist. // nodeSyncPeriod controls how often we check the cluster's nodes to determine // if load balancers need to be updated to point to a new set. // // It's an error to call Run() more than once for a given ServiceController // object. func (s *ServiceController) Run(workers int) { defer runtime.HandleCrash() go s.serviceController.Run(wait.NeverStop) for i := 0; i < workers; i++ { go wait.Until(s.worker, time.Second, wait.NeverStop) } nodeLW := cache.NewListWatchFromClient(s.kubeClient.Core().RESTClient(), "nodes", v1.NamespaceAll, fields.Everything()) cache.NewReflector(nodeLW, &v1.Node{}, s.nodeLister.Store, 0).Run() go wait.Until(s.nodeSyncLoop, nodeSyncPeriod, wait.NeverStop) }
// NewCachedServiceAccessor returns a service accessor that can answer queries about services. // It uses a backing cache to make ClusterIP lookups efficient. func NewCachedServiceAccessor(client cache.Getter, stopCh <-chan struct{}) ServiceAccessor { accessor, store := NewCachedServiceAccessorAndStore() lw := cache.NewListWatchFromClient(client, "services", api.NamespaceAll, fields.Everything()) reflector := cache.NewReflector(lw, &api.Service{}, store, 30*time.Minute) if stopCh != nil { reflector.RunUntil(stopCh) } else { reflector.Run() } return accessor }
// NewClient returns a usable Client. Don't forget to Stop it. func NewClient(addr string, resyncPeriod time.Duration) (Client, error) { var config *unversioned.Config if addr != "" { config = &unversioned.Config{Host: addr} } else { // If no API server address was provided, assume we are running // inside a pod. Try to connect to the API server through its // Service environment variables, using the default Service // Account Token. var err error if config, err = unversioned.InClusterConfig(); err != nil { return nil, err } } c, err := unversioned.New(config) if err != nil { return nil, err } podListWatch := cache.NewListWatchFromClient(c, "pods", api.NamespaceAll, fields.Everything()) podStore := cache.NewStore(cache.MetaNamespaceKeyFunc) podReflector := cache.NewReflector(podListWatch, &api.Pod{}, podStore, resyncPeriod) serviceListWatch := cache.NewListWatchFromClient(c, "services", api.NamespaceAll, fields.Everything()) serviceStore := cache.NewStore(cache.MetaNamespaceKeyFunc) serviceReflector := cache.NewReflector(serviceListWatch, &api.Service{}, serviceStore, resyncPeriod) quit := make(chan struct{}) runReflectorUntil(podReflector, resyncPeriod, quit) runReflectorUntil(serviceReflector, resyncPeriod, quit) return &client{ quit: quit, client: c, podReflector: podReflector, podStore: &cache.StoreToPodLister{Store: podStore}, serviceReflector: serviceReflector, serviceStore: &cache.StoreToServiceLister{Store: serviceStore}, }, nil }
// Run event queue for the given resource. The 'process' function is called // repeatedly with each available cache.Delta that describes state changes // to an object. If the process function returns an error queued changes // for that object are dropped but processing continues with the next available // object's cache.Deltas. The error is logged with call stack information. func runEventQueueForResource(client kcache.Getter, resourceName ResourceName, expectedType interface{}, selector fields.Selector, process ProcessEventFunc) { rn := strings.ToLower(string(resourceName)) lw := kcache.NewListWatchFromClient(client, rn, kapi.NamespaceAll, selector) eventQueue := NewEventQueue(kcache.MetaNamespaceKeyFunc) // Repopulate event queue every 30 mins // Existing items in the event queue will have watch.Modified event type kcache.NewReflector(lw, expectedType, eventQueue, 30*time.Minute).Run() // Run the queue for { eventQueue.Pop(process) } }
// NewUnscheduledPodLister returns a lister providing pods that failed to be scheduled. func NewUnscheduledPodLister(kubeClient *kube_client.Client) *UnscheduledPodLister { // watch unscheduled pods selector := fields.ParseSelectorOrDie("spec.nodeName==" + "" + ",status.phase!=" + string(kube_api.PodSucceeded) + ",status.phase!=" + string(kube_api.PodFailed)) podListWatch := cache.NewListWatchFromClient(kubeClient, "pods", kube_api.NamespaceAll, selector) podLister := &cache.StoreToPodLister{Store: cache.NewStore(cache.MetaNamespaceKeyFunc)} podReflector := cache.NewReflector(podListWatch, &kube_api.Pod{}, podLister.Store, time.Hour) podReflector.Run() return &UnscheduledPodLister{ podLister: podLister, } }
// NewUnschedulablePodLister returns a lister providing pods that failed to be scheduled. func NewUnschedulablePodLister(kubeClient *kube_client.Client, namespace string) *UnschedulablePodLister { // watch unscheduled pods selector := fields.ParseSelectorOrDie("spec.nodeName==" + "" + ",status.phase!=" + string(kube_api.PodSucceeded) + ",status.phase!=" + string(kube_api.PodFailed)) podListWatch := cache.NewListWatchFromClient(kubeClient, "pods", namespace, selector) store := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) podLister := &cache.StoreToPodLister{store} podReflector := cache.NewReflector(podListWatch, &kube_api.Pod{}, store, time.Hour) podReflector.Run() return &UnschedulablePodLister{ podLister: podLister, } }
// NewScheduledPodLister builds ScheduledPodLister func NewScheduledPodLister(kubeClient client.Interface) *ScheduledPodLister { // watch unscheduled pods selector := fields.ParseSelectorOrDie("spec.nodeName!=" + "" + ",status.phase!=" + string(apiv1.PodSucceeded) + ",status.phase!=" + string(apiv1.PodFailed)) podListWatch := cache.NewListWatchFromClient(kubeClient.Core().RESTClient(), "pods", apiv1.NamespaceAll, selector) store := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) podLister := &cache.StoreToPodLister{store} podReflector := cache.NewReflector(podListWatch, &apiv1.Pod{}, store, time.Hour) podReflector.Run() return &ScheduledPodLister{ podLister: podLister, } }
// Run starts a background goroutine that watches for changes to services that // have (or had) LoadBalancers=true and ensures that they have // load balancers created and deleted appropriately. // serviceSyncPeriod controls how often we check the cluster's services to // ensure that the correct load balancers exist. // nodeSyncPeriod controls how often we check the cluster's nodes to determine // if load balancers need to be updated to point to a new set. // // It's an error to call Run() more than once for a given ServiceController // object. func (s *ServiceController) Run(serviceSyncPeriod, nodeSyncPeriod time.Duration) error { if err := s.init(); err != nil { return err } // We have to make this check because the ListWatch that we use in // WatchServices requires Client functions that aren't in the interface // for some reason. if _, ok := s.kubeClient.(*clientset.Clientset); !ok { return fmt.Errorf("ServiceController only works with real Client objects, but was passed something else satisfying the clientset.Interface.") } // Get the currently existing set of services and then all future creates // and updates of services. // A delta compressor is needed for the DeltaFIFO queue because we only ever // care about the most recent state. serviceQueue := cache.NewDeltaFIFO( cache.MetaNamespaceKeyFunc, cache.DeltaCompressorFunc(func(d cache.Deltas) cache.Deltas { if len(d) == 0 { return d } return cache.Deltas{*d.Newest()} }), s.cache, ) lw := cache.NewListWatchFromClient(s.kubeClient.(*clientset.Clientset).CoreClient, "services", api.NamespaceAll, fields.Everything()) cache.NewReflector(lw, &api.Service{}, serviceQueue, serviceSyncPeriod).Run() for i := 0; i < workerGoroutines; i++ { go s.watchServices(serviceQueue) } nodeLW := cache.NewListWatchFromClient(s.kubeClient.(*clientset.Clientset).CoreClient, "nodes", api.NamespaceAll, fields.Everything()) cache.NewReflector(nodeLW, &api.Node{}, s.nodeLister.Store, 0).Run() go s.nodeSyncLoop(nodeSyncPeriod) return nil }
func getPodLister(url *url.URL) (*cache.StoreToPodLister, error) { kubeConfig, err := kube_config.GetKubeClientConfig(url) if err != nil { return nil, err } kubeClient := kube_client.NewOrDie(kubeConfig) lw := cache.NewListWatchFromClient(kubeClient, "pods", kube_api.NamespaceAll, fields.Everything()) store := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) podLister := &cache.StoreToPodLister{Indexer: store} reflector := cache.NewReflector(lw, &kube_api.Pod{}, store, time.Hour) reflector.Run() return podLister, nil }
// RunServiceStores retrieves service info from the master, and closes the // ServicesReady channel when done. func (c *NodeConfig) RunServiceStores(enableProxy, enableDNS bool) { if !enableProxy && !enableDNS { close(c.ServicesReady) return } serviceList := cache.NewListWatchFromClient(c.Client, "services", kapi.NamespaceAll, fields.Everything()) serviceReflector := cache.NewReflector(serviceList, &kapi.Service{}, c.ServiceStore, c.ProxyConfig.ConfigSyncPeriod) serviceReflector.Run() if enableProxy { endpointList := cache.NewListWatchFromClient(c.Client, "endpoints", kapi.NamespaceAll, fields.Everything()) endpointReflector := cache.NewReflector(endpointList, &kapi.Endpoints{}, c.EndpointsStore, c.ProxyConfig.ConfigSyncPeriod) endpointReflector.Run() for len(endpointReflector.LastSyncResourceVersion()) == 0 { time.Sleep(100 * time.Millisecond) } } for len(serviceReflector.LastSyncResourceVersion()) == 0 { time.Sleep(100 * time.Millisecond) } close(c.ServicesReady) }
// Run runs the specified KubeletExecutorServer. func (s *KubeletExecutorServer) Run(hks hyperkube.Interface, _ []string) error { // create shared channels kubeletFinished := make(chan struct{}) nodeInfos := make(chan executor.NodeInfo, 1) // create static pods directory staticPodsConfigPath := filepath.Join(s.RootDirectory, "static-pods") err := os.Mkdir(staticPodsConfigPath, 0750) if err != nil { return err } // we're expecting that either Mesos or the minion process will set this for us s.containerID = os.Getenv(envContainerID) if s.containerID == "" { log.Warningf("missing expected environment variable %q", envContainerID) } // create apiserver client var apiclient *clientset.Clientset clientConfig, err := kubeletapp.CreateAPIServerClientConfig(s.KubeletServer) if err == nil { apiclient, err = clientset.NewForConfig(clientConfig) } if err != nil { // required for k8sm since we need to send api.Binding information back to the apiserver return fmt.Errorf("cannot create API client: %v", err) } var ( pw = cache.NewListWatchFromClient(apiclient.CoreClient, "pods", api.NamespaceAll, fields.OneTermEqualSelector(client.PodHost, s.HostnameOverride), ) reg = executor.NewRegistry(apiclient) ) // start executor var executorDone <-chan struct{} executorDone, err = s.runExecutor(nodeInfos, kubeletFinished, staticPodsConfigPath, apiclient, reg) if err != nil { return err } // start kubelet, blocking return s.runKubelet(nodeInfos, kubeletFinished, staticPodsConfigPath, apiclient, pw, reg, executorDone) }
// NewCachedServiceAccessor returns a service accessor that can answer queries about services. // It uses a backing cache to make PortalIP lookups efficient. func NewCachedServiceAccessor(client *client.Client, stopCh <-chan struct{}) ServiceAccessor { lw := cache.NewListWatchFromClient(client, "services", api.NamespaceAll, fields.Everything()) store := cache.NewIndexer(cache.MetaNamespaceKeyFunc, map[string]cache.IndexFunc{ "portalIP": indexServiceByPortalIP, // for reverse lookups "namespace": cache.MetaNamespaceIndexFunc, }) reflector := cache.NewReflector(lw, &api.Service{}, store, 2*time.Minute) if stopCh != nil { reflector.RunUntil(stopCh) } else { reflector.Run() } return &cachedServiceAccessor{ reflector: reflector, store: store, } }
func (u *StatusUpdater) Run(terminate <-chan struct{}) error { nodeStore := cache.NewStore(cache.MetaNamespaceKeyFunc) nodeLW := cache.NewListWatchFromClient(u.client, "nodes", api.NamespaceAll, fields.Everything()) cache.NewReflector(nodeLW, &api.Node{}, nodeStore, u.relistPeriod).Run() monitor := func() { // build up a slave set of nodes without kubelet slavesWithoutKubeletList, err := mesos.CloudProvider.ListWithoutKubelet() if err != nil { log.Errorf("Error while updating slave nodes: %v", err) return } slavesWithoutKubelet := make(map[string]struct{}, len(slavesWithoutKubeletList)) for _, s := range slavesWithoutKubeletList { slavesWithoutKubelet[s] = struct{}{} } // update status for nodes which do not have a kubelet running and // which are still existing as slave. This status update must be done // before the node controller counts down the NodeMonitorGracePeriod obj, err := nodeLW.List() if err != nil { log.Errorf("Error listing the nodes for status updates: %v", err) } nl, _ := obj.(*api.NodeList) nodes := nl.Items for i := range nodes { if _, ok := slavesWithoutKubelet[nodes[i].Spec.ExternalID]; !ok { // let the kubelet do its job updating the status, or the // node controller will remove this node if the node does not even // exist anymore continue } err := u.updateStatus(&nodes[i]) if err != nil { log.Errorf("Error updating node status: %v", err) } } } go runtime.Until(monitor, u.heartBeatPeriod, terminate) return nil }
func NewNodeAutoscalingEnricher(url *url.URL) (*NodeAutoscalingEnricher, error) { kubeConfig, err := kube_config.GetKubeClientConfig(url) if err != nil { return nil, err } kubeClient := kube_client.NewOrDie(kubeConfig) // watch nodes lw := cache.NewListWatchFromClient(kubeClient, "nodes", kube_api.NamespaceAll, fields.Everything()) nodeLister := &cache.StoreToNodeLister{Store: cache.NewStore(cache.MetaNamespaceKeyFunc)} reflector := cache.NewReflector(lw, &kube_api.Node{}, nodeLister.Store, time.Hour) reflector.Run() return &NodeAutoscalingEnricher{ nodeLister: nodeLister, reflector: reflector, }, nil }
func NewNamespaceBasedEnricher(url *url.URL) (*NamespaceBasedEnricher, error) { kubeConfig, err := kube_config.GetKubeClientConfig(url) if err != nil { return nil, err } kubeClient := kube_client.NewOrDie(kubeConfig) // watch nodes lw := cache.NewListWatchFromClient(kubeClient, "namespaces", kube_api.NamespaceAll, fields.Everything()) store := cache.NewStore(cache.MetaNamespaceKeyFunc) reflector := cache.NewReflector(lw, &kube_api.Namespace{}, store, time.Hour) reflector.Run() return &NamespaceBasedEnricher{ store: store, reflector: reflector, }, nil }