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  }