Kubernetes如何管理pod更高可用

容器启动异常后重启

如果容器直接启动失败(如业务进程异常退出),那么Kubelet会尝试在本机重启容器,尝试间隔时间按照指数递增(10s,20s,40s...),最长不超过5分钟

引入探针机制判断业务是否正常

当业务容器启动成功后,Kubelet只能知道容器已经处于运行状态,但容器里面运行应用的真实状态就不得而知了。为此,Kubelet引入了探针机制,Kubelet支持两种探针LivenessProbe和ReadinessProbe。

LivenessProbe(存活探针):探测容器中的应用是否正在运行。如果探测失败,Kubelet会终止容器,并根据“重启策略”重建容器。如果设置存活探针,默认状态为Success,LivenessProbe的SuccessThreshold为1。

ReadinessProbe(绪探探针):探测容器中,应用是否准备好服务请求。如果探测失败,端点控制器将从与Pod匹配的所有Service端点中删除该Pod的IP地址。初始延迟之前的就绪状态默认为Failure。如果容器不提供就绪探针,则默认状态为Success。

那么在什么条件下使用存活(liveness)或就绪(readiness)探针呢?

如果容器中的应用能够在遇到问题或不健康的情况下自行崩溃,则不一定需要存活探针,Kubelet根据Pod的restartPolicy自动执行正确的操作。

如果应用在故障时仍然保持运行状态不退出,则需要借助存活探针,探测服务真实状态,并指定restartPolicy为Always或OnFailure。

应用启动是需要时间的。为了避免容器刚启动(此时应用还未启动)时,kube-proxy就直接将流量导入容器引发的错误,需要引入就绪探针。探测成功后,才开始将业务流量导入Pod。(如果是多个副本,根据业务量进行弹缩副本,引入就绪探针,外部访问时就可以避免访问到还没有启动完成的pod。如果是单个副本或者固定副本数,个人觉得并不需要就绪探针)

通常存活探针和就绪探针使用相同的探测方式来检测应用状态:

1)ExecAction:在容器内执行指定命令。如果命令退出时,返回码为0,则认为探测成功。

2)TCPSocketAction:对指定端口上的容器IP地址进行TCP检查。如果端口打开,则诊断为成功。这个可以理解为telnet端口,查看是否被监听。

3)HTTPGetAction:对指定的端口和路径上的容器IP地址发送HTTP Get请求。如果响应的状态码大于等于200,并且小于400,则认为探测成功。

PostStart和PreStop

在一个Pod的生命周期中,Kubernetes提供了两个钩子函数,一个是容器启动之后PostStart,另一个是容器关闭前PreStop。

由于PostStart和容器Entrypoint是异步执行的,Kubernetes并不能保证PostStart一定是在Entrypoint之后执行的,但如果PostStart一直无法结束,那么Pod将无法进入Running状态,所以PostStart通常可以在短时间内完成任务,不会驻留太长时间。

PreStop一定是在容器关闭之前执行,执行完成后,才会继续执行关闭操作。如果PreStop在关闭时间(默认30s)之内无法完成时,将强制停止,并将关闭时间设置成2s,继续执行之后的关闭操作。

PostStart和PreStop的配置方式和探针配置非常相似,都支持Exec(命令行)和HTTP请求两种方式。

以上官网提供的一个PostStart和PreStop的案例,目的是在容器启动后输出一段内容到message文件中,以及在容器关闭前停止nginx服务。

另一个案例:SpringCloud应用都是通过统一的服务注册发现中心eureka,在应用的服务端添加preStop的hook可以完成容器关闭前,通知eureka摘除服务节点,从而避免客户端报错500。

pod驱赶

Kubernetes通过资源调度算法将资源公平合理地分配给每一个Pod,从而能充分利用资源,达到资源的最优分配。集群资源有可能不足,为了保障高优先级任务的稳定运行,引入了QoS的概念。QoS通过释放低优先级任务占用资源,转移给高优先级任务,从而保障高优先级任务的执行,那么Kubernetes如何做到Pod分优先级的呢?Pod的QoS分级从高到低分为三个级别:Guaranteed、Burstable和Best-Effort。

