百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 博客教程 > 正文

一文了解Kubernetes部署策略

connygpt 2024-08-22 12:48 10 浏览

什么是Kubernetes部署策略?

部署策略定义了如何创建、升级或降级不同版本的应用程序。在传统软件环境中,应用程序的部署或升级会导致停机和服务中断。Kubernetes可以帮助避免这种情况,它提供了多种部署策略,让您避免或最大限度地减少停机时间。

Kubernetes部署策略是一种声明性语句,它定义应用程序生命周期以及如何应用应用程序更新。它通常在YAML文件中配置为Kubernetes部署对象的一部分。还可以使用命令式方法通过显式命令创建部署。

在本文中,将介绍以下Kubernetes部署策略:

  • Rolling Update Deployment(滚动部署)默认策略,允许在不停机的情况下更新一组Pod。它会逐个用新版本替换运行旧版本应用程序的Pod
  • Recreate Deployment(重新创建部署)一种全有或全无的部署策略,可让您立即更新应用程序,但需要停机一段时间。它会终止所有Pod并将其替换为新版本
  • Ramped slow rollout(渐进式推出)渐进式推出新版本的副本,同时关闭旧副本
  • Best-effort controlled rollout(尽最大努力控制推出)指定"最大不可用"参数,该参数指示升级期间现有Pod中有多少百分比不可用,从而使推出速度更快。
  • Blue/Green Deployment(蓝绿部署)一种部署策略,在其中创建两个独立但相同的环境,然后转移到新环境。
  • Canary Deployment(金丝雀部署)采用渐进式交付方法,一个版本的应用程序服务于大多数用户,另一个较新的版本服务于一小部分测试用户。如果测试部署成功,则会向更多用户推出。
  • Shadow Deployment(影子部署)应用程序的新版本("影子"版本)与当前版本一起接收真实世界的流量,但不会影响最终用户。
  • A/B testing(A/B测试)同时向一部分用户推出应用程序功能的两个或多个版本,以查看哪个版本在用户参与度、错误率或其他KPI方面表现更好。

注意:虽然Kubernetes支持开箱即用的滚动部署和重新创建部署,但不支持其他类型,并且可能需要定制或专门的工具才能在Kubernetes集群中实现。

Kubernetes部署策略

1. 滚动部署

滚动部署是Kubernetes中的默认部署策略。它会用新版本替换现有版本的Pod,并逐个缓慢更新Pod,且不会造成集群停机。

滚动更新使用就绪探测(Readiness)来检查新Pod是否已准备就绪,然后再开始缩减旧版本的Pod。如果出现问题,您可以停止更新并将其回滚,而无需停止整个集群。

要执行滚动更新,只需使用kubectl set image更新Pod的镜像即可。这将自动触发滚动更新。

要优化部署策略,请更改清单文件的spec:strategy部分中的参数。有两个可选参数maxSurgemaxUnavailable

  • MaxSurge:指定Deployment一次允许创建的最大Pod数量。可以将其指定为整数(例如5),也可以将其指定为所需Pod总数的百分比(例如10%,始终向上舍入到下一个整数)。如果未设置MaxSurge,则隐式默认值为25%。
  • MaxUnavailable:指定在部署期间允许的最大不可用Pod数量。与MaxSurge 一样,可以将其定义为绝对数字或百分比。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - containerPort: 80

2. 重新创建部署

一种全有或全无的部署策略,可以通过将清单的spec :strategy:type部分设置为Recreate来定义它,如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  strategy:
    type: Recreate
  replicas: 4
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - containerPort: 80
        startupProbe:
          tcpSocket:
            port: 80
          initialDelaySeconds: 20
          periodSeconds: 5

重新创建策略可能会导致停机,因为在确保新Pod与新版本的应用程序一起推出之前,旧的Pod就被删除了。

3. 缓慢推出

渐进式推出会通过创建新副本并删除旧副本来逐步更新Pod。可以选择每次推出的副本数量。还需要确保没有任何Pod变得不可用。

此策略与常规滚动部署的区别在于,可以控制新副本的推出速度。例如,可以定义每次只更新1个或2个节点,以降低更新风险。要定义此行为,请将maxSurge设置为1,将maxUnvailable设置为0。这意味着Deployment将一次滚动一个Pod,同时确保没有Pod不可用。例如,如果有10个Pod,Deployment将确保至少10个Pod一次可用。

