kubernetes容器删除时快速释放ip的方案

问题的来由

在kubernetes集群的生产中,常常遇到这样的一个问题,就是在应用大规模更新时,大量容器删除然后大量容器建立,建立的容器须要很长时间才能就绪。这其中一个可能的缘由,就是大量容器删除释放ip过于缓慢,致使新建立的容器没法及时获取ip,从而没法及时启动。api

这种状况广泛存在于ip池较小或者应用升级须要ip保持不变的情景下,具备较为广泛的意义。针对这一状况,笔者先前作过一个方案用以解决该问题,在这里与你们分享一下。网络

k8s容器删除的流程

首先,咱们先来梳理下容器删除的整个流程,看下为何会释放ip缓慢。kubernetes容器的整个删除流程基本套路以下:app

  1. 发送删除请求到apiserver,标记容器的deletionTimestamp
  2. kubelet watch到该事件,知道pod须要删除,进入删除流程
  3. pod执行killPod流程
  4. kill app容器
    1. 执行preStopHook
    2. 等待gracePeriod
    3. 中止app容器
  5. kill pause容器
    1. 调用cni接口,中止容器网络
    2. 中止pause容器
  6. 从apiserver中将pod的信息清除(真正删除掉存储在etcd的pod信息)

那么能够看到,ip的释放实际上是发生在调用cni接口的时候。所以,按照常规流程,其须要等待的时间为执行preStopHook的时间 + gracePeriod + 中止app容器的时间。这个时间对于但愿快速释放ip的情形下,是较为漫长的(通常要几十秒)。code

加速ip资源释放的方案与利弊

若是想要加速ip资源的释放,那么方式也就是显而易见的,就是在kubernetes的现有流程基础上进行定制开发,将cni的调用前置,将其提早到kill app容器以前server

特别注意,这里只是将cni接口调用提早,可是不要将中止pause容器提早,不然先中止pause容器可能会致使app容器中止时会有一些问题。接口

修改后的流程以下:事件

  1. 发送删除请求到apiserver,标记容器的deletionTimestamp
  2. kubelet watch到该事件,知道pod须要删除,进入删除流程
  3. pod执行killPod
  4. 调用cni接口,中止容器网络,释放容器ip
  5. kill app容器
    1. 执行preStopHook
    2. 等待gracePeriod
    3. 中止app容器
  6. kill pause容器
    1. 调用cni接口,中止容器网络(可选)
    2. 中止pause容器
  7. 从apiserver中将pod的信息清除(真正删除掉存储在etcd的pod信息)

这样的话,能够在第一时间尽快释放ip,而无需等待太久。ip

可是这样的方案也存在着很大的弊端,就是首先摘除了容器的网络,而若是preStopHook的执行或者中止app容器时须要依赖容器网络(好比应用须要调用某个接口才能进行下线等),可能会致使流程没法进行,容器被卡住,造成僵尸容器或者造成应用信息错误。资源

所以这个方案最好要作成可选的选项,在annotation中增长一个注解。然后根据应用的实际状况,选择是否使用快速释放ip的策略。开发

相关文章
相关标签/搜索