一个Terminating
状态(数据并没有直接从etcd删除,而是设置了DeletionTimestamp)的Pod
是怎么删除的呢?我们知道删除一个资源对象是要调用APIServer
接口从etcd
中将数据删除。
假如要调用接口那请求发起方又是哪个组件呢?
创建一个Terminating状态的Pod
k apply -f b2.yaml
,然后k delete pod b2
你会得到一个处于Terminating
状态的Pod
1
2
3
4
5
6
7
8
9
10
11# b2.yaml
apiVersion: v1
kind: Pod
metadata:
name: b2
finalizers:
- kubernetes
spec:
containers:
- name: app
image: hysyeah/my-curl:v1
删除Terminating状态的pod
k edit pod b2
将finalizers
移除,然后你会发现pod b2
被立马删除了。
你可以通过命令watch -n 1 k get pod
或 watch -n 1 etcdctl get /registry/pods/default/b2 -w json
来监听对应的资源是否删除。
关于etcdctl
的使用可以查看
验证
为了验证猜测,首先我把k8s
集群中的kube-controller-manager
给移除了。然后对Terminating
状态的移除finalizers
操作,发现pod
被删除,可见这跟kube-controller-manager
。
然后猜测可能是kubelet
发送的请求,首先在kubelet
中并没有发现删除pod
的代码,然后经过验证发现这与kubelet
也没有关系。
最后观察k edit pod b2 --v=9
看这条操作调用了什么接口。
源码分析
1 | // 当我们删除一个带有finalizer的pod时并不会马上将etcd中的数据删除 |
1 | // 在下面的函数中打个断点,执行edit操作之后通过监听etcd数据,发现并没有被删除 |
小结
Terminating
状态的Pod
即不是由kubelet
,也不是由kube-controller-manager
发起请求删除的。而是当更新资源时(删除finalizers)调用Update
接口会进入deleteWithoutFinalizers
从而删除数据。
REF:
1.staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go