k8s 强制删除 pod/pvc/pv/ns 的方法

  |  

注意:强制删除的操作具有一定的风险,建议在生产环境中慎用。

如果namespace、pod、pv、pvc 处于 “Terminating” 状态时,可能是因为kubelet 阻塞,此时为了完成之后的操作,就需要进行强制删除。

典型的应用场景是 statefulset 的 pod 无法删除,导致 statefulset 无法更新。

如果所有资源都处于 “Terminating” 状态,需要按照 pod -> pvc -> pv -> ns 的顺序进行强制删除。

强制删除 pod

1
2
3
4
5
# 查看 pod 状态
$ kubectl -n <namespace> get pod -o wide

# 强制删除 pod
$ kubectl -n <namespace> delete pod <pod_name> --grace-period=0 --force

解释:

  • --grace-period:表示等待多少秒后强制删除,默认是30秒,在删除pod时,会给pod发送一个信号,让pod自己进行清理工作,如果超过了这个时间,pod还没有清理完,就会强制删除。如果设置为0,表示不等待,直接强制删除。
  • --force:表示强制删除

强制删除 pvc & pv

1
2
3
4
5
6
7
# 查看 pvc & pv 状态
$ kubectl -n <namespace> get pvc -o wide
$ kubectl -n <namespace> get pv -o wide

# 强制删除 pvc & pv
$ kubectl -n <namespace> patch pvc <pvc_name> -p '{"metadata":{"finalizers":null}}'
$ kubectl -n <namespace> patch pv <pv_name> -p '{"metadata":{"finalizers":null}}'

解释:

  • patch:表示修改资源的内容
  • {"metadata":{"finalizers":null}}:表示将资源的 finalizers 字段设置为 null,finalizers 字段是用来阻止资源被删除的,如果设置为 null,就可以强制删除了。
  • 设置之后,即直接删除了etcd中的记录。

强制删除 namespace

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 查看 namespace 状态
$ kubectl get namespace

# 查看 namespace 中的 finalizers 字段
$ kubectl get namespace <namespace> -o yaml

# 输出信息如下:
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: "2023-06-17T05:29:36Z"
deletionTimestamp: "2023-08-19T12:50:32Z"
name: <terminating-namespace>
resourceVersion: "226501792"
uid: 3249789c-6db7-4995-9f88-a562546dbfdb
spec:
finalizers:
- kubernetes
status:
phase: Active

# 导出 json 格式的 namespace 信息到文件中
$ kubectl get namespace <namespace> -o json > namespace.json

# 编辑 namespace.json 文件,删除 finalizers 字段
$ cat namespace.json

# 注意: 以下内容的 finalizers 字段已经被清空
{
"apiVersion": "v1",
"kind": "Namespace",
"metadata": {
"creationTimestamp": "2023-06-17T05:29:36Z",
"deletionTimestamp": "2023-08-19T12:50:32Z",
"name": "<terminating-namespace>",
"resourceVersion": "226501792",
"uid": "3249789c-6db7-4995-9f88-a562546dbfdb"
},
"spec": {
"finalizers": []
},
"status": {
"phase": "Active"
}
}

# 开启代理
$ kubectl proxy

执行完成以上命令后,终端会 hang 住,此时不要关闭终端,打开一个新的终端,执行以下命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 更新 namespace 信息,注意:这里的 <namespace> 是指上面的 <terminating-namespace>,文件 namespace.json 是指上面生成的文件,访问的 url 是上面的 proxy 代理的地址
$ curl -k -H "Content-Type: application/json" -X PUT --data-binary @namespace.json http://127.0.0.1:8001/api/v1/namespaces/<namespace>/finalize

# 输出信息如下:
{
"kind": "Namespace",
"apiVersion": "v1",
"metadata": {
"name": "<terminating-namespace>",
"selfLink": "/api/v1/namespaces/<terminating-namespace>/finalize",
"uid": "3249789c-6db7-4995-9f88-a562546dbfdb",
"resourceVersion": "226501792",
"creationTimestamp": "2023-06-17T05:29:36Z",
"deletionTimestamp": "2023-08-19T12:50:32Z"
},
"spec": {
"finalizers": null
},
"status": {
"phase": "Terminating"
}
}

# 查看 namespace 状态,确认 namespace 已经被删除
$ kubectl get namespace

之后两个终端都可以关闭了。

文章目录
  1. 1. 强制删除 pod
  2. 2. 强制删除 pvc & pv
  3. 3. 强制删除 namespace