在kubernetes中,有HPA在需要的时候创建更多的pod实例。但万一所有的节点都满了,放不下更多pod了,怎么办?显然这个问题并不局限于Autoscaler创建新pod实例的场景。即便是手动创建pod,也可能碰到因为资源被已有pod使用殆尽,以至于没有节点能接收新pod的清况。

  在这种情况下,需要删除一些已有的pod, 或者纵向缩容它们,抑或向集群中添加更多节点。如果Kubernetes集群运行在自建基础架构上,那得添加一台物理机,并将其加入集群。但如果集群运行于云端基础架构之上,添加新的节点通常就是点击几下鼠标,或者向云端做API调用。这可以自动化的,对吧?

  Kubernetes支持在需要时立即自动从云服务提供者请求更多节点。该特性由Cluster Autoscaler执行。

1.Cluster Autoscaler介绍

  Cluster Autoscales负责在由于节点资源不足,而无法调度某pod到己有节点时,自动部署新节点。它也会在节点长时间使用率低下的情况下下线节点。

  从云端基础架构请求新节点

  如果在一个pod被创建之后,Scheduler无法将其调度到任何一个己有节点,一个新节点就会被创建。ClusterAutoscaler会注意此类pod,并请求云服务提供者启动一个新节点。但在这么做之前,它会检查新节点有没有可能容纳这个(些)pod,毕竟如果新节点本来就不可能容纳它们,就没必要启动这么一个节点了。

  云服务提供者通常把相同规格(或者有相同特性)的节点聚合成组。因此ClusterAutoscaler不能单纯地说“给我多一个节点”,它还需要指明节点类型。

  ClusterAutoscaler通过检查可用的节点分组来确定是否有至少一种节点类型能容纳未被调度的pod。如果只存在唯一一此种节点分组,ClusterAutoscaler就可以增加节点分组的大小,让云服务提供商给分组中增加一个节点。但如果存在多个满足条件的节点分组,ClusterAutoscaler就必须挑一个最合适的。这里“最合适”的精确含义显然必须是可配置的。在最坏的情况下,它会随机挑选一个。图15.5简单描述了ClusterAutoscaler面对一个不可调度pod时是如何反应的。

  新节点启动后,其上运行的Kubelet会联系API服务器,创建一个Node资源以注册该节点。从这一刻起,该节点即成为Kubernetes集群的一部分,可以调度pod于其上了。

  简单吧?那么缩容呢?

  归还节点

  当节点利用率不足时,Cluster Autoscaler也需要能够减少节点的数目。Cluster Autoscaler通过监控所有节点上请求的CPU与内存来实现这一点。如果某个节点上所有pod请求的CPU、内存都不到50%,该节点即被认定为不再需要。

  这并不是决定是否要归还某一节点的唯一因素。Cluster Autoscaler也会检查是否有系统pod(仅仅)运行在该节点上(这并不包括每个节点上都运行的服务,比如DaemonSet所部署的服务)。如果节点上有系统pod在运行,该节点就不会被归还。对非托管pod,以及有本地存储的pod也是如此,否则就会造成这些pod提供的服务中断。换句话说,只有当Cluster Autoscaler知道节点上运行的pod能够重新调度到其他节点,该节点才会被归还。

  当一个节点被选中下线,它首先会被标记为不可调度,随后运行其上的pod将被疏散至其他节点。因为所有这些pod都属于ReplicaSet或者其他控制器,它们的替代pod会被创建并调度到其他剩下的节点(这就是为何正被下线的节点要先标记为不可调度的原因)。

  手动标记节点为不可调度、排空节点

  节点也可以手动被标记为不可调度并排空。不涉及细节,这些工作可用以下kubectl命令完成:

    • kubectl cordon <node>标记节点为不可调度(但对其上的pod不做任何事)。
    • kubectl drain <node>标记节点为不可调度,随后疏散其上所有pod。

  两种情形下,在你用kubectl uncordon <node>解除节点的不可调度状态之前,不会有新pod被调度到该节点。

2.启用Cluster Autoscaler

  集群自动伸缩在以下云服务提供商可用:

    • Google Kubernetes Engine(GKE)
    • Google Compute Engine(GCE)
    • Amazon Web Services(AWS)
    • Microsoft Azure

  启动Cluster Autoscaler的方式取决于Kubernetes集群运行在哪。如果你的kubia集群运行在GKE上,可以这样启用Cluster Autoscaler :

