跳至主要内容

k8s 源码阅读 -- eviction

1 前言

在某些情况下 k8s 会出现 evicted 的 pod, 然而这并不在 pod 的生命周期中.这就是 k8s 的驱逐机制。
当机器的一些资源(内存、磁盘)过小时,为了保证 node 不会受到影响,会将 pod 驱逐至其他的机器上

2 资料

可以在 这里看到相关资料
来看一下代码中,驱逐策略是怎样实现的

3 代码详解

3.1 代码参考

3.2 详细

pkg/kubelet/apis/kubeletconfig/v1beta/default.go
32722122718_1572e6d5f8_b.jpg
定义了这几个默认值作为阈值
pkg/kubelet/kubelet.go
45682032475_c351bb5a24_b.jpg
kubelte 初始化了 eviction manager
在 runtime 相关模块被加载时,eviction manager 被加载进来
开始了 evict 相关的控制循环
46544499692_f17b40623e_b.jpg
接下来是 evict 真正工作的代码
代码目录是 pkg/kubelet/eviction/
主要看该目录下的两个文件 evictionmanager.go helpers.go
pkg/kubelet/eviction/evictionmanager.go
45682035215_2626ecb6e8_b.jpg
Start 是 evict manager 的入口
这里是一个死循环
循环中的主要函数是 synchronize 用来清理 pod、同步信息。这个就是今天的主角
先看一下 synchronize 的参数 diskInfoProvider podFunc
diskInfoProvider 是一个接口,用来提供磁盘的信息,作为是否发生驱逐的依据。实际函数在 pkg/kubelet/stats/ 下
synchronize 中仅用到了 HasDedicatedImageFs
45682036895_fecd046501_b.jpg
podFunc 用来获取一个待检查的 pod 列表,实际函数在 pkg/kubelet/kubeletpods.go
45682037835_a61dbf97f4_z.jpg
首先检查 imagesfs, 数据从 cadvisor 中获取
获得容器信息和 kubelet 总计状态
45682038825_801ed86d5b_b.jpg
summaryProvider 的实际函数在 /pkg/kubelet/server/stats/summary.go
45682039865_44700d76bc_b.jpg
开始监视当前的系统状态
45682040825_feceda2ba5_b.jpg
监视这些数据 Node.Memory allocatableContainer.Memory nodeFs.AvailableBytes nodeFs.InodesFree Node.Runtime.ImageFs NumOfRunningProcesses
比较阈值与观测到的数据
44778622920_332cbcf3bc_b.jpg
44778624040_7edf283c68_b.jpg
对数据去重、记录时间、确定在一段时间内仍处于不良状态
44778625000_42d002c4c0_b.jpg
开始进行驱逐
如果 apiserver 中 LocalStorageCapacityIsolation 这个参数为 true (1.10 默认打开), 那么 localstorage 的驱逐仅会发生在 localStorageEviction 内部
45682044695_544c531a82_b.jpg
45872227604_35e54ffcd8_b.jpg
根据之前获得的信息与并于阈值做比较之后,小于阈值的资源的 pod 列表,并将其排序
45872228614_39e7c7b276_b.jpg
排序的方式如下
32722130918_16e98fe221_b.jpg
在执行驱逐前记录驱逐的时间
开始驱逐
32722131298_ce32ac6e3e_b.jpg
在 ExperimentalCriticalPodAnnotation (1.10 默认关闭) 打开的情况下, 如果即是 critical pod 又是 static pod 及不会出发驱逐
如果当前的资源不再是高于阈值的资源或者没有立即进行驱逐的信号则进行软驱逐-等待一段时间
否则直接杀掉 pod
Author: Byron.wang
Created: 2019-01-04 Fri 16:15

评论

此博客中的热门博文

在 LSF 中使用 docker 运行任务

LSF + Docker Table of Contents 1. 环境信息 2. 修改配置文件在 lsf 上启用 docker 3. 验证 4. 部署常见问题 5. 部署参考链接 1  环境信息 docker 18.09.5 Kernel Version: 3.10.0-862.11.6.el7.x86_64 lsf 10.1.0.6 OS CentOs 7.6.1810 2  修改配置文件在 lsf 上启用 docker 1.conf/lsf.conf 添加/修改 LSF_PROCESS_TRACKING=Y LSF_LINUX_CGROUP_ACCT=Y LSB_RESOURCE_ENFORCE="cpu memory" 2.conf/lsf.shared 添加 docker Boolean () () (Docker container) 3.conf/lsf.cluster 添加 $your-host-name ! ! 1 3.5 () () (docker) 4./conf/lsbatch/$clustername/configdir/lsb.applications 添加 Begin Application NAME = app1 CONTAINER = docker[image(ubuntu:latest) options(--rm --network=host --ipc=host -v /etc/passwd:/etc/passwd -v /etc/group:/etc/group) starter(root)] DESCRIPTION = Test Docker Application Profile 1 End Application 5.badmin reconfig 验证是否可用 3  验证 在非 root 用户下, bsub -app app1 -I cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=18.04 DISTRIB_CODENAME=bionic DISTRIB_DES

Python 中的 UUID

python 中的 uuid 代码参考 cpython/Lib/uuid.py 版本 3.7 什么是 UUID UUID 的全称是 Universal Unique Identifier,中文名是 通用唯一标识符; wikipedia 上 UUID 的定义是 a 128-bit number used to identify information in computer systems UUID 需要满足两个条件: 128 bit 具有标识别计算机系统的能力 UUID 的规则 格式 将 16 个 8 位字节表示成 32 个十六进制数 按照 8-4-4-4-12 的格式加上 4 个连字符 “-‘ 版本 UUID 应该是下面的这种格式 xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx 其中 M 开始的 4 位表示版本,N 开始的 4 位表示变种 Name                        Length(bytes)    Length(hex digits)                       Contents time_low                         4                             8                  integer giving the low 32 bits of the time time_mid                         2                             4                  integer giving the middle 16 bits of the time| time_hi_and_version      2                              4                  4-bit “version” in the most significant bits,                                                                                               fol