概述

本文核心问题是:如何升级应用。

对于Pod的更新有两种策略:

  • 一是删除全部旧Pod之后再创建新Pod。好处是,同一时间只会有一个版本的应用存在;缺点是,应用有一段时间不可用。
  • 二是先创建新Pod,再删除旧Pod。可以一次性创建全部,再删除全部,也可以逐渐创建删除。好处是应用一直可用,缺点是要同时支持两个版本。

蓝绿部署

对于应用的版本v1和版本v2:

  • 在运行v1前,流量一直都在v2上
  • 部署v1,然后测试通过后,将流量切换到v2,v2就成为了新的生产环境
  • 一旦v2出现问题,可以在切回v1

金丝雀部署(也称灰度部署)

金丝雀部署一种增量发布,先是在小范围内发布,然后观察测试,如无问题逐渐发布全部。

kubectl rolling-update

因为kubectl rolling-update的方式已经过时,所以只是做一下简介。

假设现在有一个名为test-v1,Pod选择器为app=order的ReplicationController要升级为test-v2,则执行下面命令可升级:

k rolling-update test-v1 test-v2 --image=test:v2

运行此命令后:

  1. 立刻创建一个名为test-v2的ReplicationController,他的Pod模板镜像正是test:v2,并添加一个标签deployment=xxxx
  2. test-v1以及app=order选中的Pod都会被加上一个标签:deployment=yyyy。如此做法是防止Pod的管理混乱。
  3. 先将test-v2的Pod扩展为1,使用更新后的模板创建新Pod;再将test-v1缩小1,如此循环。
  4. 因为在滚动过程中Service的标签选择器一直是app=order,所以新老版本都会接收到流量。

过时的原因是:伸缩的请求时由kubectl发起的,如果因为任何原因丢失了网络连接,升级将处于中间状态。另一个原因是:期望只修改Pod定义中的镜像tag,就能时Kubernetes运行升级工作

使用Deployment声明式的升级

Deployment是一种更高阶的资源,用于部署程序并以声明的方式升级应用,而不是通过ReplicationController或ReplicaSet进行部署。

在使用Deployment时,Pod是由Deployment的ReplicaSet创建的。

准备镜像

将之前的文章(Kubernetes学习笔记(四):服务)里的拿过来做一下微小的改动,生成两个镜像。改动内容就是在输出内容加上版本号。

fmt.Fprintf(w,"this is v1, hostname: %v\n",hostname)
docker push registry.cn-hangzhou.aliyuncs.com/orzi/goweb:v1 fmt.Fprintf(w,"this is v2, hostname: %v\n",hostname)
docker push registry.cn-hangzhou.aliyuncs.com/orzi/goweb:v2

创建Deployment

Deployment与ReplicaSet的配置相似,都含有标签选择器、副本数量和Pod模板。此外Deployment还会包含一个部署策略。

定义Service

定义了一个NodePort类型的Service

# goweb-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: goweb
spec:
type: NodePort
selector:
app: goweb
ports:
- port: 80
targetPort: 8000
nodePort: 31234

定义Deployment

# goweb-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: goweb
spec:
replicas: 3
selector:
matchLabels:
app: goweb
template:
metadata:
labels:
app: goweb
spec:
containers:
- name: goweb
image: registry.cn-hangzhou.aliyuncs.com/orzi/goweb:v1

运行查看

可以看到名为goweb-fdfcfdcc6的RS,有个label是pod-template-hash=fdfcfdcc6,顾名思义,fdfcfdcc6就是pod模板的hash值。

创建Deployment时指定 --record 记录历史版本号,非常有用

-> [root@kube0.vm] [~] k create -f goweb-svc.yaml
service/goweb created -> [root@kube0.vm] [~] k create -f goweb-deployment.yaml --record deployment.apps/goweb created
-> [root@kube0.vm] [~] k get all -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/goweb-fdfcfdcc6-4wklw 1/1 Running 0 9s 10.244.2.37 kube2.vm <none> <none>
pod/goweb-fdfcfdcc6-bw8c4 1/1 Running 0 9s 10.244.2.36 kube2.vm <none> <none>
pod/goweb-fdfcfdcc6-xjcwf 1/1 Running 0 9s 10.244.1.33 kube1.vm <none> <none> NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/goweb NodePort 10.100.193.94 <none> 80:31234/TCP 28s app=goweb
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 54s <none> NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/goweb 3/3 3 3 9s goweb registry.cn-hangzhou.aliyuncs.com/orzi/goweb:v1 app=goweb NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
replicaset.apps/goweb-fdfcfdcc6 3 3 3 9s goweb registry.cn-hangzhou.aliyuncs.com/orzi/goweb:v1 app=goweb,pod-template-hash=fdfcfdcc6

升级Deployment

只要修改Deployment的Pod模板定义,Kubernetes会自动的将实际状态收敛为修改后的状态。对于升级,只需要修改Pod中镜像的tag。

升级策略由deployment.spec.strategy.type定义,值是Recreate或RollingUpdate,默认RollingUpdate。

kubectl patch及minReadySeconds

使用kubectl patch定义deployment.spec.minReadySeconds来减慢滚动升级时间,以便观察升级过程

