系列目录

简介

当kubernetes集群中的某个服务需要升级时,传统的做法是,先将要更新的服务下线,业务停止后再更新版本和配置,然后重新启动并提供服务。如果业务集群规模较大时,这个工作就变成了一个挑战,而且先全部了停止,再逐步升级的方式会导致服务较长时间不可用。kubernetes提供了滚动更新(rolling-update)的方式来解决上述问题。

简单来说,滚动更新就是针对多实例服务的一种不中断服务的更新升级方式。一般情况下,对于多实例服务,滚动更新采用对各个实例逐个进行单独更新而非同一时刻对所有实例进行全部更新的方式。

对于k8s集群部署的service来说,rolling update就是指一次仅更新一个pod,并逐个进行更新,而不是在同一时刻将该service下面的所有pod shutdown,避免业务中断。

Service、Deployment、RS、RC和Pod之间的关系

对于我们要部署的应用来说,一般是由多个抽象的service组成。在kubernetes中,一个service通过label selector match出一个pods集合,这些Pods作为service的endpoint,是真正承载业务的实体。而pod在集群内的部署、调度、副本数则是通过Deployment或者RC这些更高级别的抽象来管理的。如下图:

新版本的Kubernetes推荐用Deployment替代ReplicationController,在Deployment这个概念下在保持Pod副本数上实际发挥作用的是隐藏在背后的Replica Set。

因此,我们可以看到Kubernetes上Service的rolling update实质上是对Service所match出来的Pod集合的Rolling update,而控制Pod部署、调度和副本调度的却又恰恰是Deployment和replication controller,因此后两者才是kubernetes service rolling update真正要面对的实体。

使用kubectl rolling-update更新

使用kubectl rolling-update命令的方式,主要是针对使用RC创建的pods。

先来看下面一个示例,创建一个包含4个nginx副本的RC nginx-demo-v1-rc.yml:

apiVersion: v1
kind: ReplicationController
metadata:
name: nginx-demo-v1
spec:
replicas: 4
selector:
app: nginx-demo
ver: v1
template:
metadata:
labels:
app: nginx-demo
ver: v1
spec:
containers:
- name: nginx-demo
image: nginx:1.10.1
ports:
- containerPort: 80
protocol: TCP
env:
- name: NGX_DEMO_VER
value: v1

创建一个service,nginx-demo-svc.yml内容如下:

apiVersion: v1
kind: Service
metadata:
name: nginx-demo-svc
spec:
ports:
- port: 80
protocol: TCP
selector:
app: nginx-demo

创建rc和service:

kubectl create -f nginx-demo-v1-rc.yml
kubectl create -f nginx-demo-svc.yml

创建完成以后,可以通过访问任一Pod的环境变量查看NGX_DEMO_VER的值,为v1

现在我们创建一个nginx-demo-v2-rc.yml的文件,来升级现有的pod:

apiVersion: v1
kind: ReplicationController
metadata:
name: nginx-demo-v2
spec:
replicas: 4
selector:
app: nginx-demo
ver: v2
template:
metadata:
labels:
app: nginx-demo
ver: v2
spec:
containers:
- name: nginx-demo
image: nginx:1.11.9
ports:
- containerPort: 80
protocol: TCP
env:
- name: NGX_DEMO_VER
value: v2

执行更新操作:

kubectl rolling-update nginx-demo-svc -f nginx-demo-v2-rc.yml

需要注意的是,在执行滚动升级时,两个版本的yml文件区别:

  • RC的名字不能与旧的RC名字相同
  • 在selector中应至少有一个label与旧的RC的label不同,以标识其为新的RC。

我们可以通过如下操作来查看更新的完整过程:

kubectl rolling-update nginx-demo-v1 --udpate-period=10s -f nginx-demo-v2-rc.yml

当所有旧的pod被新的Pod替换完成以后,更新完成。

