func (s activePods) Less(i, j int) bool { // Unassigned < assigned if s[i].Spec.NodeName == "" && s[j].Spec.NodeName != "" { return true } // PodPending < PodUnknown < PodRunning m := map[api.PodPhase]int{api.PodPending: 0, api.PodUnknown: 1, api.PodRunning: 2} if m[s[i].Status.Phase] != m[s[j].Status.Phase] { return m[s[i].Status.Phase] < m[s[j].Status.Phase] } // Not ready < ready if !api.IsPodReady(s[i]) && api.IsPodReady(s[j]) { return true } return false }
func checkExistingRCRecovers(f Framework) { By("assert that the pre-existing replication controller recovers") podClient := f.Client.Pods(f.Namespace.Name) rcSelector := labels.Set{"name": "baz"}.AsSelector() By("deleting pods from existing replication controller") expectNoError(wait.Poll(time.Millisecond*500, time.Second*30, func() (bool, error) { pods, err := podClient.List(rcSelector, fields.Everything()) Expect(err).NotTo(HaveOccurred()) if len(pods.Items) == 0 { return false, nil } for _, pod := range pods.Items { err = podClient.Delete(pod.Name, api.NewDeleteOptions(0)) Expect(err).NotTo(HaveOccurred()) } return true, nil })) By("waiting for replication controller to recover") expectNoError(wait.Poll(time.Millisecond*500, time.Second*30, func() (bool, error) { pods, err := podClient.List(rcSelector, fields.Everything()) Expect(err).NotTo(HaveOccurred()) for _, pod := range pods.Items { if api.IsPodReady(&pod) { return true, nil } } return false, nil })) }
// Accept implements UpdateAcceptor. func (c *AcceptNewlyObservedReadyPods) Accept(deployment *kapi.ReplicationController) error { // Make a pod store to poll and ensure it gets cleaned up. podStore, stopStore := c.getDeploymentPodStore(deployment) defer close(stopStore) // Start checking for pod updates. glog.V(0).Infof("Waiting %.f seconds for pods owned by deployment %q to become ready (checking every %.f seconds; %d pods previously accepted)", c.timeout.Seconds(), deployutil.LabelForDeployment(deployment), c.interval.Seconds(), c.acceptedPods.Len()) err := wait.Poll(c.interval, c.timeout, func() (done bool, err error) { // Check for pod readiness. unready := kutil.NewStringSet() for _, obj := range podStore.List() { pod := obj.(*kapi.Pod) // Skip previously accepted pods; we only want to verify newly observed // and unaccepted pods. if c.acceptedPods.Has(pod.Name) { continue } if kapi.IsPodReady(pod) { // If the pod is ready, track it as accepted. c.acceptedPods.Insert(pod.Name) } else { // Otherwise, track it as unready. unready.Insert(pod.Name) } } // Check to see if we're done. if unready.Len() == 0 { glog.V(0).Infof("All pods ready for %s", deployutil.LabelForDeployment(deployment)) return true, nil } // Otherwise, try again later. glog.V(4).Infof("Still waiting for %d pods to become ready for deployment %s", unready.Len(), deployutil.LabelForDeployment(deployment)) return false, nil }) // Handle acceptance failure. if err != nil { if err == wait.ErrWaitTimeout { return fmt.Errorf("pods for deployment %q took longer than %.f seconds to become ready", deployutil.LabelForDeployment(deployment), c.timeout.Seconds()) } return fmt.Errorf("pod readiness check failed for deployment %q: %v", deployutil.LabelForDeployment(deployment), err) } return nil }
func (e *EndpointController) syncService(key string) { startTime := time.Now() defer func() { glog.V(4).Infof("Finished syncing service %q endpoints. (%v)", key, time.Now().Sub(startTime)) }() obj, exists, err := e.serviceStore.Store.GetByKey(key) if err != nil || !exists { // Delete the corresponding endpoint, as the service has been deleted. // TODO: Please note that this will delete an endpoint when a // service is deleted. However, if we're down at the time when // the service is deleted, we will miss that deletion, so this // doesn't completely solve the problem. See #6877. namespace, name, err := cache.SplitMetaNamespaceKey(key) if err != nil { glog.Errorf("Need to delete endpoint with key %q, but couldn't understand the key: %v", key, err) // Don't retry, as the key isn't going to magically become understandable. return } err = e.client.Endpoints(namespace).Delete(name) if err != nil && !errors.IsNotFound(err) { glog.Errorf("Error deleting endpoint %q: %v", key, err) e.queue.Add(key) // Retry } return } service := obj.(*api.Service) if service.Spec.Selector == nil { // services without a selector receive no endpoints from this controller; // these services will receive the endpoints that are created out-of-band via the REST API. return } glog.V(5).Infof("About to update endpoints for service %q", key) pods, err := e.podStore.Pods(service.Namespace).List(labels.Set(service.Spec.Selector).AsSelector()) if err != nil { // Since we're getting stuff from a local cache, it is // basically impossible to get this error. glog.Errorf("Error syncing service %q: %v", key, err) e.queue.Add(key) // Retry return } subsets := []api.EndpointSubset{} for i := range pods.Items { pod := &pods.Items[i] for i := range service.Spec.Ports { servicePort := &service.Spec.Ports[i] // TODO: Once v1beta1 and v1beta2 are EOL'ed, // this can safely assume that TargetPort is // populated, and findPort() can be removed. _ = v1beta1.Dependency _ = v1beta2.Dependency portName := servicePort.Name portProto := servicePort.Protocol portNum, err := findPort(pod, servicePort) if err != nil { glog.Errorf("Failed to find port for service %s/%s: %v", service.Namespace, service.Name, err) continue } if len(pod.Status.PodIP) == 0 { glog.Errorf("Failed to find an IP for pod %s/%s", pod.Namespace, pod.Name) continue } if !api.IsPodReady(pod) { glog.V(5).Infof("Pod is out of service: %v/%v", pod.Namespace, pod.Name) continue } epp := api.EndpointPort{Name: portName, Port: portNum, Protocol: portProto} epa := api.EndpointAddress{IP: pod.Status.PodIP, TargetRef: &api.ObjectReference{ Kind: "Pod", Namespace: pod.ObjectMeta.Namespace, Name: pod.ObjectMeta.Name, UID: pod.ObjectMeta.UID, ResourceVersion: pod.ObjectMeta.ResourceVersion, }} subsets = append(subsets, api.EndpointSubset{Addresses: []api.EndpointAddress{epa}, Ports: []api.EndpointPort{epp}}) } } subsets = endpoints.RepackSubsets(subsets) // See if there's actually an update here. currentEndpoints, err := e.client.Endpoints(service.Namespace).Get(service.Name) if err != nil { if errors.IsNotFound(err) { currentEndpoints = &api.Endpoints{ ObjectMeta: api.ObjectMeta{ Name: service.Name, Labels: service.Labels, }, } } else { glog.Errorf("Error getting endpoints: %v", err) e.queue.Add(key) // Retry return } } if reflect.DeepEqual(currentEndpoints.Subsets, subsets) && reflect.DeepEqual(currentEndpoints.Labels, service.Labels) { glog.V(5).Infof("endpoints are equal for %s/%s, skipping update", service.Namespace, service.Name) return } newEndpoints := currentEndpoints newEndpoints.Subsets = subsets newEndpoints.Labels = service.Labels if len(currentEndpoints.ResourceVersion) == 0 { // No previous endpoints, create them _, err = e.client.Endpoints(service.Namespace).Create(newEndpoints) } else { // Pre-existing _, err = e.client.Endpoints(service.Namespace).Update(newEndpoints) } if err != nil { glog.Errorf("Error updating endpoints: %v", err) e.queue.Add(key) // Retry } }
podClient = framework.Client.Pods(framework.Namespace.Name) }) AfterEach(framework.afterEach) It("with readiness probe should not be ready before initial delay and never restart", func() { p, err := podClient.Create(makePodSpec(probe.withInitialDelay().build(), nil)) expectNoError(err) startTime := time.Now() Expect(wait.Poll(poll, 90*time.Second, func() (bool, error) { p, err := podClient.Get(p.Name) if err != nil { return false, err } ready := api.IsPodReady(p) if !ready { Logf("pod is not yet ready; pod has phase %q.", p.Status.Phase) return false, nil } return true, nil })).NotTo(HaveOccurred(), "pod never became ready") if time.Since(startTime) < 30*time.Second { Failf("Pod became ready before it's initial delay") } p, err = podClient.Get(p.Name) expectNoError(err) isReady, err := podRunningReady(p)
podClient = framework.Client.Pods(framework.Namespace.Name) }) AfterEach(framework.afterEach) It("with readiness probe should not be ready before initial delay and never restart", func() { p, err := podClient.Create(makePodSpec(probe.withInitialDelay().build(), nil)) expectNoError(err) startTime := time.Now() expectNoError(wait.Poll(poll, 90*time.Second, func() (bool, error) { p, err := podClient.Get(p.Name) if err != nil { return false, err } return api.IsPodReady(p), nil })) if time.Since(startTime) < 30*time.Second { Failf("Pod became ready before it's initial delay") } p, err = podClient.Get(p.Name) expectNoError(err) isReady, err := podRunningReady(p) expectNoError(err) Expect(isReady).To(BeTrue()) Expect(getRestartCount(p) == 0).To(BeTrue()) })