Kubernetes Pod 削除操作のソースコード分析

Kubernetes Pod 削除操作のソースコード分析

たとえば、更新戦略が Recreate であるアプリケーションがあり、次のように削除コマンドを実行します。

 ☸ ➜ kubectl ポッドを取得する
名前準備完了ステータス再起動年齢
minio-875749785-sv5ns 1 / 1 実行中1 ( 2分52秒) 42時間
☸ ➜ kubectl 削除ポッドminio-875749785-sv5ns
ポッド「minio-875749785-sv5ns」 が削除されました

削除する前に、別の端末でアプリケーションの状態を確認してください。

 kubectl ポッドを取得-w
名前準備完了ステータス再起動年齢
minio-875749785-sv5ns 1 / 1 実行中1 ( 2分46秒) 42時間
minio-875749785-sv5ns 1 / 1 終了中1 ( 2分57秒) 42時間
minio-875749785-h2j2b 0 / 1 保留中0 0 秒
minio-875749785-h2j2b 0 / 1 保留中0 0 秒
minio-875749785-h2j2b 0 / 1 コンテナ作成0 0s
minio-875749785-sv5ns 0 / 1 終了中1 ( 2分59秒) 42時間
minio-875749785-sv5ns 0 / 1 終了中1 ( 2分59秒) 42時間
minio-875749785-sv5ns 0 / 1 終了中1 ( 2分59秒) 42時間
minio-875749785-h2j2b 0 / 1 実行中0 17秒
minio-875749785-h2j2b 1 / 1 実行中0 30秒

上記のプロセスから、kubectl delete コマンドを実行すると、Pod が Terminating 状態に変わり、その後消えることがわかります。次に、コードの観点から Pod を削除する全体的なプロセスを紹介します。

ここでは、Kubernetes v1.22.8 を例に挙げます。他のバージョンのコードは完全に一貫しているとは保証されませんが、全体的な考え方は同じです。

削除ステータス

kubectl 操作後に表示されるステータスに基づいて追跡できます。上記のフォーマットされた結果は、以下に示すように、コード https://github.com/kubernetes/kubernetes/blob/v1.22.8/pkg/printers/internalversion/printers.go#L88-L102 によって実装されています。

Pod の出力は printPod 関数を通じて取得されます。コードは次の場所にあります: https://github.com/kubernetes/kubernetes/blob/v1.22.8/pkg/printers/internalversion/printers.go#L756-L840。以下に示すように、pod.DeletionTimestamp != nil の場合にこの状態に変更される Terminating 値について言及しているコードがあります。

つまり、削除操作が実行されると、Pod の DeletionTimestamp 属性が設定され、Terminating 状態として表示されます。

削除操作が実行されると、DELETE リクエストが API サーバーに送信されます。

 I0408 11 : 25 : 33.002155 42938 round_trippers .go : 435 ] curl - v - XDELETE - H "Content-Type: application/json" - H "User-Agent: kubectl/v1.22.7 (darwin/amd64) kubernetes/b56e432" - H "Accept: application/json" 'https://192.168.0.111:6443/api/v1/namespaces/default/pods/minio-875749785-sv5ns'
I0408 11 : 25 : 33.037245 42938 round_trippers.go : 454 ] DELETE https://192.168.0.111:6443/api/v1/namespaces/default/pods/minio-875749785-sv5ns 200 35 ミリ秒OK

削除リクエストを受信するハンドラーは、以下に示すように、コード https://github.com/kubernetes/kubernetes/blob/v1.22.8/staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go#L986 にあります。

BeforeDelete 関数で、正常な削除が必要かどうかを判断します。判断基準は、DeletionGracePeriodSeconds 値が 0 であるかどうかです。ゼロでない場合は、正常な削除とみなされ、apiserver はオブジェクトを etcd からすぐに削除しません。それ以外の場合は直接削除されます。 Pod の場合、デフォルトの DeletionGracePeriodSeconds は 30 秒なので、すぐには削除されません。代わりに、DeletionTimestamp は現在の時刻に設定され、DeletionGracePeriodSeconds はデフォルト値の 30 秒に設定されます。コードは https://github.com/kubernetes/kubernetes/blob/v1.22.8/staging/src/k8s.io/apiserver/pkg/registry/rest/delete.go#L93-L159 にあり、DeletionTimestamp の値は次のように設定されています。

上記のコードは、削除操作が実行されると、apiserver が最初に Pod の DeletionTimestamp 属性を現在の時刻に正常な削除猶予期間の時点を加えた時刻に設定することを確認します。この属性を設定すると、クライアントはフォーマット後に終了状態を確認します。

適切な削除