使用kubectl rolling-update实现滚动更新的不足:

  • rolling-update的逻辑是由kubectl发出N条命令到APIServer完成的,很可能因为网络原因导致update中断

  • 需要创建一个新的rc,名字与要更新的rc不能一样

  • 回滚还需要执行rolling-update,只是用老的版本替换新的版本

  • service执行的rolling-update在集群中没有记录,后续无法跟踪rolling-update历史

现如今,RC的方式已经被Deployment替代。

Deployment的rolling-update

kubernetes的Deployment是一个更高级别的抽象。Deployment会创建一个Replica Set,用来保证Deployment中的Pod的副本数。要rolling-update deployment中的Pod,只需要修改Deployment自己的yml文件并应用即可。这个修改会创建一个新的Replica Set,在增加这个新RS的pod数的同时,减少旧RS的pod,直至完全升级。而这一切都发生在Server端,并不需要kubectl参与。

创建一个Deployment yml文件nginx-demo-dm.yml:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-demo
spec:
replicas: 4
selector:
matchLabels:
app: nginx-demo
minReadySeconds: 10
template:
metadata:
labels:
app: nginx-demo
version: v1
spec:
containers:
- name: deployment-demo
image: nginx:1.10.1
ports:
- containerPort: 80
protocol: TCP

创建该deployment:

kubect create -f nginx-demo-dm.yml --record

然后我们可以直接修改该deployment文件,如下 :

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-demo
spec:
replicas: 4
selector:
matchLabels:
app: nginx-demo
minReadySeconds: 10
template:
metadata:
labels:
app: nginx-demo
version: v2
spec:
containers:
- name: deployment-demo
image: nginx:1.11.9
ports:
- containerPort: 80
protocol: TCP

一共就改了两个地方,将version改为了v2,将nginx镜像从1.10.1改到了1.11.9,执行如下操作应用更改:

kubectl apply -f nginx-demo-dm.yml --record

这个时候,我们可以通过执行kubectl get rs来查看到rs的变化,以确认是否在执行升级。也可以通过kubectl describe deployment nginx-demo来查看详细的rolling-update的过程。还可以通过kubectl rollout status deployment/nginx-demo来查看更新状态。

除了使用apply方式来应用更改以外,还有另外一种方式可以直接升级。就是通过kubectl edit nginx-demo-dm.yml来编辑deployment文件,保存以后,不需要执行apply,就会自动完成升级。

我们可以注意到,在执行deployment的操作时,使用了一个--record参数,这个参数是用来告诉apiserver记录update的历史。可以通过如下命令来查看update历史:

kubectl rollout history deployment nginx-demo

查看指定revision的详细信息:

kubectl rollout history deployment hello-deployment --revision=2

需要说明的是,在升级完成以后,旧的RS也不会被删除,这些信息都会存储到server端,以方便回滚。

deployment下的pod的回滚操作相当简单,直接执行rollout undo即可将deployment回滚到record中记录的上一个revision:

kubectl rollout undo deployment nginx-demo

执行如下操作,回滚到指定版本:

kubectl rollout undo deployment hello-deployment --to-version=2

原文地址

