// 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) }
// Run starts a background goroutine that watches for changes to services that // have (or had) externalLoadBalancers=true and ensures that they have external // load balancers created and deleted appropriately. // nodeSyncPeriod controls how often we check the cluster's nodes to determine // if external load balancers need to be updated to point to a new set. func (s *ServiceController) Run(nodeSyncPeriod time.Duration) error { if err := s.init(); err != nil { return err } // We have to make this check beecause the ListWatch that we use in // WatchServices requires Client functions that aren't in the interface // for some reason. if _, ok := s.kubeClient.(*client.Client); !ok { return fmt.Errorf("ServiceController only works with real Client objects, but was passed something else satisfying the client Interface.") } // Get the currently existing set of services and then all future creates // and updates of services. // No delta compressor is needed for the DeltaFIFO queue because we only ever // care about the most recent state. serviceQueue := cache.NewDeltaFIFO(cache.MetaNamespaceKeyFunc, nil, s.cache) lw := cache.NewListWatchFromClient(s.kubeClient.(*client.Client), "services", api.NamespaceAll, fields.Everything()) cache.NewReflector(lw, &api.Service{}, serviceQueue, 0).Run() for i := 0; i < workerGoroutines; i++ { go s.watchServices(serviceQueue) } nodeLister := &cache.StoreToNodeLister{cache.NewStore(cache.MetaNamespaceKeyFunc)} nodeLW := cache.NewListWatchFromClient(s.kubeClient.(*client.Client), "nodes", api.NamespaceAll, fields.Everything()) cache.NewReflector(nodeLW, &api.Node{}, nodeLister.Store, 0).Run() go s.nodeSyncLoop(nodeLister, nodeSyncPeriod) return nil }
// newLoadBalancerController creates a new controller from the given config. func newLoadBalancerController(cfg *loadBalancerConfig, kubeClient *client.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 }
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 }
// 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 NewKubeNodes(client *client.Client) (NodesApi, error) { if client == nil { return nil, fmt.Errorf("client is nil") } lw := cache.NewListWatchFromClient(client, "minions", api.NamespaceAll, fields.Everything()) nodeLister := &cache.StoreToNodeLister{Store: cache.NewStore(cache.MetaNamespaceKeyFunc)} reflector := cache.NewReflector(lw, &api.Node{}, nodeLister.Store, 0) stopChan := make(chan struct{}) reflector.RunUntil(stopChan) return &kubeNodes{ client: client, nodeLister: nodeLister, reflector: reflector, stopChan: stopChan, nodeErrors: make(map[string]int), }, nil }
func newPodsApi(client *client.Client) podsApi { // Extend the selector to include specific nodes to monitor // or provide an API to update the nodes to monitor. selector, err := fields.ParseSelector("DesiredState.Host!=") if err != nil { panic(err) } lw := cache.NewListWatchFromClient(client, "pods", kube_api.NamespaceAll, selector) podLister := &cache.StoreToPodLister{Store: cache.NewStore(cache.MetaNamespaceKeyFunc)} // Watch and cache all running pods. reflector := cache.NewReflector(lw, &kube_api.Pod{}, podLister.Store, 0) stopChan := make(chan struct{}) reflector.RunUntil(stopChan) podsApi := &realPodsApi{ client: client, podLister: podLister, stopChan: stopChan, reflector: reflector, } return podsApi }
// Returns a cache.ListWatch that finds all pods that need to be // scheduled. func (factory *ConfigFactory) createUnassignedPodLW() *cache.ListWatch { return cache.NewListWatchFromClient(factory.Client, "pods", api.NamespaceAll, fields.Set{client.PodHost: ""}.AsSelector()) }
// Returns a cache.ListWatch that gets all changes to controllers. func (factory *ConfigFactory) createControllerLW() *cache.ListWatch { return cache.NewListWatchFromClient(factory.Client, "replicationControllers", api.NamespaceAll, parseSelectorOrDie("")) }
func createNamespaceLW(kubeClient *kclient.Client) *kcache.ListWatch { return kcache.NewListWatchFromClient(kubeClient, "namespaces", kapi.NamespaceAll, kSelector.Everything()) }
// createMinionLW returns a cache.ListWatch that gets all changes to minions. func (factory *ConfigFactory) createMinionLW() *cache.ListWatch { // TODO: Filter out nodes that doesn't have NodeReady condition. fields := fields.Set{client.NodeUnschedulable: "false"}.AsSelector() return cache.NewListWatchFromClient(factory.Client, "nodes", api.NamespaceAll, fields) }
// Returns a cache.ListWatch that gets all changes to services. func (factory *ConfigFactory) createServiceLW() *cache.ListWatch { return cache.NewListWatchFromClient(factory.Client, "services", api.NamespaceAll, parseSelectorOrDie("")) }
// Returns a cache.ListWatch that finds all pods that are // already scheduled. // TODO: return a ListerWatcher interface instead? func (factory *ConfigFactory) createAssignedPodLW() *cache.ListWatch { return cache.NewListWatchFromClient(factory.Client, "pods", api.NamespaceAll, parseSelectorOrDie(client.PodHost+"!=")) }
// Returns a cache.ListWatch that finds all pods that need to be // scheduled. func (factory *ConfigFactory) createUnassignedPodLW() *cache.ListWatch { return cache.NewListWatchFromClient(factory.Client, "pods", api.NamespaceAll, fields.Set{getHostFieldLabel(factory.Client.APIVersion()): ""}.AsSelector()) }
// createAllPodsLW returns a listWatch that finds all pods func createAllPodsLW(cl *client.Client) *cache.ListWatch { return cache.NewListWatchFromClient(cl, "pods", api.NamespaceAll, parseSelectorOrDie("")) }
// Returns a cache.ListWatch that finds all pods that are // already scheduled. // TODO: return a ListerWatcher interface instead? func (factory *ConfigFactory) createAssignedPodLW() *cache.ListWatch { return cache.NewListWatchFromClient(factory.Client, "pods", api.NamespaceAll, parseSelectorOrDie(getHostFieldLabel(factory.Client.APIVersion())+"!=")) }
// NewSourceApiserver creates a config source that watches and pulls from the apiserver. func NewSourceApiserver(client *client.Client, hostname string, updates chan<- interface{}) { lw := cache.NewListWatchFromClient(client, "pods", api.NamespaceAll, fields.OneTermEqualSelector(getHostFieldLabel(client.APIVersion()), hostname)) newSourceApiserverFromLW(lw, updates) }
// NewSourceApiserver creates a config source that watches and pulls from the apiserver. func NewSourceApiserver(c *client.Client, hostname string, updates chan<- interface{}) { lw := cache.NewListWatchFromClient(c, "pods", api.NamespaceAll, fields.OneTermEqualSelector(client.PodHost, hostname)) newSourceApiserverFromLW(lw, updates) }
func (m *NetworkManager) start(args []string) { config := &client.Config{ Host: m.config.KubeUrl, } var err error m.Client, err = client.New(config) if err != nil { glog.Fatalf("Invalid API configuratin: %v", err) } m.Controller = network.NewNetworkFactory().Create(m.Client, args) m.PodStore, m.PodInformer = framework.NewInformer( cache.NewListWatchFromClient( m.Client, string(api.ResourcePods), api.NamespaceAll, fields.Everything(), ), &api.Pod{}, m.config.ResyncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { m.Controller.AddPod(obj.(*api.Pod)) }, UpdateFunc: func(oldObj, newObj interface{}) { m.Controller.UpdatePod( oldObj.(*api.Pod), newObj.(*api.Pod)) }, DeleteFunc: func(obj interface{}) { if pod, ok := obj.(*api.Pod); ok { m.Controller.DeletePod(pod) } }, }, ) m.NamespaceStore, m.NamespaceInformer = framework.NewInformer( cache.NewListWatchFromClient( m.Client, "namespaces", api.NamespaceAll, fields.Everything(), ), &api.Namespace{}, m.config.ResyncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { m.Controller.AddNamespace( obj.(*api.Namespace)) }, UpdateFunc: func(oldObj, newObj interface{}) { m.Controller.UpdateNamespace( oldObj.(*api.Namespace), newObj.(*api.Namespace)) }, DeleteFunc: func(obj interface{}) { if namespace, ok := obj.(*api.Namespace); ok { m.Controller.DeleteNamespace(namespace) } }, }, ) m.RCStore, m.RCInformer = framework.NewInformer( cache.NewListWatchFromClient( m.Client, string(api.ResourceReplicationControllers), api.NamespaceAll, fields.Everything(), ), &api.ReplicationController{}, m.config.ResyncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { m.Controller.AddReplicationController( obj.(*api.ReplicationController)) }, UpdateFunc: func(oldObj, newObj interface{}) { m.Controller.UpdateReplicationController( oldObj.(*api.ReplicationController), newObj.(*api.ReplicationController)) }, DeleteFunc: func(obj interface{}) { if rc, ok := obj.(*api.ReplicationController); ok { m.Controller.DeleteReplicationController(rc) } }, }, ) m.ServiceStore, m.ServiceInformer = framework.NewInformer( cache.NewListWatchFromClient( m.Client, string(api.ResourceServices), api.NamespaceAll, fields.Everything(), ), &api.Service{}, m.config.ResyncPeriod, framework.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { m.Controller.AddService( obj.(*api.Service)) }, UpdateFunc: func(oldObj, newObj interface{}) { m.Controller.UpdateService( oldObj.(*api.Service), newObj.(*api.Service)) }, DeleteFunc: func(obj interface{}) { if service, ok := obj.(*api.Service); ok { m.Controller.DeleteService(service) } }, }, ) m.Controller.SetPodStore(m.PodStore) m.Controller.SetNamespaceStore(m.NamespaceStore) m.Controller.SetReplicationControllerStore(m.RCStore) m.Controller.SetServiceStore(m.ServiceStore) }