Pod にはサンドボックス コンテナー、ボリュームなど他の多くのリソースが含まれるため、削除後にそれらをリサイクルする必要があります。 Pod を削除すると、対応するコンテナも削除されます。クリーンアップを完了するには、Pod が配置されているノードの kubelet が必要です。まず、kubelet も Pod を監視し続けます。 Pod の削除時間が更新されると、当然イベントを受信し、対応するクリーンアップ作業を実行します。

Kubelet は主に syncLoop 関数で Pod を処理し、イベント関連の処理関数 syncLoopIteration を呼び出します。コードは、以下に示すように、https://github.com/kubernetes/kubernetes/blob/v1.22.8/pkg/kubelet/kubelet.go#L2040-L2079 にあります。

削除操作を実行すると、apiserver はまず Pod 内の DeletionTimestamp 属性を更新します。この変更は kubelet の更新操作であるため、kubetypes.UPDATE 操作に対応し、更新のために HandlePodUpdates 関数を呼び出します。

HandlePodUpdates では、処理のために Pod の削除を特定のワーカーに割り当てるために、dispatchWork が呼び出されます。 PodWorker は特定のエグゼキューターです。つまり、Pod を更新する必要があるたびに、その更新が podWorker に送信されます。

dispatchWork メソッドは UpdatePod 関数を呼び出して Pod を削除します。コードは https://github.com/kubernetes/kubernetes/blob/v1.22.8/pkg/kubelet/pod_workers.go#L540-L765 にあります。この関数では、Pod 情報がチャネルを介して渡され、処理のために goroutine 内で managePodLoop 関数が呼び出されます。この関数では、削除操作を実行するために syncTerminatingPod/syncPod メソッドが呼び出されます。

最終的には、killPod 関数が呼び出され、Pod が削除されます。

killPod 関数はコンテナ ランタイムを呼び出して、Pod 内のコンテナを停止します。コードは https://github.com/kubernetes/kubernetes/blob/v1.22.8/pkg/kubelet/kubelet_pods.go#L856-L868 にあります:

コンテナ ランタイムの KillPod メソッドは、以下に示すように、https://github.com/kubernetes/kubernetes/blob/v1.22.8/pkg/kubelet/kuberuntime/kuberuntime_manager.go#L969-L998 にあります。

killPodWithSyncResult メソッドは、まず killContainersWithSyncResult 関数を呼び出して実行中のすべてのコンテナを強制終了し、次に Pod のサンドボックスを削除します。

この関数では、複数の goroutine を使用して Pod 内の各コンテナを削除します。コンテナを削除するメソッドは killContainer です。この関数では、まず事前停止フック(存在する場合)が実行され、その後コンテナが停止されます。コードは https://github.com/kubernetes/kubernetes/blob/v1.22.8/pkg/kubelet/kuberuntime/kuberuntime_container.go#L660-L736 にあります。

まず、正常な削除の猶予期間を取得します。

TerminationGracePeriodSeconds はリソース リスト ファイルで設定できます。デフォルト値は 30 秒です。 Pod にシャットダウン コマンドが発行されると、SIGTERM シグナルがアプリケーションに送信されます。プログラムは SIGTERM シグナルをキャプチャし、それに応じて処理するだけで済みます。つまり、Pod が SIGTERM シグナルを受信して​​からアプリケーションが正常にシャットダウンするまでにかかる時間です。この時間は、上記で分析した apiserver によって設定されます。

事前停止フックが設定されており、十分な時間がある場合は、フックが実行されます。事前停止の主な目的は、コンテナが削除される前に、リソースの回復やその他の操作など、ビジネスを正常に停止できるようにすることです。

最後に、基盤となるコンテナ ランタイムが呼び出され、コンテナが停止されます。

コンテナが削除された後、前の killPodWithSyncResult 関数に戻り、ランタイム サービスの StopPodSandbox 関数を呼び出してサンドボックス コンテナを停止します (つまり、コンテナを一時停止します)。

 // 同じポッド属するすべてのサンドボックスを停止します
_ の場合podSandbox := range runningPod .Sandboxes {
エラーの場合:= m.runtimeService.StopPodSandbox ( podSandbox .ID .ID ); エラー = nil && !crierror .IsNotFound ( err ) {
killSandboxResult.Fail ( kubecontainer .ErrKillPodSandboxerr.Error ())
klog.ErrorS ( nil , "サンドボックスの停止に失敗しました" , "podSandboxID" , podSandbox .ID )
}
}

この時点で、kubelet は Pod の正常な削除を完了しましたが、これで終わりではありません。

同期ステータス

正常な削除の場合、API サーバーは最初に Pod の DeletionTimestamp 属性のみを設定し、その後 kubelet ウォッチが更新され、Pod の正常な削除が完了します。ただし、サーバー内には Pod の記録が残っており、実際には削除されていません。