kubernetes滚动更新的更多相关文章

  1. Kubernetes——滚动更新和数据管理

    k8s——滚动更新滚动更新就是一次只更新一小部分副本,更新成功之后再更新更多的副本,最终完成所有副本的更新.滚动更新最大的好处是零停机,整个更新的过程中始终有副本运行,从而保证了业务的连续性.kube ...

  2. 详谈kubernetes滚动更新-1

    系列目录 这个系列分为两个小节,第一个小节介绍deployment滚动更新时,deployment.replicaset.pod的细节以及创建过程以及deployment版本管理的方式 第二个小节将介 ...

  3. Kubernetes滚动更新介绍及使用-minReadySeconds

    滚动升级Deployment 现在我们将刚刚保存的yaml文件中的nginx镜像修改为 nginx:1.13.3,然后在spec下面添加滚动升级策略:   1 2 3 4 5 6 7 minReady ...

  4. kubernetes 滚动更新发布及回滚

    基本命令 记录历史 --record kubectl  apply -f **** --record 查看当前状态 kubectl rollout status deployment/demo -w ...

  5. Kubernetes集群中Service的滚动更新

    Kubernetes集群中Service的滚动更新 二月 9, 2017 0 条评论 在移动互联网时代,消费者的消费行为已经“全天候化”,为此,商家的业务系统也要保持7×24小时不间断地提供服务以满足 ...

  6. Kubernetes Deloyment实现滚动更新

    目录 滚动更新简介 使用kubectl rolling-update更新RC Deployment的rolling-update 滚动更新简介 当kubernetes集群中的某个服务需要升级时,传统的 ...

  7. Kubernetes Pod应用的滚动更新(八)

    一.环境准备 我们紧接上一节的环境,进行下面的操作,如果不清楚的,可以先查看上一篇博文. 滚动更新是一次只更新一小部分副本,成功后,再更新更多的副本,最终完成所有副本的更新.滚动更新的最大的好处是零停 ...

  8. kubernetes之DaemonSet以及滚动更新

    1.什么是DaemonSet? 1.1DaemonSet是Pod控制器的又一种实现方式,用于在集群中的全部节点上同时运行一份指定的Pod资源副本,后续加入集群的节点也会自动创建一个相关的Pod对象,当 ...

  9. Kubernetes 零宕机滚动更新

    转载自:https://www.qikqiak.com/post/zero-downtime-rolling-update-k8s/ 软件世界的发展比以往任何时候都快,为了保持竞争力需要尽快推出新的软 ...

随机推荐

  1. hihoCoder #1047 Random Tree

    题意 给出点数为 $n$($n \le 1000$)的完全图 $K_n$,带边权.随机出 $K_n$ 的一棵生成树 $T$.求 $T$ 上任意两点间距离的期望. 解法 固定两点 $u$.$v$($u ...

  2. BZOJ3991 [SDOI2015]寻宝游戏 【dfs序 + lca + STL】

    题目 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路 ...

  3. jquery中append、prepend, before和after方法的区别(一)

    原文:http://blog.csdn.net/woosido123/article/details/64439490 在 jquery中append() 与 prepend()是在元素内插入内容(该 ...

  4. 马士兵hadoop第一课:虚拟机搭建和安装hadoop及启动(转)

    马士兵hadoop第一课:虚拟机搭建和安装hadoop及启动 马士兵hadoop第二课:hdfs集群集中管理和hadoop文件操作 马士兵hadoop第三课:java开发hdfs 马士兵hadoop第 ...

  5. app_data中的数据库使用

    原文发布时间为:2008-07-24 -- 来源于本人的百度文章 [由搬家工具导入] ASP.NET中利用VWD操作数据库 建立本地数据库   你可以轻易地在Visual Studio的Web应用程序 ...

  6. Word Ladder系列

    1.Word Ladder 问题描述: 给两个word(beginWord和endWord)和一个字典word list,找出从beginWord到endWord之间的长度最长的一个序列,条件: 1. ...

  7. Latex algorithm

    方式一 需要包含的 \usepackage[noend]{algpseudocode} \usepackage{algorithmicx,algorithm} 源码 \begin{algorithm} ...

  8. 客户端负载均衡Ribbon之源码解析

    什么是负载均衡器? 假设有一个分布式系统,该系统由在不同计算机上运行的许多服务组成.但是,当用户数量很大时,通常会为服务创建多个副本.每个副本都在另一台计算机上运行.此时,出现 "Load ...

  9. mysql 设置默认id自增开始下标

    alter table 表名 AUTO_INCREMENT 此处写你想让id从几开始增长的数字:

  10. Leetcode总结之Backtracking

    本文我们就Leetcode中的一个类型的题目backtracking进行一系列的总结和归纳.backtracking这个方法本质是建立在递归的基础上,不断尝试新的路径,这里关键是每次尝试完以后需要退回 ...