以下部署YAML文件执行渐进式部署

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - containerPort: 80

4. 尽最大努力控制推出

分阶段推出的缺点是,推出应用程序需要时间,尤其是大规模推出时。另一种选择是“尽最大努力控制推出”。这可以加快推出速度,但需要权衡更高的风险,因为需要容忍节点之间一定比例的停机时间。

这涉及:

  • 将maxUnavailable设置为一定百分比,这意味着更新可以容忍一定数量的Pod停机。
  • 将maxSurge设置为0,以确保Deployment中始终有相同数量的Pod。这可在更新期间提供最佳的资源利用率。

这样做的目的是尽快更换Pod,同时确保在任意给定时间内停机的Pod数量是有限的。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 20%
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - containerPort: 80

5. 蓝绿部署

在Kubernetes中的蓝绿部署中,可以维护部署的两个版本:“蓝”表示当前版本,“绿”表示新版本。

可以使用Kubernetes服务来管理两者之间的流量:

  • 最初,服务将所有流量路由到“蓝色”版本。
  • 在集群中将“绿色”版本与“蓝色”版本一起部署。
  • 一旦“绿色”版本准备就绪并经过测试,请更新服务以将流量路由到“绿色”版本。
  • 如果出现任何问题,可以将服务切换回指向“蓝色”版本。
  • 通过使用Kubernetes中的标签和选择器,可以轻松控制服务指向哪个版本的部署。

1). blue-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: blue-myapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      version: blue
  template:
    metadata:
      labels:
        app: myapp
        version: blue
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
          - name: http
            containerPort: 80
        startupProbe:
          tcpSocket:
            port: 80
          initialDelaySeconds: 20
          periodSeconds: 5

2). green-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: green-myapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      version: green
  template:
    metadata:
      labels:
        app: myapp
        version: green
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v2
        ports:
          - name: http
            containerPort: 80
        startupProbe:
          tcpSocket:
            port: 80
          initialDelaySeconds: 20
          periodSeconds: 5

3). 切换到版本绿色版本

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  selector:
    app: myapp
    version: green
  ports:
    - protocol: TCP
      port: 80
      targetPort: http

4). 回滚到蓝色版本(如果需要)

apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  selector:
    app: myapp
    version: blue
  ports:
    - protocol: TCP
      port: 80
      targetPort: http

6. 金丝雀部署

金丝雀部署通常用于在应用程序的后端测试一些新功能。同时部署两个或多个应用程序服务或版本,一个运行现有版本,另一个运行新功能。用户逐渐转向新版本,通过将新版本展示给真实用户来验证新版本。如果没有报告错误,则可以将其中一个新版本逐步部署给所有用户。

以下借助Istio来实现Kubernetes Canary Deployment的示例:

1). 创建版本v1的Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-v1
  namespace: istio-canary
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
      version: v1
  template:
    metadata:
      labels:
        app: my-app
        version: v1
    spec:
      containers:
      - name: my-app
        image: ikubernetes/myapp:v1
        ports:
        - containerPort: 80

2). 创建版本v2的Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-v2
  namespace: istio-canary
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
      version: v2
  template:
    metadata:
      labels:
        app: my-app
        version: v2
    spec:
      containers:
      - name: my-app
        image: ikubernetes/myapp:v2
        ports:
        - containerPort: 80

3). 创建Service

apiVersion: v1
kind: Service
metadata:
  name: my-app
  namespace: istio-canary
spec:
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 80

4). 配置Istio路由

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-app
  namespace: istio-canary
spec:
  host: my-app
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-app
  namespace: istio-canary
spec:
  hosts:
  - my-app
  http:
  - route:
    - destination:
        host: my-app
        subset: v2
      weight: 10
    - destination:
        host: my-app
        subset: v1
      weight: 90

此时,Kubernetes集群中应该运行着三个v1版本的实例和一个v2 版本的实例。通过访问my-app服务,您可以验证10%的流量会被路由到v2版本,其余的流量会被路由到v1版本。

5). 调整流量

如果v2版本运行正常,可以逐步增加v2的权重,减少v1的权重,直到完全替代v1版本。

http:
- route:
  - destination:
      host: my-app
      subset: v2
    weight: 50
  - destination:
      host: my-app
      subset: v1
    weight: 50

