k8s如何滚动升级应用

本文基于《Kubernetes in Action》第9章整理。

在进入正文前,不得不感慨一下标签选择器的设计对解耦k8s各模块发挥的作用。k8s的service, replicaSet, 滚动升级,调度的亲缘性和污点容忍度都离不开标签选择器。标签选择器让k8s对资源的操作更加灵活。

手动进行滚动升级

我们先用如下的配置创建一个ReplicationController

apiVersion: v1
kind: ReplicationController
metadata:
  name: kubia-v1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: kubia
  template:
    metadata:
      name: kubia
      labels:
        app: kubia
    spec:
      containers:
        - image: test:v1
          name: my-container

并创建一个service,其标签选择器是 “app: kubia”

现在我们想要更新镜像,可以执行如下步骤进行滚动升级。

  • 新建一个新的ReplicationController,如下所示
apiVersion: v1
kind: ReplicationController
metadata:
  name: kubia-v2
spec:
  replicas: 0
  selector:
    matchLabels:
      app: kubia
      deployment: 757d16 # 增加标签,用于标记此次的升级记录
  template:
    metadata:
      name: kubia
      labels:
        app: kubia
        deployment: 757d16 # 增加标签,用于标记此次的升级记录
    spec:
      containers:
        - image: test:v2 # 修改镜像
          name: my-container
  • 为原pod和ReplicationController增加标签:deployment: 343der。此时,kubia-v1还是管理着原先的pod,kubia-v2新建的pod不会被kubia-v1管理。但是不论kubia-v1还是kubia-v2创建的pod,都会和之前建的service关联。
  • 逐步扩容kubia-v2,并逐步缩容kubia-v1,直至所有pod都是由kubia-v2管理,则此次滚动升级结束

上述的步骤,也是之前kubectl的roling-update命令执行的大概过程。

这个过程存在以下弊端

  1. 过程繁琐。需要多次和API服务器交互
  2. 是在客户端执行,因此无法保证一致性,如果在滚动升级过程中和API服务器的交互出现问题,则pod, rc等资源会处于中间状态
  3. 不符合k8s的设计理念。应该通过设置期望的状态而不是告诉需要做哪些事情

通过Deployment滚动升级

首先创建以下配置,命名为deployment.yaml

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: kubia
spec:
  replicas: 3
  progressDeadlineSeconds: 600 # 滚动升级失败的超时时间
  minReadySeconds: 10 # 需要容器就绪多久后才能认为可用,在可用前,滚动升级不会继续。这个可以用于控制滚动升级的速率
  strategy:
    rollingUpdate:
      maxSurge: 1 # 在期望副本数基础上,最多允许超出的pod实例数量,允许设置绝对值和百分比
      maxUnavailable: 25% # 相对于期望副本数,允许有多少pod实例处于不可用状态,允许设置绝对值和百分比
    type: RollingUpdate # 表示滚动升级。也可以配置成 Recreate,其会一次性删除所有旧版本的pod,然后创建新的pod
  selector:
    matchLabels:
      app: kubia
  template:
    metadata:
      name: kubia
      labels:
        app: kubia
    spec:
      containers:
        - image: test:v1
          name: my-container

执行下面命令会创建Deployment

kubectl create -f deployment.yaml --record

--record会记录历史版本号,在回滚时会很有用

随后,这个deployment会创建一个ReplicaSet,然后新建的ReplicaSet再去创建pod,不过这个都不需要我们关注。所以,Deployment是比ReplicaSet更高级的资源,是用于协调多个ReplicaSet的。

修改pod模板才会触发滚动升级,因此修改deployment本身的配置,以及pod关联的ConfigMap等都不会触发滚动升级。当滚动升级开始的时候,会新建一个ReplicaSet,根据新的pod模板创建新的pod,并不断扩容新的ReplicaSet,缩容旧的ReplicaSet。过程类似上面介绍的手动滚动升级,区别是Deployment不会删除旧的ReplicaSet,因此可以方便的进行回滚。

滚动升级相关的命令是kubectl rollout,可以查看其都有哪些子命令

kubectl rollout history deployment my-deployment # 可以查看my-deployment的滚动升级历史
kubectl rollout pause deployment my-deployment # 可以暂停滚动升级
kubectl rollout resume deployment my-deployment # 可以恢复滚动升级
kubectl rollout status deployment my-deployment # 可以查看滚动升级中的状态
kubectl rollout undo deployment my-deployment --to-revision=1 # 回滚到指定版本