kubelet が起動すると、statusManager 同期ループも開始されます。 Manager は kubelet ポッド ステータスの実際のソースであり、最新の v1.PodStatus と同期する必要があります。また、更新は apiserver に同期されます。つまり、正常な削除が完了すると、マネージャーを通じてステータスも apiserver に同期されます。

状態マネージャーが API サーバーとステータスを同期すると、マネージャーの下の syncPod メソッドを呼び出して処理します。コードは、以下に示すように、https://github.com/kubernetes/kubernetes/blob/v1.22.8/pkg/kubelet/status/status_manager.go#L149-L181 にあります。

このメソッドでは、Pod が正常に停止したかどうかを判断します。コードは、以下に示すように、https://github.com/kubernetes/kubernetes/blob/v1.22.8/pkg/kubelet/status/status_manager.go#L583-L652 にあります。

たとえば、まだ実行中のコンテナがあるかどうか、ボリュームがクリーンアップされていないかどうか、ポッド cgroup が空になっていないかどうかなどを判別します。canBeDeleted が true を返す場合、ポッドが正常に停止したことを意味します。この時点で、API サーバーに削除リクエストを送信して、ポッドを再度削除できます。

ただし、今回は GracePeriodSeconds が 0 に設定されており、Pod が強制的に削除されることを意味します。この時点で、apiserver は DELETE リクエストを再度受信します。初回との違いは、今回は Pod が強制的に削除され、etcd から Pod オブジェクトが削除される点です。

このとき、kubelet は REMOVE イベントを受信し、HandlePodRemoves 関数を呼び出して処理します。

まず、deletePod 関数が呼び出されて関連付けられたポッド ワーカーが停止され、次に、probeManager が呼び出されて、ポッドに関連するプローバー ワーカーが削除されます。これは、ポッドがノードから完全に削除されることを意味します。

<<:  Microsoft、Azure仮想マシンにArmのサポートを追加

>>:  クラウドの方が安全なのに、なぜまだハッキングされるのでしょうか?

推薦する

Google の電子商取引への間接的な浸透: 信頼できる販売業者認定プロジェクトを開始

Google、誠実な商人認定プロジェクトを開始新浪科技報北京時間6月8日朝のニュースによると、グーグ...

B2C医療電子商取引 - ブルーオーシャンにおける問題と解決策

正式な B2C 医薬品電子商取引は、2005 年に正式に人々の視界に入り始めました (単一ページ入札...

マルチクラウド開発の5つの推進要因

ビジネス革新を実現し、アプリケーションとビジネス モデルをサポートするために、パブリック クラウド、...

商務省:中国は来年、世界最大のオンライン小売市場になる

上海、6月7日(中国新聞社)(記者 姜瑜)中国商務省の邱紅副大臣は7日、上海で開催された「2012年...

ウェブマスターは外部リンク リソースをどのように調査し、適切に使用すればよいでしょうか?

今日は、SEO プロセス中に私がまとめた外部リンク リソースをマイニングする方法を皆さんと共有したい...

北京に拠点を置く仮想通貨取引所Vircurexが次のMt. Goxになる

3月24日現在、ビットコイン取引所マウントゴックスの破産危機はまだ収まっていないが、最近苦境に陥った...

A5の開発から見るソフト記事執筆の「戦略」

ソフトな文章を書くことは、これまでずっとみんなの頭痛の種でした。なぜなら、あまりにも多くのウェブマス...

タオバオストアのオンライン譲渡申請が開始、離婚した夫婦のオンラインストア所有権に関する規則が制定される

原題:タオバオの店舗譲渡オンライン申請が正式に開始、離婚後のオンラインストアの所有権に関する規則を制...

取引プロセスを最適化して、ターゲットユーザーの消費意欲を高める

オンライン取引プラットフォームにとって、より重要なのは実際のコンバージョン率です。訪問者が実際に消費...

cloudcone: 旧正月特別プロモーション、米国 VPS、年間 11 ドルから - 384M メモリ/10g SSD/8T トラフィック

Cloudcone は、旧正月に向けて特別に VPS 割引を用意しました。年間わずか 11 ドル、K...

catalysthost-年間42ドル/256MBメモリ/KVM/15GBハードディスク/100MB無制限

catalysthost は、openvz も付属する 100M 無制限 KVM VPS を宣伝して...

Google Cloud Platform に Kubernetes クラスターをデプロイするにはどうすればよいですか?

[51CTO.com クイック翻訳] あなたとあなたの会社は Kubernetes のトレンドに追い...

エッジコンピューティングと量子コンピューティングの違い

テクノロジーの世界が進化し続ける中、エッジ コンピューティングと量子コンピューティングという 2 つ...