写点什么

Kubernetes rubbish 如何回收

作者:CTO技术共享
  • 2022 年 8 月 13 日
    广东
  • 本文字数:10111 字

    阅读完需:约 33 分钟

Kubernetes rubbish如何回收

一、Tips

  1. Kubernetes 的垃圾回收由 kubelet 进行管理,每分钟会查询清理一次容器,每五分钟查询清理一次镜像。在 kubelet 刚启动时并不会立即进行 GC,即第一次进行容器回收为 kubelet 启动一分钟后,第一次进行镜像回收为 kubelet 启动五分钟后。

  2. 不推荐使用其它管理工具或手工进行容器和镜像的清理,因为 kubelet 需要通过容器来判断 pod 的运行状态,如果使用其它方式清除容器有可能影响 kubelet 的正常工作。

  3. 镜像的回收针对 node 结点上由 docker 管理的所有镜像,无论该镜像是否是在创建 pod 时 pull 的。而容器的回收策略只应用于通过 kubelet 管理的容器。

  4. Kubernetes 通过 kubelet 集成的 cadvisor 进行镜像的回收,有两个参数可以设置:--image-gc-high-threshold--image-gc-low-threshold。当用于存储镜像的磁盘使用率达到百分之--image-gc-high-threshold 时将触发镜像回收,删除最近最久未使用(LRU,Least Recently Used)的镜像直到磁盘使用率降为百分之--image-gc-low-threshold或无镜像可删为止。默认--image-gc-high-threshold为 90,``--image-gc-low-threshold`为 80。

  5. 容器的回收有三个参数可设置:--minimum-container-ttl-duration--maximum-dead-containers-per-container--maximum-dead-containers。从容器停止运行时起经过--minimum-container-ttl-duration时间后,该容器标记为已过期将来可以被回收(只是标记,不是回收),默认值为 1m0s。一般情况下每个 pod 最多可以保留--maximum-dead-containers-per-container个已停止运行的容器集,默认值为 2。整个 node 节点可以保留--maximum-dead-containers个已停止运行的容器,默认值为 100。

  6. 如果需要关闭容器的垃圾回收策略,可以将--minimum-container-ttl-duration设为 0(表示无限制),--maximum-dead-containers-per-container--maximum-dead-containers设为负数。

  7. --minimum-container-ttl-duration的值可以使用单位后缀,如 h 表示小时,m 表示分钟,s 表示秒。

  8. --maximum-dead-containers-per-container--maximum-dead-containers冲突时,``--maximum-dead-containers`优先考虑。

  9. 对于那些由 kubelet 创建的但由于某些原因导致无名字()的容器,会在到达 GC 时间点时被删除。

  10. 回收容器时,按创建时间排序,优先删除那些创建时间最早的容器。

  11. 到达 GC 时间点时,具体的 GC 过程如下:1)遍历所有 pod,使其满足--maximum-dead-containers-per-container;2)经过上一步后如果不满足--maximum-dead-containers,计算值X=(--maximum-dead-containers)/(pod总数),再遍历所有 pod,使其满足已停止运行的容器集个数不大于 X 且至少为 1;3)经过以上两步后如果还不满足--maximum-dead-containers,则对所有已停止的容器排序,优先删除创建时间最早的容器直到满足--maximum-dead-containers为止。

  12. 当某个镜像重新 pull 或启动某个 pod 用到该镜像时,该镜像的最近使用时间都会被更新。

  13. Kubernetes 的垃圾回收在 1.1.4 版本开始才渐渐完善,之前的版本存在比较多 bug 甚至不能发挥作用。

  14. 关于容器的回收需要特别注意 pod 的概念,比如,通过同一个 yaml 文件 create 一个 pod,再 delete 这个 pod,然后再 create 这个 pod,此时之前的那个 pod 对应的容器并不会作为新创建 pod 的已停止容器集,因为这两个 pod 虽然同名,但已经不是同一个 pod 了。只有同一个 pod 中在运行过程中由于意外或其它情况停止的容器才算是这个 pod 的已停止容器集。