$ gcloud container clusters update kubia --enable-autoscaling \
--min-nodes=3 --max-nodes=5

  如果集群运行在GCE上,需要在运行kubi-ub.sh前设置以下环境变量:

    • KUBE ENABLE CLUSTER AUTOSCALER=true
    • KUBE AUTOSCALER MIN NODES=3
    • KUBE AUTOSCALER MAX NODES=5

  可以参考https://github.com/kubemetes/auto-scaler/tree/master/cluster-autoscaler上的ClusterAutoscaler GitHub版本库,来了解在其他平台上如何启用它。

  注意:Cluster Autoscaler将它的状态发布到kube-system命名空间的cluster-autoscale-status ConfigMap上。

  至于很多云开启的方式去查找云平台的官方文档。

3.限制集群缩容时的服务干扰

  如果一个节点发生非预期故障,不可能阻止其上的pod变为不可用;但如果一个节点被Cluster Autoscaler或者人类操作员主动下线,可以用一个新特性来确保下线操作不会干扰到这个节点上pod所提供的服务。

  一些服务要求至少保持一定数量的pod持续运行,对基于quorum的集群应用而言尤其如此。为此,Kubernetes可以指定下线等操作时需要保持的最少pod数量,通过创建一个podDisruptionBudget资源的方式来利用这一特性。

  尽管这个资源的名称听起来挺复杂的,实际上它是最简单的Kubernetes资源之一。它只包含一个pod标签选择器和一个数字,指定最少需要维持运行的pod数量,从Kubernetes1.7开始,还有最大可以接收的不可用pod数量。看看PodDisruptionBudget(PDB)资源长什么样,但不会通过YAML文件来创建它。将用kubectl create podDisruptionBudget命令创建它,然后再查看一下YAML文件。

  如果想确保kubia pod总有3个实例在运行(它们有app=kubia这个标签),像这样创建PodDisruptionBudget资源:

$ kubectl create pdb kubia-pdb --selector=app=kubia --min-available=3
poddisruptionbudget "kubia-pdb" created

  现在获取这个PDB的YAML文件,如下代码:

#代码15.10 一个podDisruptioonBudget定义
$ kubectl get pdb kubia-pdb -o yaml
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
name: kubia-pdb
spec:
minAvailable:3 #应该有多少个pod始终可用
selector:
matchLabels: #用来确定该预算应该覆盖哪些pod的标签选择器
app: kubia
status:
....

  也可以用一个百分比而非绝对数值来写minAvailable字段。比方说,可以指定60%带app=kubia标签的pod应当时刻保持运行。

  注意:从Kubernetes1.7开始,podDismptionBudget资源也支持maxUnavailable。如果当很多pod不可用而想要阻止pod被剔除时,就可以用maxUnavailable字段而不是minAvailable。

  关于这个资源,没有更多要讲的了。只要它存在,Cluster Autoscaler与kubectl drain命令都会遵守它;如果疏散一个带有app=kubia标签的pod会导致它们的总数小于3,那这个操作就永远不会被执行。

  比方说,如果总共有4个pod,minAvailable像例子中一样被设为3,pod疏散过程就会挨个进行,待ReplicaSet控制器把被疏散的pod换成新的,才继续下一个。

