削除ポッドメインソース分析プロセス

本論文では、V1.12へのバージョンを解析し、

ポッドを削除すると、クライアント端末は、deletionTimestampはポッドのタイムをマークapiserver、apiserverに要求を送信します。処理を開始するために、イベントを見kubelet。

syncLoop

ポッドのkubelet取り扱いは、主にsyncLoopに処理されます。

func (kl *Kubelet) syncLoop(updates <-chan kubetypes.PodUpdate, handler SyncHandler) {
for {
...
        if !kl.syncLoopIteration(updates, handler, syncTicker.C, housekeepingTicker.C, plegCh) {
            break
        }
...

syncLoopIterationでポッドとの主な関心事は、次の2つを削除します。

func (kl *Kubelet) syncLoopIteration(configCh <-chan kubetypes.PodUpdate, handler SyncHandler,
    syncCh <-chan time.Time, housekeepingCh <-chan time.Time, plegCh <-chan *pleg.PodLifecycleEvent) bool {
    select {
    case u, open := <-configCh:
...
        switch u.Op {
...
        case kubetypes.UPDATE:
            handler.HandlePodUpdates(u.Pods)
...
    case <-housekeepingCh:
        if !kl.sourcesReady.AllReady() {
        } else {
            if err := handler.HandlePodCleanups(); err != nil {
                glog.Errorf("Failed cleaning pods: %v", err)
            }
        }
    }

最初のDELETE要求が増加deletionTimestampイベントをトリガapiserverに送信される予定です。ここでkubetypes.UPDATEに対応しています。つまり、それはHandlePodUpdates機能を来ります。

housekeepingChからすべての2Sは、クリーンアップのポッドのためのイベントを時限後に別の関連の削除が実行され、実行がhandler.HandlePodCleanups機能です。これら二つの異なる効果を分けて説明されています。

HandlePodUpdates

HandlePodUpdatesは、このプロセスを見てください。限りdeletionTimestampをマークしたように、このプロセスは、必然的に行くことになるだろう。

func (kl *Kubelet) HandlePodUpdates(pods []*v1.Pod) {
    for _, pod := range pods {
...
        kl.dispatchWork(pod, kubetypes.SyncPodUpdate, mirrorPod, start)
    }
}

次にHandlePodUpdatesにポッドdispatchWork処理へ情報を渡します。

func (kl *Kubelet) dispatchWork(pod *v1.Pod, syncType kubetypes.SyncPodType, mirrorPod *v1.Pod, start time.Time) {
    if kl.podIsTerminated(pod) {
        if pod.DeletionTimestamp != nil {
            kl.statusManager.TerminatePod(pod)
        }
        return
    }
    // Run the sync in an async worker.
    kl.podWorkers.UpdatePod(&UpdatePodOptions{
        Pod:        pod,
        MirrorPod:  mirrorPod,
        UpdateType: syncType,
        OnCompleteFunc: func(err error) {
...

ここでは、第一kl.podIsTerminated(POD)を解析ポッドによって決定される終端状態になっていません。その場合は、以下のkl.podWorkers.UpdatePodは行われません。

func (kl *Kubelet) podIsTerminated(pod *v1.Pod) bool {
    status, ok := kl.statusManager.GetPodStatus(pod.UID)
    if !ok {
        status = pod.Status
    }
    return status.Phase == v1.PodFailed || status.Phase == v1.PodSucceeded || (pod.DeletionTimestamp != nil && notRunning(status.ContainerStatuses))
}

この場所は特にないDeletionTimestampが終了状態によって考慮されますが、DeletionTimestampがあり、すべてのコンテナが実行されていないことは注目に値します。ポッドは、通常の操作であれば、であることを、この手段はまたkl.podWorkers.UpdatePodはに行ってきました。関数呼び出しの一連UpdatePod、最終syncPod syncPod関数に関数は非同期で実行されるであろう。

func (kl *Kubelet) syncPod(o syncPodOptions) error {
...
    if !runnable.Admit || pod.DeletionTimestamp != nil || apiPodStatus.Phase == v1.PodFailed {
        var syncErr error
        if err := kl.killPod(pod, nil, podStatus, nil); err != nil {
...

syncPodでは、それによって、ポッドの動作を停止killPodを呼び出します。

killPod

killPodは、ポッド本体を停止することです。これは、多くの場所で使用されます。これは、次のプレイの主要なワークフローを紹介します。ポッドプロセスは、主にkillPodWithSyncResult機能で発生し停止します。

func (m *kubeGenericRuntimeManager) killPodWithSyncResult(pod *v1.Pod, runningPod kubecontainer.Pod, gracePeriodOverride *int64) (result kubecontainer.PodSyncResult) {
    killContainerResults := m.killContainersWithSyncResult(pod, runningPod, gracePeriodOverride)
...
    for _, podSandbox := range runningPod.Sandboxes {
            if err := m.runtimeService.StopPodSandbox(podSandbox.ID.ID); err != nil {
...

主killPodWithSyncResultは二つの部分に分けました。コンテナ内のkillContainersWithSyncResult責任ポッドはStopPodSandboxの実施前停留所で降り停止します。

func (m *kubeGenericRuntimeManager) killContainer(pod *v1.Pod, containerID kubecontainer.ContainerID, containerName string, reason string, gracePeriodOverride *int64) error {
    if err := m.internalLifecycle.PreStopContainer(containerID.ID); err != nil {
        return err
    }
...
    err := m.runtimeService.StopContainer(containerID.ID, gracePeriod)

KillContainersWithSyncResult主な仕事はkillContainerで行われ、主に2つのステップが容器内で行うPRESTOPを操作し、ここで見ることができます。それは、仕事コンテナの停止を成功してみましょう。この時点で、アプリケーションコンテナのすべてが停止されています。次のステップは、一時停止コンテナを停止することです。StopPodSandboxは、このプロセスの実装です。、オフ停止する一時停止容器であるサンドボックス、。StopPodSandboxは中dockershimで行われます。

func (ds *dockerService) StopPodSandbox(ctx context.Context, r *runtimeapi.StopPodSandboxRequest) (*runtimeapi.StopPodSandboxResponse, error) {
...
if !hostNetwork && (ready || !ok) {
...
        err := ds.network.TearDownPod(namespace, name, cID, annotations)
...
    }
    if err := ds.client.StopContainer(podSandboxID, defaultSandboxGracePeriod); err != nil {

最初のネットワークStopPodSandboxの主要部分は、アンロード、および、対応する容器を停止されます。StopPodSandboxを完了した後、すべての船舶は、これまでに完成ポッド停止されています。アンロードのボリュームについてでvolumeManagerで行われます。この記事では、個別に説明していません。コンテナは、徹底したクリーンアップポッド後に停止された後、それはGCにリサイクルされます。ここまで言えば、起動しません。

HandlePodCleanups

このプロセスは、上記のすべてのプロセスを削除しません。典型的なケースは、コンテナが実行されていない場合、そのUpdatePodすべてのリターンは、その後、誰がそれを処理しようとしているときということですか?ここでは、先頭に戻って、あることHandlePodCleanupsすべての2Sのプロセスの実装。等のクラッシュ、コンテナの場合はこのような容器は、単に実行されていない、実際には、このプロセスで処理されているということでした。もちろん、HandlePodCleanupsの役割はよりちょうどポッドで実行されていないクリーンアップよりも、その後、そのようなデータをクリーンアップすることを余儀なくさにapiserverで失われた、またはこのノードの他の理由によるものといくつかのクリーンアップポッドを完了していないされていますが、このプロセスで処理されます。

func (kl *Kubelet) HandlePodCleanups() error {
... 
    for _, pod := range runningPods {
        if _, found := desiredPods[pod.ID]; !found {
            kl.podKillingCh <- &kubecontainer.PodPair{APIPod: nil, RunningPod: pod}
        }
    }

desiredPodsは、ノード上のポッドが停止するべきではないですしながら、runningPodsポッドは、キャッシュから既存のノードを得ることです。そこrunningPodsはなく、ポッドは、それを停止しなければならない何desiredPodsが存在しない場合は、内podKillingChに送信されます。

func (kl *Kubelet) podKiller() {
...
    for podPair := range kl.podKillingCh {
...

        if !exists {
            go func(apiPod *v1.Pod, runningPod *kubecontainer.Pod) {
                glog.V(2).Infof("Killing unwanted pod %q", runningPod.Name)
                err := kl.killPod(apiPod, runningPod, nil, nil)
...
            }(apiPod, runningPod)
        }
    }
}

podKillerプロセスで、それによってkillPodを実行するpodKillingChからメッセージを受信し、上述した、それは関数で作られています。

statusManager

プロセスの最後の、syncPod statusManagerでは、それは、検出すべてのコンテナがcanBeDeletedによって閉じられていることを確認しますが、ボリュームはクリーンアップなどをCGROUP、アンインストールしました。これらがすべて完了した場合、apiserverポッドから完全に情報を削除します。

func (m *manager) syncPod(uid types.UID, status versionedPodStatus) {
...
    if m.canBeDeleted(pod, status.status) {
        deleteOptions := metav1.NewDeleteOptions(0)
        deleteOptions.Preconditions = metav1.NewUIDPreconditions(string(pod.UID))
        err = m.kubeClient.CoreV1().Pods(pod.Namespace).Delete(pod.Name, deleteOptions)
...

おすすめ

転載: www.cnblogs.com/xuxinkun/p/11923372.html