二、Experiments

  1. 镜像回收(使用 docker 默认 --graph 参数:/var/lib/docker

结点上运行的 docker 设置的参数 --graph 使用默认的/var/lib/docker,指向/var 文件系统,通过 df -lh 查看目前 /var 磁盘使用率为 30%,启动 kubelet 设置镜像回收相关参数如下:

--image-gc-high-threshold=40 --image-gc-low-threshold=35
复制代码

此时任意创建两个使用不同镜像的 pod,在 node 节点上可以看到新 pull 了三个 images(pause 镜像是启动 pod 必需的):

[@tc-151-100 /opt/domeos/openxxs/k8s-1.1.7-flannel]# docker imagesREPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE10.11.150.76:5000/openxxs/iperf   1.2                 1783511c56f8        3 months ago        279 MB10.11.150.76:5000/centos          7                   5ddf34d4d69b        8 months ago        172.2 MBpub.domeos.org/kubernetes/pause   latest              f9d5de079539        20 months ago       239.8 kB
复制代码

此时查看/var 磁盘使用率达到了 41%,然后将使用10.11.150.76:5000/centos:7镜像的 pod 删除,等待 GC 的镜像回收时间点。然而五分钟过去了,什么事情也没有发生=_=!!。还记得 docker rmi 镜像时有个前提条件是什么吗?没错,要求使用该镜像的容器都已经被删除了才可以。前面删除 pod 只是停止了容器,并没有将容器删除。因此手工将对应的容器 docker rm 掉,再等待五分钟后,可以看到镜像已经被删除回收了:

[@tc-151-100 /opt/domeos/openxxs/k8s-1.1.7-flannel]# docker imagesREPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE10.11.150.76:5000/openxxs/iperf   1.2                 1783511c56f8        3 months ago        279 MBpub.domeos.org/kubernetes/pause   latest              f9d5de079539        20 months ago       239.8 kB
复制代码

结论:只有相关联的容器都被停止并删除回收后,才能将 Kubernetes 的镜像垃圾回收策略应用到该镜像上。

  1. 镜像回收(使用自定义 docker --graph 参数:/opt/docker

结点上运行的 docker 设置的参数--graph指向 /opt 磁盘,通过 df -lh 查看目前 /opt 磁盘使用率为 48% ,启动 kubelet 设置镜像回收相关参数如下:

--image-gc-high-threshold=50 --image-gc-low-threshold=40
复制代码

此时任意创建两个使用不同镜像的 pod,在 node 节点上可以看到新 pull 了三个 images:

[@tc-151-100 /opt/domeos/openxxs/k8s-1.1.7-flannel]# docker imagesREPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE10.11.150.76:5000/openxxs/iperf   1.2                 1783511c56f8        3 months ago        279 MB10.11.150.76:5000/centos          7                   5ddf34d4d69b        8 months ago        172.2 MBpub.domeos.org/kubernetes/pause   latest              f9d5de079539        20 months ago       239.8 kB
复制代码

此时查看/opt 磁盘使用率达到了 51%,然后将使用 10.11.150.76:5000/centos:7 镜像的 pod 删除,手工将对应的容器 docker rm 掉,等待 GC 的镜像回收时间点。然而五分钟过去了,十分钟过去了,docker images 时 centos 镜像依旧顽固地坚守在阵地。

结论:目前 Kubernetes 的镜像垃圾回收策略可以在 docker  --graph 参数默认为 /var/lib/docker 时正常工作,当 --graph 设置为其它磁盘路径时还存在 bug。

问题反馈在 Github 的相关 issue 里:https://github.com/kubernetes/kubernetes/issues/17994,可以继续跟进。

Append: 根据 Github 上的反馈,这个 bug 将在后续版本中解决,目前版本需要让设置了--graph 的镜像垃圾回收生效,在启动 kubelet 时还需要加上参数 --docker-root=<docker --graph参数值>

  1. 容器回收之 --maximum-dead-containers-per-container 参数

启动 kubelet 设置容器回收相关参数如下:

--maximum-dead-containers-per-container=1 --minimum-container-ttl-duration=30s --maximum-dead-containers=100
复制代码

创建一个只包含一个容器且该容器一运行就退出的 pod,此时在 node 节点上可以看到该 pod 中的容器不断的创建退出创建退出:

[@tc-151-100 /home/domeos]# docker ps -aCONTAINER ID        IMAGE                                    COMMAND             CREATED             STATUS                      PORTS               NAMES2fe969499164        10.11.150.76:5000/centos:7               "/bin/bash"         4 seconds ago       Exited (0) 2 seconds ago                        k8s_iperf1.57dfe29d_test-gc-pod-exit_default_92e8bd05-e9e6-11e5-974c-782bcb2a316a_68cc6f03555b5e7a8550        10.11.150.76:5000/centos:7               "/bin/bash"         24 seconds ago      Exited (0) 22 seconds ago                       k8s_iperf1.57dfe29d_test-gc-pod-exit_default_92e8bd05-e9e6-11e5-974c-782bcb2a316a_ad4a5e3994b30a0b32c2        10.11.150.76:5000/centos:7               "/bin/bash"         34 seconds ago      Exited (0) 32 seconds ago                       k8s_iperf1.57dfe29d_test-gc-pod-exit_default_92e8bd05-e9e6-11e5-974c-782bcb2a316a_4027e3e1d458e6a7d396        pub.domeos.org/kubernetes/pause:latest   "/pause"            34 seconds ago      Up 33 seconds                                   k8s_POD.bdb2e1f5_test-gc-pod-exit_default_92e8bd05-e9e6-11e5-974c-782bcb2a316a_09798975
复制代码

GC 的容器回收时间点到达时,可以看到创建时间大于 30 秒的已退出容器只剩下一个(pause 容器不计算),且先创建的容器被优先删除:

[@tc-151-100 /home/domeos]# docker ps -aCONTAINER ID        IMAGE                                    COMMAND             CREATED             STATUS                      PORTS               NAMES5aae6157aeff        10.11.150.76:5000/centos:7               "/bin/bash"         46 seconds ago      Exited (0) 45 seconds ago                       k8s_iperf1.57dfe29d_test-gc-pod-exit_default_92e8bd05-e9e6-11e5-974c-782bcb2a316a_f126d2a8d458e6a7d396        pub.domeos.org/kubernetes/pause:latest   "/pause"            2 minutes ago       Up 2 minutes                                    k8s_POD.bdb2e1f5_test-gc-pod-exit_default_92e8bd05-e9e6-11e5-974c-782bcb2a316a_09798975
复制代码

结论:Kubernetes 容器垃圾回收的--maximum-dead-containers-per-container参数设置可正常工作。

  1. --maximum-dead-containers-per-container 针对容器还是容器集

启动 kubelet 设置容器回收相关参数如下:

--maximum-dead-containers-per-container=1 --minimum-container-ttl-duration=30s --maximum-dead-containers=100
复制代码

创建一个包含三个容器且这些容器一运行就退出的 pod,此时在 node 节点上可以看到该 pod 中的容器不断的创建退出创建退出:

[@tc-151-100 /home/domeos]# docker ps -aCONTAINER ID        IMAGE                                    COMMAND             CREATED             STATUS                      PORTS               NAMESdec04bd28a03        10.11.150.76:5000/centos:7               "/bin/bash"         7 seconds ago       Exited (0) 6 seconds ago                        k8s_iperf1.57dfe29d_test-gc-pod-exit_default_d1677c09-e9e7-11e5-974c-782bcb2a316a_830a93757c94d4a963a7        10.11.150.76:5000/centos:7               "/bin/bash"         7 seconds ago       Exited (0) 6 seconds ago                        k8s_iperf3.5c8de29f_test-gc-pod-exit_default_d1677c09-e9e7-11e5-974c-782bcb2a316a_975d44d34f3e7e8ddfd5        10.11.150.76:5000/centos:7               "/bin/bash"         8 seconds ago       Exited (0) 7 seconds ago                        k8s_iperf2.5a36e29e_test-gc-pod-exit_default_d1677c09-e9e7-11e5-974c-782bcb2a316a_d024eb06cb48cf2ba133        10.11.150.76:5000/centos:7               "/bin/bash"         12 seconds ago      Exited (0) 11 seconds ago                       k8s_iperf3.5c8de29f_test-gc-pod-exit_default_d1677c09-e9e7-11e5-974c-782bcb2a316a_b5ff7373ec2941f046f0        10.11.150.76:5000/centos:7               "/bin/bash"         13 seconds ago      Exited (0) 12 seconds ago                       k8s_iperf2.5a36e29e_test-gc-pod-exit_default_d1677c09-e9e7-11e5-974c-782bcb2a316a_69b1a996f831e8ed5687        10.11.150.76:5000/centos:7               "/bin/bash"         13 seconds ago      Exited (0) 12 seconds ago                       k8s_iperf1.57dfe29d_test-gc-pod-exit_default_d1677c09-e9e7-11e5-974c-782bcb2a316a_fbc02e2eee972a4537fc        pub.domeos.org/kubernetes/pause:latest   "/pause"            14 seconds ago      Up 13 seconds                                   k8s_POD.bdb2e1f5_test-gc-pod-exit_default_d1677c09-e9e7-11e5-974c-782bcb2a316a_85b3c032
复制代码

GC 的容器回收时间点到达时,可以看到创建时间大于 30 秒的已退出容器剩下三个(pause 容器不计算),且这三个容器正好是一组:

[@tc-151-100 /home/domeos]# docker ps -aCONTAINER ID        IMAGE                                    COMMAND             CREATED              STATUS                      PORTS               NAMESe4351e6855ae        10.11.150.76:5000/centos:7               "/bin/bash"         51 seconds ago       Exited (0) 50 seconds ago                       k8s_iperf3.5c8de29f_test-gc-pod-exit_default_d1677c09-e9e7-11e5-974c-782bcb2a316a_263dd820990baa6e6a7a        10.11.150.76:5000/centos:7               "/bin/bash"         52 seconds ago       Exited (0) 51 seconds ago                       k8s_iperf2.5a36e29e_test-gc-pod-exit_default_d1677c09-e9e7-11e5-974c-782bcb2a316a_b16b5eaac6916fb06d65        10.11.150.76:5000/centos:7               "/bin/bash"         53 seconds ago       Exited (0) 51 seconds ago                       k8s_iperf1.57dfe29d_test-gc-pod-exit_default_d1677c09-e9e7-11e5-974c-782bcb2a316a_1d8ea284ee972a4537fc        pub.domeos.org/kubernetes/pause:latest   "/pause"            About a minute ago   Up About a minute                               k8s_POD.bdb2e1f5_test-gc-pod-exit_default_d1677c09-e9e7-11e5-974c-782bcb2a316a_85b3c032
复制代码

结论:--maximum-dead-containers-per-container 的计数针对一个 pod 内的容器集而不是容器的个数。

  1. 容器回收之 --maximum-dead-containers 参数

启动 kubelet 设置容器回收相关参数如下:

--maximum-dead-containers-per-container=2 --minimum-container-ttl-duration=30s --maximum-dead-containers=3
复制代码

创建一个包含三个容器的 pod,再删除该 pod,再创建该 pod,再删除该 pod,这样就产生了 8 个已退出容器(包括两个 pause 容器):

[@tc-151-100 /home/domeos]# docker ps -aCONTAINER ID        IMAGE                                    COMMAND             CREATED             STATUS                              PORTS               NAMESa28625d189df        10.11.150.76:5000/centos:7               "/bin/bash"         1 seconds ago       Exited (0) Less than a second ago                       k8s_iperf3.5c8de29f_test-gc-pod-exit_default_c7612b59-e9ee-11e5-974c-782bcb2a316a_48c1120097aca44f0deb        10.11.150.76:5000/centos:7               "/bin/bash"         2 seconds ago       Exited (0) 1 seconds ago                                k8s_iperf2.5a36e29e_test-gc-pod-exit_default_c7612b59-e9ee-11e5-974c-782bcb2a316a_df34f48d4e57b6c839ae        10.11.150.76:5000/centos:7               "/bin/bash"         3 seconds ago       Exited (0) 2 seconds ago                                k8s_iperf1.57dfe29d_test-gc-pod-exit_default_c7612b59-e9ee-11e5-974c-782bcb2a316a_afd622b212588fce1433        pub.domeos.org/kubernetes/pause:latest   "/pause"            3 seconds ago       Exited (2) Less than a second ago                       k8s_POD.bdb2e1f5_test-gc-pod-exit_default_c7612b59-e9ee-11e5-974c-782bcb2a316a_c9d4cbaa621ed207d452        10.11.150.76:5000/centos:7               "/bin/bash"         4 seconds ago       Exited (0) 3 seconds ago                                k8s_iperf3.5c8de29f_test-gc-pod-exit_default_c5cbddbb-e9ee-11e5-974c-782bcb2a316a_a91278cd023c10fad4fd        10.11.150.76:5000/centos:7               "/bin/bash"         5 seconds ago       Exited (0) 4 seconds ago                                k8s_iperf2.5a36e29e_test-gc-pod-exit_default_c5cbddbb-e9ee-11e5-974c-782bcb2a316a_6cc03f37756eb7bb4b53        10.11.150.76:5000/centos:7               "/bin/bash"         5 seconds ago       Exited (0) 4 seconds ago                                k8s_iperf1.57dfe29d_test-gc-pod-exit_default_c5cbddbb-e9ee-11e5-974c-782bcb2a316a_83312ec2d54bdc22773e        pub.domeos.org/kubernetes/pause:latest   "/pause"            6 seconds ago       Exited (2) 3 seconds ago                                k8s_POD.bdb2e1f5_test-gc-pod-exit_default_c5cbddbb-e9ee-11e5-974c-782bcb2a316a_ccb57220
复制代码

GC 的容器回收时间点到达时,可以看到已退出容器只剩下了三个,pause 容器也被回收了:

[@tc-151-100 /home/domeos]# docker ps -aCONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS                     PORTS               NAMESa28625d189df        10.11.150.76:5000/centos:7   "/bin/bash"         2 minutes ago       Exited (0) 2 minutes ago                       k8s_iperf3.5c8de29f_test-gc-pod-exit_default_c7612b59-e9ee-11e5-974c-782bcb2a316a_48c1120097aca44f0deb        10.11.150.76:5000/centos:7   "/bin/bash"         2 minutes ago       Exited (0) 2 minutes ago                       k8s_iperf2.5a36e29e_test-gc-pod-exit_default_c7612b59-e9ee-11e5-974c-782bcb2a316a_df34f48d4e57b6c839ae        10.11.150.76:5000/centos:7   "/bin/bash"         2 minutes ago       Exited (0) 2 minutes ago                       k8s_iperf1.57dfe29d_test-gc-pod-exit_default_c7612b59-e9ee-11e5-974c-782bcb2a316a_afd622b2
复制代码

结论:Kubernetes 容器垃圾回收的 --maximum-dead-containers 参数设置可正常工作;pause 容器也作为可回收容器被管理着;Tips 第 11 条第 3)点。

  1. --maximum-dead-containers 对于非 kubelet 管理的容器是否计数

在第 5 个实验的基础上,手工创建一个 container,等待 GC 的容器回收时间点到达,一分钟过去了,两分钟过去了,docker ps -a 显示的依然是 4 个容器:

[@tc-151-100 /home/domeos]# docker run -it 10.11.150.76:5000/openxxs/iperf:1.2 /bin/shsh-4.2# exitexit[@tc-151-100 /home/domeos]# docker ps -aCONTAINER ID        IMAGE                                 COMMAND             CREATED             STATUS                      PORTS               NAMES939b932dc7db        10.11.150.76:5000/openxxs/iperf:1.2   "/bin/sh"           2 minutes ago       Exited (0) 2 minutes ago                        backstabbing_aryabhataa28625d189df        10.11.150.76:5000/centos:7            "/bin/bash"         12 minutes ago      Exited (0) 12 minutes ago                       k8s_iperf3.5c8de29f_test-gc-pod-exit_default_c7612b59-e9ee-11e5-974c-782bcb2a316a_48c1120097aca44f0deb        10.11.150.76:5000/centos:7            "/bin/bash"         12 minutes ago      Exited (0) 12 minutes ago                       k8s_iperf2.5a36e29e_test-gc-pod-exit_default_c7612b59-e9ee-11e5-974c-782bcb2a316a_df34f48d4e57b6c839ae        10.11.150.76:5000/centos:7            "/bin/bash"         12 minutes ago      Exited (0) 12 minutes ago                       k8s_iperf1.57dfe29d_test-gc-pod-exit_default_c7612b59-e9ee-11e5-974c-782bcb2a316a_afd622b2
复制代码

结论:Kubernetes 容器垃圾回收的策略不适用于非 kubelet 管理的容器。

发布于: 刚刚阅读数: 5
用户头像

学如逆水行舟,不进则退 2022.08.05 加入

大型企业CTO,专注大数据、架构框架、集群、中间件、分布式、数据库、监控、开源、基础架构等技术分享,助力数字化转型。

评论

发布
暂无评论
Kubernetes rubbish如何回收_开源_CTO技术共享_InfoQ写作社区