Kubernetes自动横向伸缩集群节点以及介绍PDB资源的更多相关文章

  1. db2 数据库配置HADR+TSA添加集群节点

    Db2配置HADR高可用+TSA添加集群节点 一.服务器资源 Master IP:10.78.10.1 数据库:dbclassSlave IP:10.78.10.2 数据库:dbclassVIP:10 ...

  2. Kubernetes从懵圈到熟练:读懂这一篇,集群节点不下线

    排查完全陌生的问题,完全不熟悉的系统组件,是售后工程师的一大工作乐趣,当然也是挑战.今天借这篇文章,跟大家分析一例这样的问题.排查过程中,需要理解一些自己完全陌生的组件,比如systemd和dbus. ...

  3. Akka(12): 分布式运算:Cluster-Singleton-让运算在集群节点中自动转移

    在很多应用场景中都会出现在系统中需要某类Actor的唯一实例(only instance).这个实例在集群环境中可能在任何一个节点上,但保证它是唯一的.Akka的Cluster-Singleton提供 ...

  4. kubernetes集群节点多网卡,calico指定网卡

    kubernetes集群节点多网卡,calico指定网卡 1.calico如果有节点是多网卡,所以需要在配置文件中指定内网网卡 spec: containers: - env: - name: DAT ...

  5. 使用kubeadm搭建Kubernetes(1.10.2)集群(国内环境)

    目录 目标 准备 主机 软件 步骤 (1/4)安装 kubeadm, kubelet and kubectl (2/4)初始化master节点 (3/4) 安装网络插件 (4/4)加入其他节点 (可选 ...

  6. 【葵花宝典】lvs+keepalived部署kubernetes(k8s)高可用集群

    一.部署环境 1.1 主机列表 主机名 Centos版本 ip docker version flannel version Keepalived version 主机配置 备注 lvs-keepal ...

  7. 被集群节点负载不均所困扰?TKE 重磅推出全链路调度解决方案

    引言 在 K8s 集群运营过程中,常常会被节点 CPU 和内存的高使用率所困扰,既影响了节点上 Pod 的稳定运行,也会增加节点故障的几率.为了应对集群节点高负载的问题,平衡各个节点之间的资源使用率, ...

  8. Kubernetes(k8s)部署redis-cluster集群

    Redis Cluster 提供了一种运行 Redis 安装的方法,其中数据 在多个 Redis 节点之间自动分片. Redis Cluster 还在分区期间提供了一定程度的可用性,这实际上是在某些节 ...

  9. 使用国内的镜像源搭建 kubernetes(k8s)集群

    1. 概述 老话说的好:努力学习,提高自己,让自己知道的比别人多,了解的别人多. 言归正传,之前我们聊了 Docker,随着业务的不断扩大,Docker 容器不断增多,物理机也不断增多,此时我们会发现 ...

随机推荐

  1. font 和 text ,cursor

    font:14px/30px/"宋体"这种写法等于 font-size="14px" line-heigiht="30px" font-fa ...

  2. OAuth2.0 授权方式及步骤梳理总结

    OAuth 2.0授权协议使第三方应用程序可以通过协调资源所有者和HTTP服务之间的批准交互,或者通过允许第三方应用程序代表资源所有者来获得对HTTP服务的有限访问权,或者代表资源所有者. 代表自己获 ...

  3. C#基础之==(双等于号)与equals()区别

    C#中Equals和= =比较 这两种方式也是大家在日常编码工作当中用的比较多的判断方式.之前在使用的时候也没太关注两者在比较不同类型的时候存在哪些区别. 今天就和大家一起深入了解一下其中区别 一.值 ...

  4. Vue3响应式系统api 之 ref reactive

    reactive 接收一个普通对象然后返回该普调对象的响应式代理.等同于2.x的  Vue.observable() Vue3中响应数据核心是 reactive , reactive 中的实现是由 P ...

  5. Docker创建镜像以及私有仓库

    Docker的安装及镜像.容器的基本操作详见博客https://blog.51cto.com/11134648/2160257下面介绍Docker创建镜像和创建私有仓库的方法,详细如下: 创建镜像 创 ...

  6. iozone测试方法-20191008

    iozone   一.简介 磁盘设备之上是文件系统,测试磁盘的工具往往就是调用驱动块设备驱动的接口进行读写测试.而文件系统的测试软件就是,针对文件系统层提供的功能进行测试,包括文件的打开关闭速度以及顺 ...

  7. Ansible_常用文件模块使用详解

    一.Ansibel常用文件模块使用详解 1.file模块 1️⃣:file模块常用的参数列表: path       被管理文件的路径 state状态常用参数: absent           删除 ...

  8. nginx 的三种虚拟主机配置方法

    nginx三种虚拟主机配置的方法. 基于端口 在生产环境中一般使用端口或者域名. [root@web01 /etc/nginx/conf.d]# cat web01.conf server { lis ...

  9. linux python3安装whl包时报错解决:is not a supported wheel on this platform

    原因1 你下载安装的包不是当前平台所支持的 原因2 你下载的包,不符合你所在的平台的安装whl的名称规范,所以出错.比如当前我要安装的包是:pymssql-2.1.5-cp36-cp36m-manyl ...

  10. PHP相关session的知识

    由于http协议是一种无状态协议,所以没有办法在多个页面间保持一些信息.例如,用户的登录状态,不可能让用户每浏览一个页面登录一次.session就是为了解决一些需要在多页面间持久保持一种状态的机制.P ...