type OnCompleteFunc … type PodStatusFunc … type KillPodOptions … type UpdatePodOptions … type PodWorkerState … const SyncPod … const TerminatingPod … const TerminatedPod … func (state PodWorkerState) String() string { … } type PodWorkerSync … type podWork … type PodWorkers … type podSyncer … type syncPodFnType … type syncTerminatingPodFnType … type syncTerminatingRuntimePodFnType … type syncTerminatedPodFnType … type podSyncerFuncs … func newPodSyncerFuncs(s podSyncer) podSyncerFuncs { … } var _ … func (f podSyncerFuncs) SyncPod(ctx context.Context, updateType kubetypes.SyncPodType, pod *v1.Pod, mirrorPod *v1.Pod, podStatus *kubecontainer.PodStatus) (bool, error) { … } func (f podSyncerFuncs) SyncTerminatingPod(ctx context.Context, pod *v1.Pod, podStatus *kubecontainer.PodStatus, gracePeriod *int64, podStatusFn func(*v1.PodStatus)) error { … } func (f podSyncerFuncs) SyncTerminatingRuntimePod(ctx context.Context, runningPod *kubecontainer.Pod) error { … } func (f podSyncerFuncs) SyncTerminatedPod(ctx context.Context, pod *v1.Pod, podStatus *kubecontainer.PodStatus) error { … } const workerResyncIntervalJitterFactor … const workerBackOffPeriodJitterFactor … const backOffOnTransientErrorPeriod … type podSyncStatus … func (s *podSyncStatus) IsWorking() bool { … } func (s *podSyncStatus) IsTerminationRequested() bool { … } func (s *podSyncStatus) IsTerminationStarted() bool { … } func (s *podSyncStatus) IsTerminated() bool { … } func (s *podSyncStatus) IsFinished() bool { … } func (s *podSyncStatus) IsEvicted() bool { … } func (s *podSyncStatus) IsDeleted() bool { … } func (s *podSyncStatus) IsStarted() bool { … } // WorkType returns this pods' current state of the pod in pod lifecycle state machine. func (s *podSyncStatus) WorkType() PodWorkerState { … } // mergeLastUpdate records the most recent state from a new update. Pod and MirrorPod are // incremented. KillPodOptions is accumulated. If RunningPod is set, Pod is synthetic and // will *not* be used as the last pod state unless no previous pod state exists (because // the pod worker may be responsible for terminating a pod from a previous run of the // kubelet where no config state is visible). The contents of activeUpdate are used as the // source of truth for components downstream of the pod workers. func (s *podSyncStatus) mergeLastUpdate(other UpdatePodOptions) { … } type podWorkers … func newPodWorkers( podSyncer podSyncer, recorder record.EventRecorder, workQueue queue.WorkQueue, resyncInterval, backOffPeriod time.Duration, podCache kubecontainer.Cache, ) PodWorkers { … } func (p *podWorkers) IsPodKnownTerminated(uid types.UID) bool { … } func (p *podWorkers) CouldHaveRunningContainers(uid types.UID) bool { … } func (p *podWorkers) ShouldPodBeFinished(uid types.UID) bool { … } func (p *podWorkers) IsPodTerminationRequested(uid types.UID) bool { … } func (p *podWorkers) ShouldPodContainersBeTerminating(uid types.UID) bool { … } func (p *podWorkers) ShouldPodRuntimeBeRemoved(uid types.UID) bool { … } func (p *podWorkers) ShouldPodContentBeRemoved(uid types.UID) bool { … } func (p *podWorkers) IsPodForMirrorPodTerminatingByFullName(podFullName string) bool { … } func isPodStatusCacheTerminal(status *kubecontainer.PodStatus) bool { … } // UpdatePod carries a configuration change or termination state to a pod. A pod is either runnable, // terminating, or terminated, and will transition to terminating if: deleted on the apiserver, // discovered to have a terminal phase (Succeeded or Failed), or evicted by the kubelet. func (p *podWorkers) UpdatePod(options UpdatePodOptions) { … } // calculateEffectiveGracePeriod sets the initial grace period for a newly terminating pod or allows a // shorter grace period to be provided, returning the desired value. func calculateEffectiveGracePeriod(status *podSyncStatus, pod *v1.Pod, options *KillPodOptions) (int64, bool) { … } // allowPodStart tries to start the pod and returns true if allowed, otherwise // it requeues the pod and returns false. If the pod will never be able to start // because data is missing, or the pod was terminated before start, canEverStart // is false. This method can only be called while holding the pod lock. func (p *podWorkers) allowPodStart(pod *v1.Pod) (canStart bool, canEverStart bool) { … } // allowStaticPodStart tries to start the static pod and returns true if // 1. there are no other started static pods with the same fullname // 2. the uid matches that of the first valid static pod waiting to start func (p *podWorkers) allowStaticPodStart(fullname string, uid types.UID) bool { … } // cleanupUnstartedPod is invoked if a pod that has never been started receives a termination // signal before it can be started. This method must be called holding the pod lock. func (p *podWorkers) cleanupUnstartedPod(pod *v1.Pod, status *podSyncStatus) { … } // startPodSync is invoked by each pod worker goroutine when a message arrives on the pod update channel. // This method consumes a pending update, initializes a context, decides whether the pod is already started // or can be started, and updates the cached pod state so that downstream components can observe what the // pod worker goroutine is currently attempting to do. If ok is false, there is no available event. If any // of the boolean values is false, ensure the appropriate cleanup happens before returning. // // This method should ensure that either status.pendingUpdate is cleared and merged into status.activeUpdate, // or when a pod cannot be started status.pendingUpdate remains the same. Pods that have not been started // should never have an activeUpdate because that is exposed to downstream components on started pods. func (p *podWorkers) startPodSync(podUID types.UID) (ctx context.Context, update podWork, canStart, canEverStart, ok bool) { … } func podUIDAndRefForUpdate(update UpdatePodOptions) (types.UID, klog.ObjectRef) { … } // podWorkerLoop manages sequential state updates to a pod in a goroutine, exiting once the final // state is reached. The loop is responsible for driving the pod through four main phases: // // 1. Wait to start, guaranteeing no two pods with the same UID or same fullname are running at the same time // 2. Sync, orchestrating pod setup by reconciling the desired pod spec with the runtime state of the pod // 3. Terminating, ensuring all running containers in the pod are stopped // 4. Terminated, cleaning up any resources that must be released before the pod can be deleted // // The podWorkerLoop is driven by updates delivered to UpdatePod and by SyncKnownPods. If a particular // sync method fails, p.workerQueue is updated with backoff but it is the responsibility of the kubelet // to trigger new UpdatePod calls. SyncKnownPods will only retry pods that are no longer known to the // caller. When a pod transitions working->terminating or terminating->terminated, the next update is // queued immediately and no kubelet action is required. func (p *podWorkers) podWorkerLoop(podUID types.UID, podUpdates <-chan struct{ … } // acknowledgeTerminating sets the terminating flag on the pod status once the pod worker sees // the termination state so that other components know no new containers will be started in this // pod. It then returns the status function, if any, that applies to this pod. func (p *podWorkers) acknowledgeTerminating(podUID types.UID) PodStatusFunc { … } // completeSync is invoked when syncPod completes successfully and indicates the pod is now terminal and should // be terminated. This happens when the natural pod lifecycle completes - any pod which is not RestartAlways // exits. Unnatural completions, such as evictions, API driven deletion or phase transition, are handled by // UpdatePod. func (p *podWorkers) completeSync(podUID types.UID) { … } // completeTerminating is invoked when syncTerminatingPod completes successfully, which means // no container is running, no container will be started in the future, and we are ready for // cleanup. This updates the termination state which prevents future syncs and will ensure // other kubelet loops know this pod is not running any containers. func (p *podWorkers) completeTerminating(podUID types.UID) { … } // completeTerminatingRuntimePod is invoked when syncTerminatingPod completes successfully, // which means an orphaned pod (no config) is terminated and we can exit. Since orphaned // pods have no API representation, we want to exit the loop at this point and ensure no // status is present afterwards - the running pod is truly terminated when this is invoked. func (p *podWorkers) completeTerminatingRuntimePod(podUID types.UID) { … } // completeTerminated is invoked after syncTerminatedPod completes successfully and means we // can stop the pod worker. The pod is finalized at this point. func (p *podWorkers) completeTerminated(podUID types.UID) { … } // completeWork requeues on error or the next sync interval and then immediately executes any pending // work. func (p *podWorkers) completeWork(podUID types.UID, phaseTransition bool, syncErr error) { … } // SyncKnownPods will purge any fully terminated pods that are not in the desiredPods // list, which means SyncKnownPods must be called in a threadsafe manner from calls // to UpdatePods for new pods. Because the podworker is dependent on UpdatePod being // invoked to drive a pod's state machine, if a pod is missing in the desired list the // pod worker must be responsible for delivering that update. The method returns a map // of known workers that are not finished with a value of SyncPodTerminated, // SyncPodKill, or SyncPodSync depending on whether the pod is terminated, terminating, // or syncing. func (p *podWorkers) SyncKnownPods(desiredPods []*v1.Pod) map[types.UID]PodWorkerSync { … } // removeTerminatedWorker cleans up and removes the worker status for a worker // that has reached a terminal state of "finished" - has successfully exited // syncTerminatedPod. This "forgets" a pod by UID and allows another pod to be // recreated with the same UID. The kubelet preserves state about recently // terminated pods to prevent accidentally restarting a terminal pod, which is // proportional to the number of pods described in the pod config. The method // returns true if the worker was completely removed. func (p *podWorkers) removeTerminatedWorker(uid types.UID, status *podSyncStatus, orphaned bool) bool { … } // killPodNow returns a KillPodFunc that can be used to kill a pod. // It is intended to be injected into other modules that need to kill a pod. func killPodNow(podWorkers PodWorkers, recorder record.EventRecorder) eviction.KillPodFunc { … } // cleanupPodUpdates closes the podUpdates channel and removes it from // podUpdates map so that the corresponding pod worker can stop. It also // removes any undelivered work. This method must be called holding the // pod lock. func (p *podWorkers) cleanupPodUpdates(uid types.UID) { … } // requeueLastPodUpdate creates a new pending pod update from the most recently // executed update if no update is already queued, and then notifies the pod // worker goroutine of the update. This method must be called while holding // the pod lock. func (p *podWorkers) requeueLastPodUpdate(podUID types.UID, status *podSyncStatus) { … }