话题:调API删除Pod,真的删掉了吗???
先说下物理环境:
机器:3物理机(其实就是虚机)
配置:2core * 2GB
Kubelect Version:V1.7.9
Kube Proxy: V1.7.9
情况是这样的,自己封了一个api,功能大致是这样:用户前端页面删除自己的项目环境,顺带把namespace已发布的资源一并删除。
于是,自然而然想到如下思路:
1.调自封api删除PodTemplate
2.调自封api删除Deployment
3.调自封api删除Service
.... ....
美滋滋,但是接着在测试其它项目发布时,发现Replicas数量一直达不到预期?
开始排错:
kubectl get events -n=xxxxx -w
发现报错:
No nodes are available that match all of the following predicates:: Insufficient cpu (3), Insufficient memory (3).
???
查看配额:
request.cpu:3, requests.memory:3Gi
按照开头的思路,明明项目相关k8s已经全部删光,为什么这边会有3Core、3Gi的资源占用呢?
继续排错:
kubectl get deployment -n=xxxxx
No resources found.
kubectl get rs -n=xxxxx
No resources found.
kubectl get svc -n=xxxxx
No resources found.
kubectl get podtemplates -n=xxxxx
No resources found.
直到:
pod没有被删掉???
想到在deployment里,pod是由rs管理的
查看rs:
果然:rs没有删掉
OK,继续执行:kubectl delete rs/deployment-demo-3344900030 -n=xxxx
再次查看pod:
此时pod已经被删除
查看资源配额:
资源已经被释放
原因分析:
1. 缺少了对rs的清理;
OK,加入对rs资源的清理(之前接口已经封装好,直接拿来用)
于是,逻辑变成:
1.调自封api删除PodTemplate
2.调自封api删除ReplicationSet
3.调自封api删除Deployment
4.调自封api删除Service
继续验证:
调完1-4接口
资源都删除了
但悲剧仍没解除:
pod依然坚挺存在
分析:
???为什么rs都删除里,pod没自动清理(删除)呢?
记得之前执行过指令:kubectl delete rs/deployment-demo-3344900030 -n=xxxx
此时Pod已经被成功删除了
最终找到原因:
官方API在删除deployment后,并不会自动删除rs、pod等资源,需自行调相关api删除
此时,解决思路变为:
先干掉pod,释放quota那边资源占用,再依次删除podtemplate、rs、deployment、svc
如何干掉pod,并释放quota呢?
很简单,将deployment的replicas(副本集)数量置为0
于是,写下如下代码:
name := value.Name namesapce := value.NameSpace go func(na, ns string, ch chan error) { // 副本集数置为0 // 停止项目(pod)在k8s资源占用 deployment_name := fmt.Sprintf("deployment-%s", na) _, err := K8s_Client.UpdateDeployment(ns, deployment_name, patch_replaceop, patch_path , int32(0)) if err != nil { ch <- err } else { ch <- nil } }(name, namesapce, ch) go func(na, ns string, ch1 chan error) { select { case err := <- ch: if err != nil { ch1 <- err } else { // 删除podtemplate if err := DeletePodtemplate(na, ns); err != nil { ch1 <- err } else { // 删除ReplicationSet if err := DeleteReplicationSet(na, ns); err != nil { ch1 <- err } else { // 删除Deployment if err := DeleteDeployment(na, ns); err != nil { ch1 <- err } else { // 删除Service if err := DeleteService(na, ns); err != nil { ch1<- err } else { ch1 <- nil } } } } } } }(name, namesapce, ch1) select { case err := <- ch1: close(ch) close(ch1) if err != nil { KubernetesError(c, Unknown, err, b) return } }
开两个gorouting,第一个,调用自封PATCH接口重置deployment的replicas数量为0(Pod=0),quota资源即可释放
第二个,读到ch通道的返回后,删除后续podtemplate、rs、deployment、svc,如有错误,再抛到外部做处理