最近在公司的线上服务器上发现了一个现象: 将某个node的kubelet短暂的停掉之后,其上的pod马上会被驱逐,这让笔者大吃一惊,印象之中,停掉kubelet后,该node会变为NotReady状态,随后controller-manger会经过一段时间才开始驱逐其上的pod。还有个参数专门来控制这个时间:

--pod-eviction-timeout The grace period for deleting pods on failed nodes. (default 5m0s)`

该参数默认值为5min, 也就是说当node NotReady之后,最少也得五分钟之后其上的pod才会被驱逐。但是现实情况明显不符合预期啊,这样就有点奇怪了。
鉴于该问题影响巨大,笔者果断开启了debug之旅。

首先我们从直接原因下手,需要了解一下当node NotReady之后,controller-manager是如何判断并驱逐其上的pod的,这部分工作是由node lifecycel controller模块负责。

node lifecycle controller 主要负责对node生命周期进行检查,判断node是否存活,如果长时间检测不到node心跳则驱逐其上的pod。在目前的版本(v1.16)中,默认开启了TaintBasedEvictions, TaintNodesByCondition这两个feature gate,则所有node生命周期管理都是通过condition + taint的方式进行管理。其主要逻辑由三部分组成:

  1. 不断地检查所有node状态,设置对应的condition
  2. 不断地根据node condition 设置对应的taint
  3. 不断地根据taint驱逐node上面的pod

想要详细了解node lifecycle controller工作机制的同学可以翻阅笔者上一篇文章: kubernetes中node心跳处理逻辑分析

查看代码发现--pod-eviction-timeout并未起作用,原来在v1.13版本之前TaintBasedEvictions功能还未开启,此时node not-ready之后,controller直接判断not-ready时间是否超过了--pod-eviction-timeout,超过就进行删除。而v1.13,TaintBasedEvictions功能开启之后就不会使用了该参数,转而使用了上面描述的condition+taint方案。也就是说node NotReady之后,pod的驱逐时间完全由每个pod toleration中 tolerationSecond决定,而不是由controller-manager的参数--pod-eviction-timeout统一决定。这样想想也合情合理,每个pod对于故障的容忍时间不同,tolerationSecond可以更加灵活地为每个pod指定不同的驱逐时间。

这样说来,所有的pod都需要设置一个toleration才对,查阅相关资料后发现,社区已经有了一个DefaultTolerationSeconds admisson controller自动地帮助我们设置toleration,每次创建更新pod, 在请求发送到apiserver之后会自动设置5min的默认toleration。

This admission controller sets the default forgiveness toleration for pods to tolerate the taints notready:NoExecute and unreachable:NoExecute for 5 minutes, if the pods don’t already have toleration for taints node.kubernetes.io/not-ready:NoExecute or node.alpha.kubernetes.io/unreachable:NoExecute.

文档上显示该admission controller默认开启,但是为什么我司的环境上面没有生效,仔细看了一下文档,是因为自己使用了一个deprecated的参数:--admission-control,使用这个参数的话必须显式指定所有要开启的admisson controller plugin列表。该参数在v1.10被废弃,由两个新的参数--enable-admission-plugins--disable-admission-plugins替换,这两个参数如果不指定的话会有默认值,其中DefaultTolerationSeconds就属于--enable-admission-plugins参数的默认值之一,也就是会默认开启该plugin。又是一个升级导致的坑! 正确修改了该参数之后,新创建的pod就会默认带上了toleration,DefaultTolerationSeconds adminssion controller plugin总算生效了。 

新创建的pod总算没有问题了,但是对于集群中已经存在的pod还没有toleration该怎么办? 显然社区对这种情况未做处理,DefaultTolerationSeconds是社区很早就开发的一个feature,但是TaintBasedEvictions是v1.13才默认开启,估计社区在开发时前后没有做好兼容。翻了下DefaultTolerationSecondsadminssion plugin源码,发现该plugin对于pod create, update操作都会设置toleration, 所以一般情况下, 我们升级集群的时候,总是能触发pod发生update,该toleration会自动添加上,无需过多操作,大可不必担心,心里知道有这个事情并检查一下就行。但是笔者的环境已经升级完成了,只能手动触发pod update了,思来想去,想要触发pod update又不能影响业务,给pod打label是一个比较好的方式,于是笔者写了一个脚本将集群中所有的pod都打了一个无关紧要的label, 触发uodate后就自动添加了toleration。

至此整个修复工作全部完成,回过头来仔细想想,kubernetes版本间升级挑战还是挺大的,兼容性问题防不胜防,很可能两个小版本间完全兼容,没任何问题,但是当一步步从低版本升级上来的时候问题就出现了,而且在兼容性测试的时候难以覆盖到每种情况,很可能需要很久问题才能暴露出来。对于这种情况,唯有掌握内部机理,熟读源码才能快速诊断,修复。

记一次kubernetes驱逐踩坑的更多相关文章

  1. Kubernetes探针踩坑记

    1. 荒腔走板 最近一两个月生产K8s集群频繁出现短时503 Service Temporarily Unavailable,还不能主动复现,相当郁闷,压力山大. HTTP 5xx响应状态码用于定义服 ...

  2. 记一次FTP下载踩坑的故(shi)事(gu)

    下班前领导忽然要求我将客户的日志服务器上一些日志拷贝到测试服务器中,不过领导只提供给我FTP的连接方式,很明显就是要我用FTP方式去做啦 一般来说FTP批量下载也就上网随便找个脚本的事,但是却成了我疯 ...

  3. Mac上使用Docker Desktop启动Kubernetes,踩坑后终于搞掂

    1 前言 Kubernetes又简称k8s,是Google开源的容器集群管理系统,最近也是火热.闲来无事(为了发文),捣鼓了一下,在Mac上搭建Kubernetes,遇到一些坑,也记录一下. 另外,D ...

  4. 记一次pm2的踩坑

    1.问题: 公司采用了自动发布平台,最近突然发现一个问题,上线完成后服务是能正常访问的,但是有一个节点访问的时候每两次中总是有一次404,通过nginx的access日志分析发现第一次正常访问有一次g ...

  5. Kubernetes实践踩坑系列(一).应用管理的难题

    应用管理的两大难题  今天我们主要讨论这两个方面的挑战: 对应用研发而言,K8s API 针对简单应用过于复杂,针对复杂应用难以上手: 对应用运维而言,K8s 的扩展能力难以管理:K8s 原生的 AP ...

  6. IdentityServer 部署踩坑记

    IdentityServer 部署踩坑记 Intro 周末终于部署了 IdentityServer 以及 IdentityServerAdmin 项目,踩了几个坑,在此记录分享一下. 部署架构 项目是 ...

  7. Spark踩坑记——Spark Streaming+Kafka

    [TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...

  8. Spark踩坑记——数据库(Hbase+Mysql)

    [TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...

  9. 记jQuery.fn.show的一次踩坑和问题排查

    最近很少已经很少用jQuery,因为主攻移动端,常用Zepto,其实很多细节和jQuery并不一样.最近又无意中接触到了PC的需求和IE6, 使用了jQuery,刚好踩坑了,特意记录一下. 本文内容如 ...

随机推荐

  1. AttributeError: 'list' object has no attribute 'sorted'

    效果图: 解决办法: 原因: AttributeError: 'list' object has no attribute 'sorted' 属性错误: list对象没有sorted属性方法. sor ...

  2. ThinkPad全家族机型对比

    如图所示

  3. Http协议 Content-Type

    详情:https://www.cnblogs.com/ranyonsue/p/5984001.html *****Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面. ** ...

  4. Drupal SA-CORE-2019-010 .开头文件名(如.htaccess) 文件上传

    目录 drupal .开头文件名 文件上传 原生模块分析 第三方模块分析 补丁 参考 drupal .开头文件名 文件上传 通过diff 8.8.1的补丁,很容易发现修复点,位于core\module ...

  5. mongoskin 是让 Node.js 支持 MongoDB 的内嵌访问层。

    mongoskin 是让 Node.js 支持 MongoDB 的内嵌访问层.

  6. Java程序员学习Go语言—之一

    转载:https://www.luozhiyun.com/archives/206 GOPATH 工作空间 GOPATH简单理解成Go语言的工作目录,它的值是一个目录的路径,也可以是多个目录路径,每个 ...

  7. 创建dynamics CRM client-side (二) - Client API

    如果我们想用script来直接在form上做一些修改, 我们需要用到client api 来做交互. 我们可以用以下来理解: Form <---> Client API <---&g ...

  8. selenium,CSS定位法应用

    如图,下载按钮 查看其元素,是无法直接定位的,通过xpath也无法定位,转为firepath获取的CSS也是无效的#downloadItems>a 但是为经过firepath,直接在html下复 ...

  9. [校内训练19_09_02]A

    题意 给出N 个形如$f_i(x) = a_i x^2 + b_i x $的二次函数. 有Q 次询问,每次给出一个x,询问$max{\{f_i(x)\}}$.$N,Q \leq 5*10^5$. 思考 ...

  10. mysql--->innodb引擎什么时候表锁什么时候行锁?

    mysql innodb引擎什么时候表锁什么时候行锁? InnoDB基于索引的行锁 InnoDB行锁是通过索引上的索引项来实现的,这一点MySQL与Oracle不同,后者是通过在数据中对相应数据行加锁 ...