Finalizers¶
Finalizer 是带有名字空间的键(namespaced keys),告诉Kubernetes需要等待特定条件满足后,才能完全删除标记为删除的资源。Finalers通知控制器清理被删除对象拥有的资源。
当通知Kubernetes删除一个指定了 Finalizers 的对象时,Kubernetes API通过填充 .metadata.deletionTimestamp
来标记要删除的对象,并返回 202
状态码(HTTP “已接受”)使对象进入只读状态。此时控制平面(control plane)或其他组件会采用 Finalizers 所定义的动作,而目标对象仍然处于终止(Terminating)状态。
备注
你可以理解为 Finalizers
是对象删除前需要完成的一系列动作清单,只有 metadata.finalizers
字段清空之后,Kubernetes踩认为系列动作已经完成,才会删除对象。
可以使用 Finalizer 控制资源的垃圾回收。例如可以定义Finalizer,在删除目标资源之前清理相关资源或基础设施。
删除该资源时,处理删除请求的 API 服务器会注意到 finalizers
字段中的值, 并进行以下操作:
修改对象,将你开始执行删除的时间添加到
metadata.deletionTimestamp
字段禁止对象被删除,直到其
metadata.finalizers
字段内的所有项被删除返回
202
状态码(HTTP “Accepted”)
警告
在对象卡在删除状态的情况下,要避免手动移除 Finalizers,以允许继续删除操作。 Finalizers 通常因为特殊原因被添加到资源上,所以强行删除它们会导致集群出现问题。 只有了解 finalizer 的用途时才能这样做,并且应该通过一些其他方式来完成 (例如,手动清除其余的依赖对象)。
通过patch方式更新对象去除finalizers¶
实际生产维护,因为节点故障导致资源没有摘除的情况较多,例如公司的 cni-services
组件没有处理掉宕机节点(因为节点agent没有正确完成IP处理流程,宕机了啊)。此时紧急情况下,我们需要通过去除pod的 finalizers
来完成资源释放:
finalizers:
- pod.beta1.sigma.ali/cni-allocated
单个处理节点上pod的释放脚本:
# 输出参数是Node节点
node=$1
cluster=z-k8s
kubeconfig="--kubeconfig ${cluster}/admin.kubeconfig.yaml"
kubectl ${kubeconfig} get pods -l scheduler.assign/nodename=${node} -A | tee node_pods
# 获取节点上pods的ns和名字列表
cat node_pods | grep "Terminating" | awk '{print $1" "$2}' | tee node_ns_pods
> node_ns_pods_cmd
while read ns pod; do
# 最初我是手工修改
#echo "kubectl ${kubeconfig} -n $ns edit pods $pod" | tee -a node_ns_pods_cmd
#echo "kubectl ${kubeconfig} -n $ns delete pods $pod --force" | tee -a node_ns_pods_cmd
# 采用patch方式可以批量处理
echo "kubectl ${kubeconfig} -n $ns patch pods $pod -p '{"metadata":{"finalizers":null}}' --type=merge" | tee -a node_ns_pods_cmd
done < "node_ns_pods"
批量处理多个节点上pod释放脚本:
#!/usr//bin/env bash
cluster=z-k8s
cat << EOF > hosts
server-1
server-x
EOF
function gen_cmd() {
local node=$1
kubeconfig="--kubeconfig biz/${cluster}/admin.kubeconfig.yaml"
kubectl ${kubeconfig} get pods -l scheduler.assign/nodename=${node} -A | tee node_pods
cat node_pods | grep "Terminating" | awk '{print $1" "$2}' | tee node_ns_pods
while read ns pod; do
#echo "kubectl ${kubeconfig} -n $ns edit pods $pod" | tee -a node_ns_pods_cmd
#echo "kubectl ${kubeconfig} -n $ns delete pods $pod --force" | tee -a node_ns_pods_cmd
echo "kubectl ${kubeconfig} -n $ns patch pods $pod -p '{\"metadata\":{\"finalizers\":null}}' --type=merge" | tee -a node_ns_pods_cmd
done < "node_ns_pods"
}
function batch_gen_cmd() {
> node_ns_pods_cmd
for sn in `cat hosts`;do
gen_cmd $sn
done
}
batch_gen_cmd