2020/09/12 10:06

# Finalizers

Finalizers 字段属于 Kubernetes GC 垃圾收集器，是一种删除拦截机制，能够让控制器实现异步的删除前（Pre-delete）回调。其存在于任何一个资源对象的 Meta[1] 中，在 k8s 源码中声明为 []string，该 Slice 的内容为需要执行的拦截器名称。

metadata.deletionGracePeriodSeconds 的取值控制对更新的轮询周期。

// DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This// field is set by the server when a graceful deletion is requested by the user, and is not// directly settable by a client. The resource is expected to be deleted (no longer visible// from resource lists, and not reachable by name) after the time in this field, once the// finalizers list is empty. As long as the finalizers list contains items, deletion is blocked.// Once the deletionTimestamp is set, this value may not be unset or be set further into the// future, although it may be shortened or the resource may be deleted prior to this time.// For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react// by sending a graceful termination signal to the containers in the pod. After that 30 seconds,// the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup,// remove the pod from the API. In the presence of network partitions, this object may still// exist after this timestamp, until an administrator or automated process can determine the// resource is fully terminated.// If not set, graceful deletion of the object has not been requested.//// Populated by the system when a graceful deletion is requested.// Read-only.// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata// +optionalDeletionTimestamp *Time json:"deletionTimestamp,omitempty" protobuf:"bytes,9,opt,name=deletionTimestamp"// Number of seconds allowed for this object to gracefully terminate before// it will be removed from the system. Only set when deletionTimestamp is also set.// May only be shortened.// Read-only.// +optionalDeletionGracePeriodSeconds *int64 json:"deletionGracePeriodSeconds,omitempty" protobuf:"varint,10,opt,name=deletionGracePeriodSeconds"// Must be empty before the object is deleted from the registry. Each entry// is an identifier for the responsible component that will remove the entry// from the list. If the deletionTimestamp of the object is non-nil, entries// in this list can only be removed.// Finalizers may be processed and removed in any order.  Order is NOT enforced// because it introduces significant risk of stuck finalizers.// finalizers is a shared field, any actor with permission can reorder it.// If the finalizer list is processed in order, then this can lead to a situation// in which the component responsible for the first finalizer in the list is// waiting for a signal (field value, external system, or other) produced by a// component responsible for a finalizer later in the list, resulting in a deadlock.// Without enforced ordering finalizers are free to order amongst themselves and// are not vulnerable to ordering changes in the list.// +optional// +patchStrategy=mergeFinalizers []string json:"finalizers,omitempty" patchStrategy:"merge" protobuf:"bytes,14,rep,name=finalizers"

# 在 Operator 中的应用

// pkg/controller/chaosblade/controller.go 部分源码...const chaosbladeFinalizer = "finalizer.chaosblade.io"...func (r *ReconcileChaosBlade) Reconcile(request reconcile.Request) (reconcile.Result, error) {    reqLogger := logrus.WithField("Request.Name", request.Name)    forget := reconcile.Result{}    // Fetch the RC instance    cb := &v1alpha1.ChaosBlade{}    err := r.client.Get(context.TODO(), request.NamespacedName, cb)    if err != nil {      return forget, nil    }    if len(cb.Spec.Experiments) == 0 {      return forget, nil    }    // Destroyed->delete    // Remove the Finalizer if the CR object status is destroyed to delete it    if cb.Status.Phase == v1alpha1.ClusterPhaseDestroyed {      cb.SetFinalizers(remove(cb.GetFinalizers(), chaosbladeFinalizer))      err := r.client.Update(context.TODO(), cb)      if err != nil {        reqLogger.WithError(err).Errorln("remove chaosblade finalizer failed at destroyed phase")      }      return forget, nil    }    if cb.Status.Phase == v1alpha1.ClusterPhaseDestroying || cb.GetDeletionTimestamp() != nil {      err := r.finalizeChaosBlade(reqLogger, cb)      if err != nil {        reqLogger.WithError(err).Errorln("finalize chaosblade failed at destroying phase")      }      return forget, nil    }    ...    return forget, nil}

# 结语

“人生如同道路。最近的捷径通常是最坏的路。”

#### 引用链接

[1] Meta: https://github.com/kubernetes/apimachinery/blob/master/pkg/apis/meta/v1/types.go#L246
[2] chaosblade-operator: https://github.com/chaosblade-io/chaosblade-operator
[3] Issue#368: https://github.com/chaosblade-io/chaosblade/issues/368

0
0 收藏

0 评论
0 收藏
0