7. 影子部署

影子部署是一种方法,其中应用程序的新版本("影子"版本)与当前版本一起接收真实流量,但不会影响最终用户。这种部署策略允许团队实时测试系统在真实负载和数据下的表现。

在Kubernetes中,实现影子部署需要高级流量路由,通常使用Istio或Linkerd等服务网格完成:

  • 与当前版本一起部署影子版本。
  • 配置服务网格以复制传入流量,将一份副本发送到当前版本,将另一份副本发送到影子版本。
  • 监控影子版本的性能和错误,确保其运行符合预期。
  • 由于影子版本的结果不会返回给用户,因此它们不受影响。

1). 创建v1版本的Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-v1
  namespace: istio-shadow
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
      version: v1
  template:
    metadata:
      labels:
        app: my-app
        version: v1
    spec:
      containers:
      - name: my-app
        image: ikubernetes/myapp:v1
        ports:
        - containerPort: 80

2). 影子版本v2的Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-v2
  namespace: istio-shadow
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
      version: v2
  template:
    metadata:
      labels:
        app: my-app
        version: v2
    spec:
      containers:
      - name: my-app
        image: ikubernetes/myapp:v2
        ports:
        - containerPort: 80

3). 创建Service

apiVersion: v1
kind: Service
metadata:
  name: my-app
  namespace: istio-shadow
spec:
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 80

4). 配置Istio路由

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-app
  namespace: istio-shadow
spec:
  hosts:
  - my-app
  http:
  - route:
    - destination:
        host: my-app
        subset: v1
  - mirror:
      host: my-app
      subset: v2
    mirror_percent: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-app
  namespace: istio-shadow
spec:
  host: my-app
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

此时,Kubernetes集群中应该运行着三个v1版本的实例和一个v2版本的实例。通过访问my-app服务,实际生产流量会被路由到v1版本,同时流量的副本会被发送到v2版本。

8. A/B测试

在部署策略中,A/B测试是指同时向一部分用户推出应用程序功能的两个或多个版本,以查看哪个版本在用户参与度、错误率或其他KPI方面表现更好。

Kubernetes中的A/B测试通常需要部署和服务的组合,并可能需要入口控制器或服务网格的帮助来实现更细粒度的流量路由:

  • 并行部署功能的两个版本(A和B)。
  • 使用Kubernetes服务或入口控制器在两个版本之间拆分流量,例如50%到版本A,50%到版本B。
  • 监控两个版本的性能指标和用户反馈。
  • 一旦收集到足够的数据,就决定选择性能更好的版本并相应地调整流量,最终逐步淘汰不太优化的版本。

1). 版本A的Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-v1
  namespace: istio-abtest
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
      version: v1
  template:
    metadata:
      labels:
        app: my-app
        version: v1
    spec:
      containers:
      - name: my-app
        image: ikubernetes/myapp:v1
        ports:
        - containerPort: 80

2). 版本B的Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-v2
  namespace: istio-abtest
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
      version: v2
  template:
    metadata:
      labels:
        app: my-app
        version: v2
    spec:
      containers:
      - name: my-app
        image: ikubernetes/myapp:v2
        ports:
        - containerPort: 80

3). 创建Service

apiVersion: v1
kind: Service
metadata:
  name: my-app
  namespace: istio-abtest
spec:
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 80

4). 配置Istio路由

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: my-app
  namespace: istio-abtest
spec:
  host: my-app
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: my-app
  namespace: istio-abtest
spec:
  hosts:
  - my-app
  http:
  - match:
    - headers:
        end-user:
          exact: user1
    route:
    - destination:
        host: my-app
        subset: v2
  - route:
    - destination:
        host: my-app
        subset: v1
      weight: 50
    - destination:
        host: my-app
        subset: v2
      weight: 50

此时,Kubernetes集群中应该运行着两个版本的应用(v1和v2),并且通过访问my-app服务,50%的流量会被路由到v1版本,50%的流量会被路由到v2版本。特定用户(如user1)会被固定路由到v2版本。

选择哪种Kubernetes部署策略?

  • 如果停机不是问题,那么重新创建是最容易实施的部署策略。
  • 如果停机是一个问题,那么渐进式部署蓝绿部署通常是一个不错的选择,但蓝绿部署成本更高且设置起来稍微复杂一些。
  • 如果对发布的质量没有信心则应使用Canary和A/B测试。这些策略以及影子将需要额外的集群组件(例如服务网格),从而增加成本和复杂性。

