github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/edge/pkg/edged/status/status_manager.go (about) 1 package status 2 3 import ( 4 "time" 5 6 "k8s.io/api/core/v1" 7 apiequality "k8s.io/apimachinery/pkg/api/equality" 8 "k8s.io/apimachinery/pkg/types" 9 "k8s.io/apimachinery/pkg/util/wait" 10 clientset "k8s.io/client-go/kubernetes" 11 "k8s.io/klog" 12 "k8s.io/kubernetes/pkg/kubelet/status" 13 14 edgeapi "github.com/kubeedge/kubeedge/common/types" 15 "github.com/kubeedge/kubeedge/edge/pkg/edged/podmanager" 16 "github.com/kubeedge/kubeedge/edge/pkg/metamanager/client" 17 ) 18 19 // manager as status manager, embedded a k8s.io/kubernetes/pkg/kubelet/status.Manager 20 // inherit it's method but refactored Start() function to periodicity update status to IEF 21 type manager struct { 22 status.Manager 23 // TODO: consider need lock? 24 podManager podmanager.Manager 25 apiStatusVersions map[types.UID]*v1.PodStatus 26 metaClient client.CoreInterface 27 } 28 29 //NewManager creates and returns a new manager object 30 func NewManager(kubeClient clientset.Interface, podManager podmanager.Manager, podDeletionSafety status.PodDeletionSafetyProvider, metaClient client.CoreInterface) status.Manager { 31 kubeManager := status.NewManager(kubeClient, podManager, podDeletionSafety) 32 return &manager{ 33 Manager: kubeManager, 34 metaClient: metaClient, 35 podManager: podManager, 36 apiStatusVersions: make(map[types.UID]*v1.PodStatus), 37 } 38 } 39 40 const syncPeriod = 10 * time.Second 41 42 func (m *manager) Start() { 43 klog.Info("Starting to sync pod status with apiserver") 44 syncTicker := time.Tick(syncPeriod) 45 46 go wait.Forever(func() { 47 select { 48 case <-syncTicker: 49 m.updatePodStatus() 50 } 51 }, 0) 52 } 53 54 func (m *manager) updatePodStatus() { 55 for _, pod := range m.podManager.GetPods() { 56 uid := pod.UID 57 podStatus, ok := m.GetPodStatus(uid) 58 if !ok { 59 continue 60 } 61 latestStatus, ok := m.apiStatusVersions[uid] 62 if ok && apiequality.Semantic.DeepEqual(latestStatus, &podStatus) { 63 continue 64 } 65 s := *podStatus.DeepCopy() 66 var conditionFlag bool 67 podCondition := v1.PodCondition{Type: v1.PodReady, Status: v1.ConditionFalse, Reason: "ContainersNotReady"} 68 for idx, cs := range podStatus.ContainerStatuses { 69 if cs.State.Running != nil && cs.State.Running.StartedAt.Unix() == 0 { 70 newState := v1.ContainerState{Waiting: &v1.ContainerStateWaiting{ 71 Reason: "CrashLoopBackOff", 72 Message: "Container restarting in container runtime", 73 }} 74 s.ContainerStatuses[idx].State = newState 75 conditionFlag = true 76 } 77 } 78 var podReadyFlag bool 79 if conditionFlag { 80 if s.Conditions == nil { 81 s.Conditions = append(s.Conditions, podCondition) 82 } else { 83 for index, condition := range s.Conditions { 84 if condition.Type == v1.PodReady { 85 s.Conditions[index].Status = v1.ConditionFalse 86 s.Conditions[index].Reason = "ContainersNotReady" 87 podReadyFlag = true 88 break 89 } 90 } 91 if !podReadyFlag { 92 s.Conditions = append(s.Conditions, podCondition) 93 } 94 } 95 } 96 97 err := m.metaClient.PodStatus(pod.Namespace).Update(pod.Name, edgeapi.PodStatusRequest{UID: pod.UID, Name: pod.Name, Status: s}) 98 if err != nil { 99 klog.Errorf("Update pod status failed err :%v", err) 100 } 101 klog.Infof("Status for pod %s updated successfully: %+v", pod.Name, podStatus) 102 m.apiStatusVersions[pod.UID] = podStatus.DeepCopy() 103 } 104 }