kubernetes之pod中断
目标读者:
想要构建高可用应用的应用所有者,因此需要知道pod会发生哪些类型的中断
想要执行自动化(比如升级和自动扩容)的集群管理员.
自愿和非自愿的中断
pod不会自动消息,除非有人(可能是一个人或者一个控制器)把它销毁了,或者出现无法避免的硬件或者系统软件错误.
我们把这些称作非自愿的不可避免的应用中断.
以下是示例:
用于支撑节点的机会出现硬件故障
集群管理员误操作把VM(实例)删除了
虚拟机故障导致VM实例消失
kernel panic
由于网络分区导致集群节点消失
由于资源耗尽导致pod被驱离
除了资源耗尽外,其它情况大部分读者应该都非常熟悉,它们并不是kubernetes特有的.
我们称其它的情况为自愿中断.这包括集群管理员或者应用拥有者采取的动作.应用拥有者采取的典型动作有:
删除了管理pod的deployment或者其它控制器
更新了deployment的pod模板导致重启
直接删除pod(比如误删除)
集群管理员的动作有如下:
排干node以便升级或修复
排干一个node以便对集群缩容
从节点中删除一个pod以便可以做其它的事情
这些动作可能由集群管理者直接触发,或者自动触发,或者有集群服务提供者触发
询问集群管理员或者云服务提供商或者查询文档来确定是否触发了自愿中止.如果以上都没有发生,你可以跳过创建Pod Disruption Budgets
注意:并非所有的自愿中断都被
Pod Disruption Budgets
约束,比如删除deployment或者pod会绕过Pod Disruption Budgets
处理中断
以下是一些可以减轻非自愿中断的办法
确保pod请求需要的资源
如果你想要高可用,制作程序副本集
如果想要更高可用性,使用跨区域集群部署应用
自愿中断的频率根据实际情况往往也是不同的.在一个基础的集群上,可能根本不会有自愿的中断.但是集群管理员或者服务提供商可能会运行一些额外的服务导致自愿中断.比如滚动更新可能会导致自愿中断.一些自动集群扩容为了防止完整节点碎片化也会自愿中断.集群管理员或者服务提供商应该用文档把可能导致的自愿中断写出来,以便查询.
kubernetes提供了这样一种特性,当高频率自愿中断发生时仍然能够保证集群的高可用性,我们称之为Disruption Budgets
Disruption Budgets
有些资料上翻译为中断预算,但是更多的是没有翻译,大家只要知道它的大致意思就行了,这里也不做翻译
Disruption Budgets如何工作
应用所有者可以为每个应用创建一个PodDisruptionBudget(PDB)
对象.PDB限制一个包含副本集的集群由于自愿中断而同时宕掉的pod的个数.例如,一个基于仲裁投票的应用想要保证运行的副本数永远不会低于某个数量以便仲裁.一个web前端想要保证运行中的副本数不会低于某一比例.
集群管理员和服务提供商应当通过遵守Pod Disruption Budgets
的Eviction API而不是直接删除pod或者deployment.例如可以使用kubectl drain
当集群管理员想通过kubectl drain
命令来排干一个节点.命令会尝试排干节点机器上的所有pod.驱离请求可能会暂时被拒绝,命令会周期性的重新发送失败请求直到所有pod都终止,或者达到了设定的超时时间.
PDB规定了副本集可以容忍的副本集的数量(实际上是能容忍的最小值),这是相对于它期望的数量而言的.比如一个有.spec.replicas: 5
的deployment希望在任何时候都有五个副本,如果PDB允许有4个副本运行,则Eviction API
允许同一时刻有一个副本中断,而不是2个.
期望的副本数量由pod控制器通过pod的.spec.replicas
计算得出,控制器通过.metadata.ownerReferences
被pod发现
PDB不能阻止非自愿的中断发生,但是它们会被计入预算
由于被删除或者更新导到不可用的pod也会计入预算,但是控制器(比如deployment,stateful-set)滚动更新时不会被PDB限制,滚动更新导致的失败会计入控制器的spec里
当一个pod通过eviction API被驱离,它会优雅的中止(请看podspec里的terminationGracePeriodSeconds
)
PDB示例
比如集群有从node-1到node-3这样的3个节点.集群中运行着一些应用,其中一个有三个副本,叫作pod-a,pod-b和pod-c.此外还有一个无关的,包含PDB的pod称作pod-x,它们的初始分布情况如下:
node-1 | node-2 | node-3 |
---|---|---|
pod-a available | pod-b available | pod-c available |
pod-x available |
同一副本集的三个节点是一个deployment的一部分,它们共享一个PDB,要求它们三个中至少有2个同时运行着.
假如集群管理员想要重启节点以便修复一个内核bug,集群管理员首先尝试通过kubectl drain
命令来排干node-1节点.命令会尝试把pod-a和pod-x驱离节点node-1.命令马上执行成功,上面的pod同时进入terminating
状态.现在集群处于如下状态:
node-1 draining | node-2 | node-3 |
---|---|---|
pod-a terminating | pod-b available | pod-c available |
pod-x terminating |
deployment发现其中一个节点终止了.因此它创建了一个替代节点叫作pod-d,由于node-1被封锁,因此它会落到其它节点.其它的控制器也会创建一个pod-y来替代pod-x
注意,对一StatefulSet,pod-a可能叫作pod-1,需要在被替代之前完全终止,它仍然叫作pod-a,但是PID可能不同了.除此之外(pod的名字的区别),这个例子也适用于StatefulSet.
现在集群处于如下状态:
node-1 draining | node-2 | node-3 |
---|---|---|
pod-a terminating | pod-b available | pod-c available |
pod-x terminating | pod-d starting | pod-y |
在某一个时间点,node-a上的节点被终止,现在集群的状态如下
node-1 drained | node-2 | node-3 |
---|---|---|
pod-b available | pod-c available | |
pod-d starting | pod-y |
此时,如果一个没有耐心的集群管理员尝试排干node-2或者node-3,排干命令会被阻止,因为只有两个可用的节点,它的PDB要求至少运行2个,过一段时间,pod-d变得可用
node-1 drained | node-2 | node-3 |
---|---|---|
pod-b available | pod-c available | |
pod-d available | pod-y |
此时,如果集群管理员尝试排干node-2,排干命令会以一定顺序驱离上面的两个pod,比如说先是pod-b然后是pod-d,它会成功驱离pod-b.但是当尝试驱离pod-d的时候会被拒绝,因为这会导致deployment只有一个可用pod
pod-b被驱离后并不会马上在其它节点上落地开始工作,也就是这个节点的替代节点并不能马上工作,此时如果再驱离pod-d会导致只有pod-c是可用的,因此会被拒绝.
deployment创建了一个pod-b的替代叫作pod-e,由于集群没有足够资源来调度pod-e因此此时drain会再入陷入阻塞.集群最终的状态如下:
node-1 drained | node-2 | node-3 | no node |
---|---|---|---|
pod-b available | pod-c available | pod-e pending | |
pod-d available | pod-y |
此时,集群管理员需要添加一个节点来让升级继续.
你可以看到基于以下原因,kubernetes怎样控制中断的速率:
集群需要多少个副本
优雅地中止一个实例需要多长时间
一个新的实例启动需要多长时间
控制器的类型
集群资源容量
分离集群拥有者和应用拥有者的角色
通常,把集群管理者和应用拥有者看作是对对方知之甚少不同的角色是有用的.这种职责分离在以下情形是有意义的:
多个开发团队使用同一个集群,这时候有一个中立的专家角色
当一些第三方工具或者服务被用来做集群的自动化管理工作.
怎样在集群中执行有中断性的动作
如果你是集群管理员,由于节点或者系统软件升级,你可能需要对集群的所有节点执行可能产生中断的动作,有以下选项:
升级过程中接受宕机时间
故障转移到一个完整的副本集群中.这能够保证没有宕机时间,但是可能需要花费高价钱来复制节点和花费人力来编排切换
使用能容忍中断的程序和使用PDB
没有宕机时间
最小量资源复制
允许更多的集群自动化管理
编写能容忍中断的程序是很有技巧的,但是容忍中断的工作很大部分是与支持自动扩容和容忍非自愿中断是重叠的
kubernetes之pod中断的更多相关文章
- kubernetes调度pod运行于master节点上
应用背景: 使用kubeadm部署的kubernetes集群,其master节点默认拒绝将pod调度运行于其上的,加点官方的术语就是:master默认被赋予了一个或者多个“污点(taints)”,“污 ...
- Kubernetes探索学习004--深入Kubernetes的Pod
深入研究学习Pod 首先需要认识到Pod才是Kubernetes项目中最小的编排单位原子单位,凡是涉及到调度,网络,存储层面的,基本上都是Pod级别的!官方是用这样的语言来描述的: A Pod is ...
- Kubernetes之Pod使用
一.什么是Podkubernetes中的一切都可以理解为是一种资源对象,pod,rc,service,都可以理解是 一种资源对象.pod的组成示意图如下,由一个叫”pause“的根容器,加上一个或多个 ...
- kubernetes之pod健康检查
目录 kubernetes之pod健康检查 1.概述和分类 2.LivenessProbe探针(存活性探测) 3.ReadinessProbe探针(就绪型探测) 4.探针的实现方式 4.1.ExecA ...
- Kubernetes基石-pod容器
引用三个问题来叙述Kubernetes的pod容器 1.为什么不直接在一个Docker容器中运行所有的应用进程. 2.为什么pod这种容器中要同时运行多个Docker容器(可以只有一个) 3.为什么k ...
- kubernetes concepts -- Pod Overview
This page provides an overview of Pod, the smallest deployable object in the Kubernetes object model ...
- kubernetes删除pod一直处于terminating状态的解决方法
kubernetes删除pod一直处理 Terminating状态 # kubectl get po -n mon NAME READY STATUS RESTARTS AGE alertmanage ...
- Kubernetes服务pod的健康检测liveness和readiness详解
Kubernetes服务pod的健康检测liveness和readiness详解 接下来给大家讲解下在K8S上,我们如果对我们的业务服务进行健康检测. Health Check.restartPoli ...
- Kubernetes之POD
什么是Pod Pod是可以创建和管理Kubernetes计算的最小可部署单元.一个Pod代表着集群中运行的一个进程. Pod就像是豌豆荚一样,它由一个或者多个容器组成(例如Docker容器),它们共享 ...
随机推荐
- Codeforces 899D Shovel Sale
题目大意 给定正整数 $n$($2\le n\le 10^9$). 考虑无序整数对 $(x, y)$($1\le x,y\le n, x\ne y$). 求满足 「$x+y$ 结尾连续的 9 最多」的 ...
- 正则表达式的\b与\B总结
\b 单词边界,是指单词与符号之间的边界,是一个位置,不是空格或字符.(这里单词可以是中文字符,英文字符,数字: 符号可以是中文符号,英文符号,空格,制表符,换行).不能与量词?+*{1}{2,5} ...
- spring boot-html和templates
静态页面 spring boot项目只有src目录,没有webapp目录,会将静态访问(html/图片等)映射到其自动配置的静态目录,如下 /static /public /resources / ...
- poj 3468 线段树成段更新
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 54012 ...
- C语言第三题
1.完成char *p,char *q 的字符串比较,相等返回1,错误返回-1 2.用户需要计算的2个20位数数字的加法,写程序实现让用户输入两个20位以上的数字并且相加,输出结果
- bzoj 3208 花神的秒题计划I
bzoj 3208 花神的秒题计划I Description 背景[backboard]: Memphis等一群蒟蒻出题中,花神凑过来秒题-- 描述[discribe]: 花花山峰峦起伏,峰顶常年被雪 ...
- Crash的数字表格 BZOJ 2154 / jzptab BZOJ 2693
jzptab [问题描述] 求: 多组询问 [输入格式] 一个正整数T表示数据组数 接下来T行 每行两个正整数 表示N.M [输出格式] T行 每行一个整数 表示第i组数据的结果 [样例输入] 1 4 ...
- node总结--回调函数阻塞和非阻塞代码实例
阻塞代码实例: var fs = require("fs"); var data = fs.readFileSync('input.txt'); console.log(data. ...
- 获取cookie中的某个参数值
因为cookie的值是很多key=value连接起来的字符串,所以如果要取cookie中某个key的值: function getCookie(name) { let cookieValue = nu ...
- Epoll详解及源码分析【转】
转自:http://blog.csdn.net/chen19870707/article/details/42525887 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] ...