k8s滚动升级和扩缩容

一、扩缩容

手动扩容

k8s使用过kubectl scale命令进行扩容

假设原本的pod有3个,这个时候由于业务的增长,我们可以将pod增加到5个

kubectl scale rc blog --replicas=5
这里的blog是rc的名称

当--replicas的值设置为比原来的pod数,k8s会杀掉一些pod,下面3个变成1个
kubectl scale rc blog --replicas=1

自动扩容(HPA)

用于实现基于CPU使用率进行自动Pod扩缩容的功能。HPA控制器基于Master的kube-controller-manager服务启动参数--horizontal-pod-autoscaler-sync-period定义的探测周期(默认值为 15s),周期性地监测目标Pod的资源性能指标,并与HPA资源对象中的扩缩容条件进行对比,在满足条件时对Pod副本数量进行调整.

HPA的原理
k8s通过某个个Metrics Server持续采集集群中pod副本的性能指标,然后HPA通过Metrics Server提供的api获取这些数据,跟用户定于性能指标规则对比,计算出所需的pod数量,当计算出的数量跟当前集群中的pod数量不同,HPA就调用RC控制器进行扩缩容。

扩缩容算法
最终pod的数量=ceil[当前的pod数量*(当前性能指标数/期望性能性能指标数)]
ceil向上取整

比如:当前的cpu使用率是60%,但是我期望的是30%,并且当前已经存在2个pod了
2*(60% / 30%)= 4,所以应该扩容2个pod变成4个

比如:当前的cpu使用200m,但是我期望的是100m,并且当前已经存在2个pod了
2*(200m / 100m)= 4,所以应该扩容2个pod变成4个

容忍度
容忍度通过kube-controller-manager服务的启动参数--horizontal- pod-autoscaler-tolerance进行设置,默认值为0.1(即10%),表示基于上 述算法得到的结果在[-10%-+10%]区间内,即[0.9-1.1],控制器都不会进
行扩缩容操作。

由于有可能业务不稳定,突然有服务压力但过几分钟就结束了,kubernetes 增加了弹性增加节点和减少节点的延迟时间(kube-controller-manager启动参数)。
--horizontal-pod-autoscaler-downscale-delay: 弹性减少节点延迟时间,默认5分钟

--horizontal-pod-autoscaler-upscale-delay: 弹性增加节点延迟时间,默认3分钟

k8s针对扩容做了一个最大限制,每次扩容的pod数量不会大于当前副本数量的2倍。

HorizontalPodAutoscaler
k8s提供HorizontalPodAutoscaler资源对象,让我们可以使用它进行配置扩缩容的规则。
HorizontalPodAutoscaler有两个版本,autoscaling/v1 只支持CPU使用率的指标数,autoscaling/v2则用于支持基于任意指标的自动扩缩容配置,包括基于资源使用率(Resource)、Pod指标(Pods)、其他指标(Object)等。

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata: 
  name: php-apache 
  namespace: default 
spec: scaleTargetRef: 
apiVersion: apps/v1beta1 
kind: Deployment name: php-apache minReplicas: 1 maxReplicas: 10 
metrics: 
- type: Resource 
  resource: 
    name: cpu
    target:
      type: Utilization
      averageUtilization: 50

averageUtilization:50 设置cpu的平均使用率为50
平均值所有Pod副本当前指标值的总和除以Pod 副本数量得到的平均值

metrics的type可以设置为Resource、Pods、Object3种
Resource可以设置CPU和内存。对于CPU使用率,在target参数中设置averageUtilization定义目标平均CPU使用率。对于内存资源,在target参数中设置AverageValue定义目标平均内存使用值

metrics:
- type: Pods
  pods: 
    metric
      name: packets-per-second 
      target:
        type: AverageValue
        averageValue: 1k 

平均每秒的数据量达到1000进行扩容

类型为Pods的指标数据来源于Pod对象本身,其target指标类型只能使用AverageValue

metrics:
- type: Object
  object: 
    metric
      name: requests-per-second
    describedObject: 
      apiVersion: extensions/v1beta1 
      kind: Ingress 
      name: main-route 
    target:
      type: Value
      value: 2k

设置指标的名称为requests-per-second,其值来源于 Ingress“main-route”,将目标值(value)设置为2000,即在Ingress的每 秒请求数量达到2000个时触发扩缩容

类型为Object的指标数据来源于其他资源对象或任意自定义指标, 其target指标类型可以使用Value或AverageValue(根据Pod副本数计算平 均值)进行设置

HPA 最佳实践
1)为容器配置 CPU Requests
2)HPA 目标设置恰当,如设置 70% 给容器和应用预留 30% 的余量
3)保持 Pods 和 Nodes 健康(避免 Pod 频繁重建)
4)保证用户请求的负载均衡
5)使用 kubectl top node 和 kubectl top pod 查看资源使用情况

二、滚动升级