Guaranteed级别是指Pod中所有容器都必须设置limit。如果有一个容器设置了request,那么所有的容器都要设置,并且针对每个容器的request和limit必须相等。如果一个容器只设置了limit,而未设定request,则request值等于limit值。

Burstable级别是指Pod中只要有一个容器的request和limit的设置不相同,该Pod的QoS即为Burstable。

Best-Effort是指Pod中所有容器的request和limit均未设置。

疑问:容器的request和limit是人为设置的,那么QoS是Kubernetes根据人为设置的request和limit来自动判断是某个级别还是人为设置?

为了保证高优先级Pod(如果pod和容器是一对一,这个地方说是容器也可以)的稳定运行,Kubelet引入了Pod驱赶策略,将优先级较低的Pod驱赶到其他节点运行。那么何时会触发驱赶呢?Kubelet设置Pod的驱赶条件主要包括memory.available(节点内存可用值)、nodefs.available (文件系统存储可用值)、nodefs.inodesFree(inode可用值)、imagefs.available(镜像文件系统存储可用值)和imagefs.inodesFree(镜像文件系统inode可用值)这五个指标。

备注:QoS三个级别是针对Pod所有资源的,包括Pod的内存和存储。此处的驱赶条件是某个节点上所有Pod的资源占用之和是否达到该节点上因资源的使用情况设置的驱赶条件(奇怪的是,没啥没有CPU资源?)。

如果Kubelet启动参数设置memory.available<10%或者memory.available<1Gi后,当Kubelet所在主机剩余可用内存不足10%或者1GB后,将会触发驱赶动作。

Kubelet驱赶的阈值分为软硬两个值,软阈值是指当节点满足该阈值后,Kubelet允许业务Pod优雅停止,硬阈值则是会触发Kubelet强制杀死Pod并且会标注节点处于不健康状态(内存不足MemoryPressure、磁盘不足DiskPressure),从而阻止新Pod在调度时候分配到该节点。

除了上面介绍的QoS优先级以外,在Kubernetes 1.8版本引入了PriorityClass(优先级)和Preemption(抢占)功能,但直到Kubernetes 1.14,该功能才进入稳定版本。之前版本的Scheduler在出现资源不足时,新的容器将会一直处于等待调度状态(Pending),直到运维人员手动添加新资源,或者删除其他容器后,这些容器才有可能被重新调度。为了保障高优先级任务的执行,引入了Pod优先级和抢占机制,这保证了高优先级的任务首先被调度,并且在整个集群资源不足的情况下,终止低优先级任务,从而保障高优先任务的稳定执行。

OMM killer

在驱赶后,主机上面的资源可能仍然无法满足要求,此时便会触发Linux内核的OOM killer,它会终止优先级较低的进程,保障系统继续运行。

在Kubelet启动容器时,不同优先级的容器会设置对应的OOM分数(分数越大,优先级越低,在资源不足时,将首先被回收),默认的OOM分数如下。

Burstable级别Pod的OOM分数则是通过下面公式计算得出的,可见Pod申请的内存越多,OOM分数越低,优先级越高。

为了保障Pod不被OOM,请将优先高的任务设置成guaranteed。

亲和与反亲和调度策略和排除策略

之后的Kubernetes又引入了亲和(Affinity)和反亲和(Anti-affinity)调度策略,可以更加灵活地设置容器和容器,以及容器和节点之间的调度关系。亲和和反亲和策略主要分为3个场景:节点亲和、Pod亲和及Pod反亲和,每种场景下都有两种策略:RequiredDuringSchedulingIgnoredDuringExecution (调度时必须满足规则)和PreferredDuringScheduling IgnoredDuringExecution(调度时可选满足规则)。

通过上面的亲和/反亲和策略能够很好地控制容器调度到某些节点。除此外,Kubernetes还提供一种排除策略,控制容器不调度到某些节点上,通过为主机添加Taint (污点)和为Pod添加Tolerations(容忍)的方式完成。

节点支持设置3种污点策略:NoSchedule (严格不调度)、PreferNoSchedule(最好不调度)及NoExecute(不允许运行)。当节点被设置为污点后,只有设置容忍测量Pod才能调度这个节点。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,137评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,824评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,465评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,131评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,140评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,895评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,535评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,435评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,952评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,081评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,210评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,896评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,552评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,089评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,198评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,531评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,209评论 2 357