系列目录html
简介
nginx
当kubernetes集群中的某个服务须要升级时,传统的作法是,先将要更新的服务下线,业务中止后再更新版本和配置,而后从新启动并提供服务。若是业务集群规模较大时,这个工做就变成了一个挑战,并且先所有了中止,再逐步升级的方式会致使服务较长时间不可用。kubernetes提供了滚动更新(rolling-update)的方式来解决上述问题。api
简单来讲,滚动更新就是针对多实例服务的一种不中断服务的更新升级方式。通常状况下,对于多实例服务,滚动更新采用对各个实例逐个进行单独更新而非同一时刻对全部实例进行所有更新的方式。bash
对于k8s集群部署的service来讲,rolling update就是指一次仅更新一个pod,并逐个进行更新,而不是在同一时刻将该service下面的全部pod shutdown,避免业务中断。网络
对于咱们要部署的应用来讲,通常是由多个抽象的service组成。在kubernetes中,一个service经过label selector match出一个pods集合,这些Pods做为service的endpoint,是真正承载业务的实体。而pod在集群内的部署、调度、副本数则是经过Deployment或者RC这些更高级别的抽象来管理的。以下图:app
新版本的Kubernetes推荐用Deployment替代ReplicationController,在Deployment这个概念下在保持Pod副本数上实际发挥做用的是隐藏在背后的Replica Set。3d
所以,咱们能够看到Kubernetes上Service的rolling update实质上是对Service所match出来的Pod集合的Rolling update,而控制Pod部署、调度和副本调度的却又偏偏是Deployment和replication controller,所以后二者才是kubernetes service rolling update真正要面对的实体。code
使用kubectl rolling-update命令的方式,主要是针对使用RC建立的pods。
先来看下面一个示例,建立一个包含4个nginx副本的RC nginx-demo-v1-rc.yml:server
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内容以下:htm
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文件区别:
咱们能够经过以下操做来查看更新的完整过程:
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替代。
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