-> [root@kube0.vm] [~] k patch deployment goweb -p '{"spec":{"minReadySeconds":5}}'
deployment.apps/goweb patched

循环请求服务

在执行升级前新开窗口,运行下面的命令查看输出

-> [root@kube0.vm] [~] while true; do curl http://192.168.199.231:31234/ ; sleep 1; done
this is v1, hostname: goweb-fdfcfdcc6-pw7b4
this is v1, hostname: goweb-fdfcfdcc6-pw7b4
this is v1, hostname: goweb-fdfcfdcc6-x8n7h
this is v1, hostname: goweb-fdfcfdcc6-pw7b4
this is v1, hostname: goweb-fdfcfdcc6-x8n7h
this is v1, hostname: goweb-fdfcfdcc6-j4mz8
this is v1, hostname: goweb-fdfcfdcc6-j4mz8
# 以上是升级之前的输出、以下是开始升级后的
this is v1, hostname: goweb-fdfcfdcc6-x8n7h
this is v1, hostname: goweb-fdfcfdcc6-pw7b4
this is v1, hostname: goweb-fdfcfdcc6-pw7b4
this is v1, hostname: goweb-fdfcfdcc6-j4mz8
this is v2, hostname: goweb-65cc575865-25988
this is v2, hostname: goweb-65cc575865-25988
this is v1, hostname: goweb-fdfcfdcc6-x8n7h
this is v1, hostname: goweb-fdfcfdcc6-j4mz8
this is v2, hostname: goweb-65cc575865-bfd98
this is v2, hostname: goweb-65cc575865-bfd98
this is v2, hostname: goweb-65cc575865-25988
this is v2, hostname: goweb-65cc575865-25988
this is v2, hostname: goweb-65cc575865-25988
# 这之后就是升级完成了

kubectl set

使用 kubectl set image 更新任何包含容器资源的镜像。

-> [root@kube0.vm] [~] k set image deployment goweb goweb=registry.cn-hangzhou.aliyuncs.com/orzi/goweb:v2
deployment.apps/goweb image updated

kubectl rollout

查看升级状态信息。执行完kubectl set image,立刻执行下面的命令。手速得快,不然赶不上热乎的。

-> [root@kube0.vm] [~] k rollout status deployment goweb
Waiting for deployment "goweb" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "goweb" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "goweb" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "goweb" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "goweb" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "goweb" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "goweb" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "goweb" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "goweb" rollout to finish: 1 old replicas are pending termination...
deployment "goweb" successfully rolled out

修改Deployment或其他资源的方式

方法 作用
kubectl edit 使用编辑器打开资源配置
kubectl patch 在命令行以merge的方式修改配置
kubectl apply 通过yaml或者json文件,修改新改动的值。如果指定的对象不存在则创建。
kubectl replace 使用yaml或者json文件替换一个必须已存在的对象配置。
kubectl set image 修改镜像

回滚

使用kubectl rollout undo 回滚到上一个版本

-> [root@kube0.vm] [~] k rollout undo deployment goweb
deployment.apps/goweb rolled back

使用 kubectl rollout history 查看版本记录

-> [root@kube0.vm] [~] k rollout history deployment goweb
deployment.apps/goweb
REVISION CHANGE-CAUSE
6 kubectl create --filename=goweb-deployment.yaml --record=true
7 kubectl create --filename=goweb-deployment.yaml --record=true

回滚到特定版本

-> [root@kube0.vm] [~] k rollout undo deployment goweb --to-revision=5
error: unable to find specified revision 5 in history -> [root@kube0.vm] [~] k rollout undo deployment goweb --to-revision=7
deployment.apps/goweb skipped rollback (current template already matches revision 7) -> [root@kube0.vm] [~] k rollout undo deployment goweb --to-revision=6
deployment.apps/goweb rolled back

通过deployment.spec.revisionHistoryLimit指定历史版本个数,默认为2。也就是当前和上一个版本。

控制滚动升级速率

deployment.spec.strategy.rollingUpdate下有两个字段,用来控制升级速率

  • maxSurge:超出期望副本数的Pod实例的比例或个数。默认25%,转换成绝对值后四舍五入,也可以直接指定为绝对值。
  • maxUnavailable:滚动升级时,最多允许有多少实例不可用,默认25%,转换成绝对值后四舍五入,也可以直接指定为绝对值。

暂停、恢复升级

  • 使用kubectl rollout pause暂停升级
  • 使用kubectl rollout resume取消暂停

阻止出错版本的滚动升级

  • minReadySeconds:指定新创建的Pod至少要运行多久才视为可用。
  • 配置就绪探针
  • 为滚动升级配置progressDeadlineSeconds