相关推荐

3分钟让你的项目支持AI问答模块,完全开源!

hello,大家好,我是徐小夕。之前和大家分享了很多可视化,零代码和前端工程化的最佳实践,今天继续分享一下最近开源的Next-Admin的最新更新。最近对这个项目做了一些优化,并集成了大家比较关注...

干货|程序员的副业挂,12个平台分享

1、D2adminD2Admin是一个完全开源免费的企业中后台产品前端集成方案,使用最新的前端技术栈,小于60kb的本地首屏js加载,已经做好大部分项目前期准备工作,并且带有大量示例代码,助...

Github标星超200K,这10个可视化面板你知道几个

在Github上有很多开源免费的后台控制面板可以选择,但是哪些才是最好、最受欢迎的可视化控制面板呢?今天就和大家推荐Github上10个好看又流行的可视化面板:1.AdminLTEAdminLTE是...

开箱即用的炫酷中后台前端开源框架第二篇

#头条创作挑战赛#1、SoybeanAdmin(1)介绍:SoybeanAdmin是一个基于Vue3、Vite3、TypeScript、NaiveUI、Pinia和UnoCSS的清新优...

搭建React+AntDeign的开发环境和框架

搭建React+AntDeign的开发环境和框架随着前端技术的不断发展,React和AntDesign已经成为越来越多Web应用程序的首选开发框架。React是一个用于构建用户界面的JavaScrip...

基于.NET 5实现的开源通用权限管理平台

??大家好,我是为广大程序员兄弟操碎了心的小编,每天推荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节省开发效率,实现不加班不熬夜不掉头发,是我的目标!??今天小编推荐一款基于.NE...

StreamPark - 大数据流计算引擎

使用Docker完成StreamPark的部署??1.基于h2和docker-compose进行StreamPark部署wgethttps://raw.githubusercontent.com/a...

教你使用UmiJS框架开发React

1、什么是Umi.js?umi,中文可发音为乌米,是一个可插拔的企业级react应用框架。你可以将它简单地理解为一个专注性能的类next.js前端框架,并通过约定、自动生成和解析代码等方式来辅助...

简单在线流程图工具在用例设计中的运用

敏捷模式下,测试团队的用例逐渐简化以适应快速的发版节奏,大家很早就开始运用思维导图工具比如xmind来编写测试方法、测试点。如今不少已经不少利用开源的思维导图组件(如百度脑图...)来构建测试测试...

【开源分享】神奇的大数据实时平台框架,让Flink&Spark开发更简单

这是一个神奇的框架,让Flink|Spark开发更简单,一站式大数据实时平台!他就是StreamX!什么是StreamX大数据技术如今发展的如火如荼,已经呈现百花齐放欣欣向荣的景象,实时处理流域...

聊聊规则引擎的调研及实现全过程

摘要本期主要以规则引擎业务实现为例,陈述在陌生业务前如何进行业务深入、调研、技术选型、设计及实现全过程分析,如果你对规则引擎不感冒、也可以从中了解一些抽象实现过程。诉求从硬件采集到的数据提供的形式多种...

【开源推荐】Diboot 2.0.5 发布,自动化开发助理

一、前言Diboot2.0.5版本已于近日发布,在此次发布中,我们新增了file-starter组件,完善了iam-starter组件,对core核心进行了相关优化,让devtools也支持对IAM...

微软推出Copilot Actions,使用人工智能自动执行重复性任务

IT之家11月19日消息,微软在今天举办的Ignite大会上宣布了一系列新功能,旨在进一步提升Microsoft365Copilot的智能化水平。其中最引人注目的是Copilot...

Electron 使用Selenium和WebDriver

本节我们来学习如何在Electron下使用Selenium和WebDriver。SeleniumSelenium是ThoughtWorks提供的一个强大的基于浏览器的开源自动化测试工具...

Quick 'n Easy Web Builder 11.1.0设计和构建功能齐全的网页的工具

一个实用而有效的应用程序,能够让您轻松构建、创建和设计个人的HTML网站。Quick'nEasyWebBuilder是一款全面且轻巧的软件,为用户提供了一种简单的方式来创建、编辑...