当集群中的某个服务需要升级时,我们需要停止目前与该服务相关的所有Pod,然后下载新版本镜像并创建新的Pod。如果集群规模比较大,服务不能对外提供服务,则这个工作变成了一个挑战,而且先全部停止然后逐步升级的方式会导致较长时间的服务不可用。Kubernetes提供了滚动升级功能来解决上述问题。

kubectl set image完成滚动升级

Pod镜像需要被更新为Nginx:1.9.1, 我们可以通过kubectl set image命令为Deployment设置新的镜像名称


$ image (-f filename | type name) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N

资源对象 pod (po)、replicationcontroller (rc)、deployment (deploy)、daemonset (ds)、job、replicaset (rs)


kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
deployment为资源对象类型
nginx-deployment 为资源对象名
nginx=nginx:1.9.1   容器名为nginx 更新镜像为nginx:1.9.1

一旦镜像名(或Pod定义)发生了修改,则将触发系统完成 Deployment所有运行Pod的滚动升级操作。

可以使用kubectl rollout status 命令查看Deployment的更新过程

spec.strategy.rollingUpdate.maxUnavailable:用于指定更新过程中,不可用的pod的数量
可以是整数如3,也可以是百分比30%(从Kubernetes 1.6开始, maxUnavailable的默认值从1改为25%)
比如设置为30%,滚动更新开始时立即将副本数缩小到所需副本总数的70%,等新的pod准备后,在进一步缩容。

spec.strategy.rollingUpdate.maxSurge:用于指定更新过程中,新旧pod数量总和的上限
可以是整数如3,也可以是百分比30%(向上取整)(从Kubernetes 1.6开始, maxUnavailable的默认值从1改为25%)举例来说,当maxSurge的值被设置为30%时,新的ReplicaSet可以在滚动更新开始时立即进行副本数扩容,只需要保证新旧ReplicaSet 的Pod副本数之和不超过期望副本数的130%即可

kubectl rolling-update命令进行滚动升级

见篇另一篇博客 k8s初识的滚动升级

三、回滚

在实际发布项目中,一般不会这么顺利,我们会经常遇到发布错了。比如我们要发布镜像为nginx:1.9.1,结果不小心发布成了nginx:1.9.2。这个时候我们需要回滚到上一个版本。

默认情况下,k8s会将有deployment发布历史记录保存在系统中,方便我们回滚。(可以设置保存的记录条数)

kubectl set image deployment/nginx-deployment nginx=nginx:1.9.2
由于nginx:1.9.2不存在,发布过程卡主我们使用Ctrl-C中止

用kubectl rollout status 命令查看Deployment的更新过程
kubectl rollout status deployment/nginx-deployment

kubectl rollout history查看这个Deployment的历史记录
kubectl rollout history deployment/nginx-deployment

查看特定版本的详情信息
kubectl rollout history deployment/nginx-deployment --revision=3


回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment
回滚到特定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2

在创建Deployment时使用--record参数,就可以在CHANGE- CAUSE列看到每个版本使用的命令了。
kubectl create -f nginx-deployment.yaml --record=true

注意:只有修改spec.template才会创建新的修订版本,如更新镜像,容器标签。其他更新不会触发更新操作如修改pod的数量。这也意味着我们将Deployment回滚到 之前的版本时,只有Deployment的Pod模板部分会被修改。

四、暂停更新和恢复

对于一次复杂的Deployment配置修改,为了避免频繁触发 Deployment的更新操作,可以先暂停Deployment的更新操作,然后进行配置修改,再恢复Deployment,一次性触发完整的更新操作,就可以避 免不必要的Deployment更新操作了。

通过kubectl rollout pause命令暂停Deployment的更新操作:
kubectl rollout pause deployment/nginx-deployment

进行一系列操作,比如修改镜像,(并不会更新)
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
设置容器的资源
kubectl set resources deployment nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi

恢复这个Deployment的部署操作:
kubectl rollout resume nginx-deployment

注意
在恢复暂停的Deployment之前,无法回滚该Deployment

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

推荐阅读更多精彩内容

  • 在实际生产系统中,我们经常会遇到某个服务需要扩容的场景,也可能会遇到由于资源紧张或者工作负载降低而需要减少服务实例...
    王勇1024阅读 3,211评论 0 6
  • ## 1 kubectl命令介绍 ### 1.1 基本命令 Kubectl是kubernetes的命令行工具。职责...
    小曼版阅读 349评论 0 0
  • [TOC] 一、概述 1.1、什么是Kubernetes ​ Kubernetes是容器集群管理系统,是一个开...
    Sonic_Ma阅读 1,176评论 0 2
  • 福字,拆解开看,一口人,有衣,有田。 有田,就有食。衣食无忧当然有福了。 旧体俭字,体现的是,一个屋檐下,两口人。...
    方有怀阅读 97评论 0 5
  • 文/何冠萱 每天几分钟的晨光照亮创作园地,一觉到天亮,醒来就练笔,没有太多的想法的文章。 许多的人留在以后写,许许...
    何冠萱阅读 685评论 13 15