��K8s涓�广大�Pod璋�搴��版��涓���Node���逛���锛���缁����舵��缁存�や俊�������卞�瑰��哄�ㄤ���kubelet杩�琛�缁存�わ�濡�浣�疏浚��跺��兄弟����拌�琛��舵��锛�骞堕����apiserver����璁捐�$���剧�戊寅� ����涓昏�����杩�����Pod�舵���������㈡��舵���瑰��涓や釜娴�绋��ュ���������舵�稿��版��缁���锛��ヤ�瑙e���ㄨ�捐��

1. �舵��绠$��

1.1 ����Pod

image.png
����Pod涓昏��������d�涓�����杩�����apiserver��寤虹��pod, ��涓�apiserver涓�骞朵�����锛�浣������朵���瑕�缁存�ゅ���山��杩�绫�Pod���舵��锛� k8s涓�广大辫�捐�′�涓�涓�����Pod��姒�蹇碉��跺��广大辨��涓洪����Pod�����烘�ヤ�涓�Pod璇�Pod��涓昏�淇℃��涓�����Pod涓��达�骞朵���apiserver涓�杩�琛���寤猴���杩�apiserver��浠ユ���ョ��杩�涓�����Pod�ュ������疏浚�������Pod���舵��,�

1.2 �舵���版��婧�

image.png
statusManager��杩�琛��舵����姝ョ���抽��缁�浠跺�堕��瑕�缁煎��褰���Pod杩�琛�涓����版����apiserver海洋��ㄧ���版��锛�浠����冲����缁����舵��潘���, 杩������虫敞�句��诲�烘�ョ��锛��村����舵��绛���缁�浼�涓�涓�浠�缁�

2. ����涓��存��

type versionedPodStatus struct {
    status v1.PodStatus
    // ��璋���澧��������凤�姣�涓�pod锛�
    version uint64
    // Pod name & namespace, for sending updates to API server.
    podName      string
    podNamespace string
}

��Kubelet涓�涓轰�璇�涓�apiserver绔�淇℃������姝ワ��ㄦ���颁�海洋�河渠�涓�涓�Pod�舵������淇℃��锛��堕���㈤�や�淇�海洋�褰���Pod���舵���版��杩���涓�涓����������凤���杩���璋���澧��������风��瀵规���ョ‘疏浚�����杩�琛��舵������姝�

3. �稿�婧���疏浚���

statusManager��娴�绋��跺��杩�����澶�����锛�浠�澶╂��浠�广大卞��璁蹭�涓��烘��锛���kubelet��杩�apiserver���ュ�颁�涓�Pod�存�起��跺��椤虹��璇ュ���界���版��娴��ヨ�琛�姊崇��statusMangaer���㈢���版��娴�潘�

3.1 �稿��版��缁���

manager涓����稿��舵���稿�崇���版��缁�����浠ヤ富瑕���涓轰袱澶х把锛���广大��版��缁存��(podManager��podStatuses��apiStatusVersions)�版����淇$�¢��(podStatusChannel)锛� �╀�������瀵逛�apiserver��淇$��kublet��杩�琛�pod���ゆ��ョ���podDeletionSafety

type manager struct {
    kubeClient clientset.Interface
        // 绠$��缂�海洋�Pod锛���������pod������pod����广大�
    podManager kubepod.Manager
    // 浠�pod UID��广大��扮演�稿�pod�������舵��淇℃�� ��
    podStatuses      map[types.UID]versionedPodStatus
    podStatusesLock  sync.RWMutex
    podStatusChannel chan podStatusSyncRequest
    // 海洋��ㄩ����pod������
    apiStatusVersions map[kubetypes.MirrorPodUID]uint64
    podDeletionSafety PodDeletionSafetyProvider
}

3.2 璁剧疆Pod�舵��

璁剧疆Pod�舵��涓昏���浣�河渠�kubelet涓���syncPod涓�锛��ㄦ�ユ�跺��pod河渠�浠跺���翠���锛�浼�涓�apiserver杩�琛� Pod���版�版������姝ヤ����山��褰���pod��apiserver绔������扮演�舵��

func (m *manager) SetPodStatus(pod *v1.Pod, status v1.PodStatus) {
    m.podStatusesLock.Lock()
    defer m.podStatusesLock.Unlock()

    for _, c := range pod.Status.Conditions {
        if !kubetypes.PodConditionByKubelet(c.Type) {
            klog.Errorf("Kubelet is trying to update pod condition %q for pod %q. "+
                "But it is not owned by kubelet.", string(c.Type), format.Pod(pod))
        }
    }
    // Make sure we're caching a deep copy.
    status = *status.DeepCopy()

    // 濡���Pod琚����や�����瑕�寮哄�朵�apiserver杩�琛�淇℃������姝�
    m.updateStatusInternal(pod, status, pod.DeletionTimestamp != nil)
}

3.3 �存�板���ㄧ�海洋��舵��河渠х����姝ヤ�浠�

image.png

3.3.1 �山��缂�海洋��舵��

    var oldStatus v1.PodStatus
    // 妫�娴�涔��������扮演�海洋��版��
    cachedStatus, isCached := m.podStatuses[pod.UID]
    if isCached {
        oldStatus = cachedStatus.status
    } else if mirrorPod, ok := m.podManager.GetMirrorPodByPod(pod); ok {
        oldStatus = mirrorPod.Status
    } else {
        oldStatus = pod.Status
    }

3.3.2 妫�娴�疏浚瑰�ㄧ�舵��

妫�娴�疏浚瑰�ㄧ�舵��涓昏�����瀵瑰�瑰�ㄧ�姝㈢�舵��潘�������娉��ц�琛�妫�娴�锛��跺��广大辨���规��璁惧����Pod��RestartPolicy�ユ�娴���瀵逛�涓�缁�姝㈢��疏浚瑰�ㄦ������浠ヨ�琛�����

    if err := checkContainerStateTransition(oldStatus.ContainerStatuses, status.ContainerStatuses, pod.Spec.RestartPolicy); err != nil {
        klog.Errorf("Status update on pod %v/%v aborted: %v", pod.Namespace, pod.Name, err)
        return false
    }
    if err := checkContainerStateTransition(oldStatus.InitContainerStatuses, status.InitContainerStatuses, pod.Spec.RestartPolicy); err != nil {
        klog.Errorf("Status update on pod %v/%v aborted: %v", pod.Namespace, pod.Name, err)
        return false
    }

3.3.3 �存��PodCondition����潘��㈡�堕��

��杩����扮演��status���㈢��condition璁惧��瀵瑰�PodCondition��LastTransitionTime�存�版�堕�存��褰����堕��

    // Set ContainersReadyCondition.LastTransitionTime.
    updateLastTransitionTime(&status, &oldStatus, v1.ContainersReady)

    // Set ReadyCondition.LastTransitionTime.
    updateLastTransitionTime(&status, &oldStatus, v1.PodReady)

    // Set InitializedCondition.LastTransitionTime.
    updateLastTransitionTime(&status, &oldStatus, v1.PodInitialized)

    // Set PodScheduledCondition.LastTransitionTime.
    updateLastTransitionTime(&status, &oldStatus, v1.PodScheduled)

3.3.4 �″�规�堕�存����杩��夸俊��

兄弟���浼��规��褰���疏浚瑰�ㄧ��涓��起�浠����冲��姣�涓�疏浚瑰�ㄦ��澶х��海洋����板ぇ广大�锛��跺��瀵瑰�瑰�ㄩ���㈢��缁�姝㈢�舵�����㈢��Message淇℃��锛�杩�琛�����锛����惰�琛��堕�寸���″��

    normalizeStatus(pod, &status)

3.3.5 �舵���存�版�′欢妫�娴�

濡���涔���宸茬�缂�海洋�河渠�瀵瑰����版��锛�骞朵�缂�海洋����版��涓�褰������舵���������瑰��锛�涔�涓���瑕�寮哄�舵�存�起�广大辩�存�ヨ���

    if isCached && isPodStatusByKubeletEqual(&cachedStatus.status, &status) && !forceUpdate {
        // 濡���涓�寮哄�舵�存�� 锛�榛�璁ゆ��true姝ゅ�涓�浼���绔�
        klog.V(3).Infof("Ignoring same status for pod %q, status: %+v", format.Pod(pod), status)
        return false // No new status.
    }

3.3.6 ������姝ヤ�浠舵�存�扮演�海洋�

�������扮演���舵��缂�海洋��版��锛�骞朵���澧����扮演������淇℃��

    // ��寤烘�扮演���舵��
    newStatus := versionedPodStatus{
        status:       status,
        version:      cachedStatus.version + 1, // �存�板�ㄧ�海洋�
        podName:      pod.Name,
        podNamespace: pod.Namespace,
    }
    // �存�版�扮演��缂�海洋��舵��
    m.podStatuses[pod.UID] = newStatus

    select {
    case m.podStatusChannel <- podStatusSyncRequest{pod.UID, newStatus}: // ��寤轰�涓��扮演����姝ヨ�锋�
        klog.V(5).Infof("Status Manager: adding pod: %q, with status: (%d, %v) to podStatusChannel",
            pod.UID, newStatus.version, newStatus.status)

        return true
    default:
        // Let the periodic syncBatch handle the update if the channel is full.
        // We can't block, since we hold the mutex lock.
        klog.V(4).Infof("Skipping the status update for pod %q for now because the channel is full; status: %+v",
            format.Pod(pod), status)
        return false
    }

3.4 �㈡��舵���存��

image.png
�㈡��舵���跺��广大辨��Pod��疏浚瑰�ㄧ��杩�琛��舵��锛�姣�濡�濡���璁剧疆浜�Readiness�㈡�锛�褰���涓�疏浚瑰�ㄦ�㈡�澶辫触���跺��锛�广大变����ュ�瑰���service浠���绔���enpoint涓�绉婚�よ��Pod, 璁╂��浠�涓�璧风����Kubelet��濡�浣�广大�杩�琛��舵�����ュ��apiserver绔���

3.4.1 �山��褰����舵��

func (m *manager) SetContainerReadiness(podUID types.UID, containerID kubecontainer.ContainerID, ready bool) {
    m.podStatusesLock.Lock()
    defer m.podStatusesLock.Unlock()

    // �山�����扮演��疏浚瑰��
    pod, ok := m.podManager.GetPodByUID(podUID)
    if !ok {
        klog.V(4).Infof("Pod %q has been deleted, no need to update readiness", string(podUID))
        return
    }

    // �山��褰������舵��
    oldStatus, found := m.podStatuses[pod.UID]
    if !found {
        klog.Warningf("Container readiness changed before pod has synced: %q - %q",
            format.Pod(pod), containerID.String())
        return
    }

    // �山��褰�����疏浚瑰�ㄧ�舵��
    containerStatus, _, ok := findContainerStatus(&oldStatus.status, containerID.String())
    if !ok {
        klog.Warningf("Container readiness changed for unknown container: %q - %q",
            format.Pod(pod), containerID.String())
        return
    }

3.4.2 妫�娴��舵�����������瑰��

    // 妫�娴�������广大辩华�舵�����������瑰��
    if containerStatus.Ready == ready {
        klog.V(4).Infof("Container readiness unchanged (%v): %q - %q", ready,
            format.Pod(pod), containerID.String())
        return
    }

3.4.3 淇��瑰�瑰�ㄧ��广大辩华�舵��

�山��疏浚瑰�ㄧ���舵��锛�淇��瑰氨缁�涓哄������舵��

    status := *oldStatus.status.DeepCopy()
    containerStatus, _, _ = findContainerStatus(&status, containerID.String())
    containerStatus.Ready = ready

3.4.4 �规�����扮演��疏浚瑰�ㄧ�舵��淇���

浼��规��褰���杩�琛��剁��疏浚瑰�ㄦ�㈡����舵��锛��ヤ慨�瑰�瑰�PodCondition���㈢���舵��锛�����璋��ㄥ���ㄧ���存�伴�昏�

    updateConditionFunc := func(conditionType v1.PodConditionType, condition v1.PodCondition) {
        conditionIndex := -1
        // �山��Pod瀵瑰���PodCondition�舵��
        for i, condition := range status.Conditions {
            if condition.Type == conditionType {
                conditionIndex = i
                break
            }
        }
        // 淇��规��杩藉��Pod瀵瑰���PodCondition�舵��
        if conditionIndex != -1 {
            status.Conditions[conditionIndex] = condition
        } else {
            klog.Warningf("PodStatus missing %s type condition: %+v", conditionType, status)
            status.Conditions = append(status.Conditions, condition)
        }
    }
    // 璁$��Ready�舵��
    updateConditionFunc(v1.PodReady, GeneratePodReadyCondition(&pod.Spec, status.Conditions, status.ContainerStatuses, status.Phase))
    // 璁$��疏浚瑰��Ready�舵��
    updateConditionFunc(v1.ContainersReady, GenerateContainersReadyCondition(&pod.Spec, status.ContainerStatuses, status.Phase))
    m.updateStatusInternal(pod, status, false)

3.5 ���ㄥ���板��姝ヤ换��

statusManager浼����ㄤ�涓����扮演��绾跨��ヨ�琛��存�扮演�¢�����㈠��姝ヨ�锋���娑�璐�

func (m *manager) Start() {
    // ���ラ���稿�浠g��
    go wait.Forever(func() {
        select {
        case syncRequest := <-m.podStatusChannel:
            // �山�����扮演���舵��淇℃��锛��存��apiserver
            klog.V(5).Infof("Status Manager: syncing pod: %q, with status: (%d, %v) from podStatusChannel",
                syncRequest.podUID, syncRequest.status.version, syncRequest.status.status)
            m.syncPod(syncRequest.podUID, syncRequest.status)
        case <-syncTicker:
            m.syncBatch()
        }
    }, 0)
}

3.6 ��姝�Pod�舵��

image.png

3.6.1 ��姝ユ�′欢妫�娴�

��姝ユ�′欢妫�娴�涓昏���妫�娴�����Pod��������������������Pod褰�������琚����わ�濡���pod娌℃��琚����ゅ��杩���false,�冲�逛�涓�娌℃�����ょ��Pod��浠�杩�����瑕�缁х图�存�板�剁�舵����

    if !m.needsUpdate(uid, status) {
        klog.V(1).Infof("Status for pod %q is up-to-date; skipping", uid)
        return
    }

3.6.2 ��杩�apiserver�山������Pod�版��

濡���娌℃���山����Pod淇℃��锛����存�ヨ�琛����哄�冲��

    pod, err := m.kubeClient.CoreV1().Pods(status.podNamespace).Get(status.podName, metav1.GetOptions{})
    if errors.IsNotFound(err) {
        klog.V(3).Infof("Pod %q does not exist on the server", format.PodDesc(status.podName, status.podNamespace, uid))
        // 濡���Pod宸茬�琚����や�锛�广大辩�存�ラ���哄氨琛�
        return
    }
    if err != nil {
        klog.Warningf("Failed to get status for pod %q: %v", format.PodDesc(status.podName, status.podNamespace, uid), err)
        return
    }

3.6.3 璋���Patch�ュ�h�琛��存��

杩�����浼���杩�广大���广大����舵��涓�涔������舵���ヨ�琛�merge��骞讹��跺��璋���kubeClient杩�琛�apiserver绔��舵����淇���

    oldStatus := pod.Status.DeepCopy()
    // �存�版���$�����舵��
    newPod, patchBytes, err := statusutil.PatchPodStatus(m.kubeClient, pod.Namespace, pod.Name, pod.UID, *oldStatus, mergePodStatus(*oldStatus, status.status))
    klog.V(3).Infof("Patch status for pod %q with %q", format.Pod(pod), patchBytes)
    if err != nil {
        klog.Warningf("Failed to update status for pod %q: %v", format.Pod(pod), err)
        return
    }

3.6.4 �存�版���扮演��Apiserver绔�������淇℃��

    // 褰��������扮演���舵��
    pod = newPod

    klog.V(3).Infof("Status for pod %q updated successfully: (%d, %+v)", format.Pod(pod), status.version, status.status)
    m.apiStatusVersions[kubetypes.MirrorPodUID(pod.UID)] = status.version

3.6.5 妫�娴�����Pod

杩���涓昏��������舵�碉���Pod瀵瑰���璧�婧��藉凡缁����句�锛�������缁�����apiserver绔���Pod

// 濡���pod��DeletionTimestamp琚�璁剧疆锛���瀵瑰���Pod��瑕�琚�����
if m.canBeDeleted(pod, status.status) {
        deleteOptions := metav1.NewDeleteOptions(0)

        deleteOptions.Preconditions = metav1.NewUIDPreconditions(string(pod.UID))
        //  璋���apiserver瀵�Pod杩�琛�����
        err = m.kubeClient.CoreV1().Pods(pod.Namespace).Delete(pod.Name, deleteOptions)
        if err != nil {
            klog.Warningf("Failed to delete status for pod %q: %v", format.Pod(pod), err)
            return
        }
        klog.V(3).Infof("Pod %q fully terminated and removed from etcd", format.Pod(pod))
        m.deletePodStatus(uid)
    }

�㈡大人�翠���璁捐�″ぇ姒�广大辨��杩��凤�甯���澶т浆浠�澶�澶��虫敞锛�涓�璧蜂氦娴���
k8s婧�����璇荤�靛��涔��板��: https://www.yuque.com/baxiaoshi/tyado3