聊一下服务的上线

服务的上线是一个危险的动作,很多事故都是因为上线引起的。之所以危险,原因有很多,比如测试不到位,服务没有优雅退出,没有做好兼容等。所以对于服务的上线,需要足够的敬畏。

为了减少服务上线带来的事故,采取的措施一般有

  1. 封线。比如节假日前后,流量高峰期时一般不允许上线
  2. 周知。周知相关服务的负责人,让他们协助在服务上线期间一起观察服务有无异常
  3. 分阶段升级。比如第一次只升级其中一个实例,第二次升级3个实例,逐步放量,缓慢上线
  4. 做好观察。在服务上线期间,需要盯监控,关注告警,观察失败日志,在出现异常的时候第一时间会滚
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 下面是一个简单的 k8s 滚动升级的 YAML 模板: ``` apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deployment spec: replicas: 3 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: myapp:v2 ports: - containerPort: 80 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1 ``` 这个模板定义了一个 Deployment,名为 `myapp-deployment`,它由 3 个副本组成,副本使用镜像 `myapp:v2`。滚动升级策略是,在升级过程中最多允许 1 个副本不可用,最多允许新副本数量达到 1 个。 请注意,这只是一个简单的模板,实际情况可能会有所不同。例如,您可能希望为 Deployment 设置更复杂的选择器,或者指定更多的容器选项(例如环境变量、卷挂载等)。 希望这个模板对您有帮助! ### 回答2: Kubernetes(简称k8s滚动升级模板是一种描述如何更新Kubernetes集群中的应用程序的计划。下面是一个滚动升级的模板示例: 1. 创建Deployment对象来管理应用程序的部署。 ``` apiVersion: extensions/v1beta1 kind: Deployment metadata: name: my-app spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: my-app-container image: my-app:v1 ports: - containerPort: 8080 ``` 2. 执行滚动升级之前,在Deployment对象中更新镜像版本为新的版本。 ``` apiVersion: extensions/v1beta1 kind: Deployment metadata: name: my-app spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: my-app-container image: my-app:v2 ports: - containerPort: 8080 ``` 3. 执行kubectl apply命令来应用新的Deployment配置文件,触发滚动升级操作。 ``` kubectl apply -f deployment.yaml ``` 4. Kubernetes将逐步替换集群中的旧Pod实例,并创建新的Pod实例,以确保应用程序在滚动升级过程中保持可用性。此过程根据定义的副本数和滚动升级策略逐步进行。 滚动升级模板为应用程序提供了平滑的升级方式,使得应用程序能够持续提供服务而无需中断。我们可以通过适当定义滚动升级策略,例如最大不可用性和最小可用时间,来控制升级的速度和方式,以最大程度减少对用户的影响。 ### 回答3: 在使用Kubernetes进行滚动升级时,你可以按照以下模板进行操作: ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: your-deployment-name labels: app: your-app-label spec: replicas: 3 selector: matchLabels: app: your-app-label template: metadata: labels: app: your-app-label spec: containers: - name: your-container-name image: your-image:your-tag ports: - containerPort: your-port strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1 ``` 解释: - `your-deployment-name`:你的Deployment的名称,自定义命名。 - `your-app-label`:你的应用的标签,用于选择器和部署中的Pod匹配。 - `your-container-name`:你的容器的名称,自定义命名。 - `your-image:your-tag`:你的容器镜像和标签,指定要使用的镜像及其版本。 - `your-port`:你的容器暴露的端口号,根据实际情况进行修改。 - `maxUnavailable`:在进行滚动升级过程中,最大不可用的Pod数量,这里设置为1。 - `maxSurge`:在进行滚动升级过程中,最大可增加的Pod数量,这里设置为1。 以上模板定义了一个Deployment,它会创建3个Pod,并通过选择器将它们与Deployment关联起来。每个Pod都会运行一个容器,该容器使用指定的镜像和端口号。滚动升级策略被设置为RollingUpdate,最大不可用数量和最大增加数量都为1,以确保在升级期间保持可用性。 你可以将以上模板保存为一个YAML文件,然后使用`kubectl apply -f your-file.yaml`命令进行部署。当你需要升级应用时,可以通过更新镜像和标签,并再次执行`kubectl apply`命令来触发滚动升级过程。Kubernetes会逐步更新Pod,保持应用的可用性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值