目次
バックグラウンド
Kubernetes では、コントローラーはリソース オブジェクトを管理して、リソース オブジェクトが常に望ましい状態になるようにする責任があります。リソース オブジェクトを削除する必要がある場合、Finalizer と DeletionTimestamp は 2 つの重要なフィールドであり、コントローラーがリソース オブジェクトの削除を安全に管理するのに役立ちます。
ファイナライザーは、リソース オブジェクトを削除する前に特定の操作を実行するメカニズムです。たとえば、リソース オブジェクトを削除する前のクリーンアップ操作などです。ファイナライザーのリストは、リソース オブジェクトの metadata.finalizers フィールドで指定された文字列のセットとして実装されます。Kubernetes は、リソース オブジェクトが削除対象としてマークされると、ファイナライザーのリストにファイナライザーを追加します。すべてのファイナライザーが実行されると、Kubernetes はオブジェクトを削除します。
DeletionTimestamp は、リソース オブジェクトの削除時間をマークするために使用されるタイムスタンプです。Kubernetes は、リソース オブジェクトが削除対象としてマークされると、DeletionTimestamp フィールドにタイムスタンプを設定します。リソース オブジェクトに削除のマークが付けられると、変更または更新できなくなります。
使用法
Finalizer と DeletionTimestamp は密接に関連しています。リソース オブジェクトが削除対象としてマークされると、Kubernetes は DeletionTimestamp フィールドにタイムスタンプを設定し、ファイナライザー リストにファイナライザーを追加します。すべてのファイナライザーが実行されると、Kubernetes はオブジェクトを削除し、DeletionTimestamp フィールドを null に設定します。
達成
Deployment リソース オブジェクトの Finalizer と DeletionTimestamp の使用例を次に示します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
finalizers:
- my-finalizer
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
上の例では、Deployment リソース オブジェクトの Finalizers リストに my-finalizer という名前のファイナライザーが含まれています。Deployment リソース オブジェクトが削除されると、Finalizer my-finalizer は、関連付けられた ConfigMap リソース オブジェクトの削除など、いくつかのクリーンアップ操作を実行します。
const (
myFinalizerName = "my-finalizer"
)
myFinalizerName
サンプル コードで定義されている文字列定数で、Deployment リソース オブジェクトに追加されるファイナライザーの名前を表します。必要に応じてファイナライザーの名前を設定できますが、ファイナライザーを追加または削除するときは必ず同じ名前を使用してください。コード例では、ファイナライザーの名前は ですmy-finalizer
。
以下は、コントローラの調整プロセスのサンプルであり、Finalizer と DeletionTimestamp の使用法を示しています。
func (c *Controller) reconcile(ctx context.Context, deployment *appsv1.Deployment) error {
// Check if the object is being deleted
if !deployment.ObjectMeta.DeletionTimestamp.IsZero() {
// The object is being deleted
if containsString(deployment.ObjectMeta.Finalizers, myFinalizerName) {
// Run finalization logic
if err := c.finalizeDeployment(ctx, deployment); err != nil {
return err
}
// Remove the finalizer
deployment.ObjectMeta.Finalizers = removeString(deployment.ObjectMeta.Finalizers, myFinalizerName)
if _, err := c.kubeClient.AppsV1().Deployments(deployment.Namespace).Update(ctx, deployment, metav1.UpdateOptions{}); err != nil {
return err
}
}
return nil
}
// The object is not being deleted
if !containsString(deployment.ObjectMeta.Finalizers, myFinalizerName) {
// Add finalizer
deployment.ObjectMeta.Finalizers = append(deployment.ObjectMeta.Finalizers, myFinalizerName)
if _, err := c.kubeClient.AppsV1().Deployments(deployment.Namespace).Update(ctx, deployment, metav1.UpdateOptions{}); err != nil {
return err
}
}
// Handle normal reconcile logic here
// ...
}
func (c *Controller) finalizeDeployment(ctx context.Context, deployment *appsv1.Deployment) error {
// Perform finalization logic, such as deleting related ConfigMaps
// ...
return nil
}
func containsString(strs []string, str string) bool {
for _, s := range strs {
if s == str {
return true
}
}
return false
}
func removeString(strs []string, str string) []string {
newStrs := []string{}
for _, s := range strs {
if s != str {
newStrs = append(newStrs, s)
}
}
return newStrs
}
上の例では、Deployment リソース オブジェクトが削除対象としてマークされている場合、reconcile 関数は、my-finalizer Finalizer が Deployment リソース オブジェクトのファイナライザーのリストに含まれているかどうかを確認します。含まれている場合は、finalizeDeployment 関数でクリーンアップ ロジックを実行します。クリーンアップ ロジックが完了すると、my-finalizer Finalizer がファイナライザーのリストから削除されます。最後に、Kubernetes API を使用して Deployment リソース オブジェクトを更新し、ファイナライザーのリストが正しく更新されるようにします。
デプロイメント リソース オブジェクトが削除対象としてマークされているが、ファイナライザー リストに my-finalizer Finalizer が含まれていない場合、reconcile 関数は、クリーンアップ ロジックが正しく実行されることを確認するために、my-finalizer Finalizer をファイナライザー リストに追加します。
要約する
Finalizer と DeletionTimestamp は、Kubernetes でリソースの削除を管理するための重要なメカニズムです。コントローラーは Finalizer と DeletionTimestamp を使用して、リソース オブジェクトの削除を安全に管理し、必要に応じてクリーンアップ操作を実行できます。リソース オブジェクトを扱うときは、Finalizer と DeletionTimestamp の役割を考慮し、リソース オブジェクトの誤った削除を避けるためにそれらを正しく使用することが重要です。