小结

  • kubectl rolling-update 过时的原因:伸缩的请求时由kubectl发起的,如果因为任何原因丢失了网络连接,升级将处于中间状态
  • Deployment是一种更高阶的资源,用于部署程序并以声明的方式升级应用,而不是通过ReplicationController或ReplicaSet进行部署。
  • 创建Deployment时指定 --record 记录历史版本号
  • Deployment下的ReplicaSet命名是DeploymentName+Pod模板Hash,而ReplicaSet下的Pod是在此基础拼接个随机字符串。
  • 升级策略由deployment.spec.strategy.type定义,值是Recreate或RollingUpdate,默认RollingUpdate。
  • 定义deployment.spec.minReadySeconds来减慢滚动升级时间
  • maxSurge与maxUnavailable控制滚动升级速率
  • 命令:patch、set、rollout
  • kubectl rollout:status、undo、pause、resume、history。

Kubernetes学习笔记(八):Deployment--声明式的升级应用的更多相关文章

  1. k8s之Deployment 声明式地升级应用(五)

    Deployment 声明式地升级应用 现在你已经知道如何将应用程序组件打包进容器,将他们分组到pod中,并为它们提供临时或者持久存储,将密钥或配置文件注入,并可以使pod之间互相通信.这就是微服务化 ...

  2. 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:Spring声明式事务管理(基于Annotation注解方式实现)

    在 Spring 中,除了使用基于 XML 的方式可以实现声明式事务管理以外,还可以通过 Annotation 注解的方式实现声明式事务管理. 使用 Annotation 的方式非常简单,只需要在项目 ...

  3. Struts2学习第八课 声明式异常处理

    异常处理:exception-mapping元素 exception-mapping元素:配置当前的action的声明式异常处理 exception-mapping元素有两个属性: --excepti ...

  4. deployment:声明式的升级应用

    9.1.使用RC实现滚动升级 #kubectl rolling-update kubia-v1 kubia-v2 --image=luksa/kubia:v2 使用kubia-v2版本应用来替换运行着 ...

  5. Kubernetes 学习笔记(一):基础概念

    个人笔记,仅本人查阅使用,不保证正确. 零.微服务 微服务架构专注于应用解耦合,通过将应用彻底地组件化和服务化,每个微服务只包含一个非常小的功能,比如权限管理.日志收集等等.由这一组微服务组合起来,提 ...

  6. Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  7. python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑

    python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件?当我们点开下载页时, 一般 ...

  8. Go语言学习笔记八: 数组

    Go语言学习笔记八: 数组 数组地球人都知道.所以只说说Go语言的特殊(奇葩)写法. 我一直在想一个人参与了两种语言的设计,但是最后两种语言的语法差异这么大.这是自己否定自己么,为什么不与之前统一一下 ...

  9. 【opencv学习笔记八】创建TrackBar轨迹条

    createTrackbar这个函数我们以后会经常用到,它创建一个可以调整数值的轨迹条,并将轨迹条附加到指定的窗口上,使用起来很方便.首先大家要记住,它往往会和一个回调函数配合起来使用.先看下他的函数 ...

随机推荐

  1. 算法竞赛进阶指南--lowbit运算,找到二进制下所有是1的位

    // lowbit运算,找到二进制下所有是1的位 int H[37]; // 预处理 for (int i = 0; i < 36; i++) H[(1ll << i) % 37] ...

  2. Eclipse中获取html jsp 标签的属性提示信息方法

    操作方法: windows------preferences----------搜索 html----------找到 html Source这项---------找到 content assist ...

  3. web安全笔记

    判断网站是否伪静态 把.html后缀即可或者加.php?id=99 例子:33_99.html   去掉.html和_变成33.php?id=99 即可判断是否伪静态 判断网站是否在win或者linu ...

  4. Codeforces Round #637 (Div. 2) 题解

    A. Nastya and Rice 网址:https://codeforces.com/contest/1341/problem/A Nastya just made a huge mistake ...

  5. Android 自定义View—清爽小巧灵活的多节点进度条

    前言 最近项目有一个节点进度条的小需求,完成后,想分享出来希望可以帮到有需要的同学. 真机效果图 自定义View完整代码 开箱即用~,注释已经炒鸡详细了 /** * @description: 节点进 ...

  6. 微软2016校园招聘在线笔试之Magic Box

    题目1 : Magic Box 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 The circus clown Sunny has a magic box. When ...

  7. MES系统的模型结构和主要功能(二)

    上一节,我们主要说了Mes系统是什么,以及它的特点和难点,本节,再来讨论一下一个合格的MES系统的模型结构和基本功能. 现代工厂的快速发展,对MES系统提出了更高的要求,其必须满足范围广泛的任务要求, ...

  8. D. Distance in Tree(树型Dp计数)

    \(其实思路都能想到一点,就是去重这里特别麻烦,没有好的思路.\) \(设dp[i][j]为以i为根深度为j的节点数量\) \(dp[parent][j]=\sum{dp[son][j-1]}\) \ ...

  9. 王颖奇 201771010129《面向对象程序设计(java)》第四周学习总结

    实验四 类与对象的定义及使用 实验时间 2018-9-20 1.目的与要求 学习目标 掌握类与对象的基础概念,理解类与对象的关系: 掌握对象与对象变量的关系: 掌握预定义类的基本使用方法,熟悉Math ...

  10. 前后端bug定位

    否一致一个商品状态为status,待上架status=0,上架中status=1,下架status=2 前端bug:如:一个商品上架成功后,数据库显示的状态status=1,这时候可能是前端对应值的定 ...