Go微服务架构实战 中篇:5. k8s基于ingress和service实现金丝雀发布和蓝绿发布

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: Go微服务架构实战 中篇:5. k8s基于ingress和service实现金丝雀发布和蓝绿发布

5. 基于ingress和service实现灰度发布



关于灰度发布有好几种方式,比如蓝绿发布,滚动发布以及金丝雀发布。基于它们的表现形式不同,可以在不同场景下做到灵活应用。


细分的话基于Request Header的流量切分,基于Cookie的流量切分以及基于服务权重的流量切分都是灰度发布的具体表现,那我们这篇文章重点来聊聊蓝绿发布和金丝雀发布。


先大概介绍下这三种发布:


蓝绿发布:蓝绿部署是不停老版本,部署新版本然后进行测试,确认OK,将流量切到新版本,然后老版本同时也升级到新版本。


也就是说老版本(绿)在提供服务的时候,新版本上线(蓝),把流量全部切到新版本之后,如果验证通过就直接将老版本资源释放掉(下线机器等资源).


这种方式风险太大,一旦新版本有问题,回退之后切到原来老版本上,那么数据库里面的数据有可能因为这次灰度变脏了,怎么处理这些数据需要较强的运维能力和解决问题能力。


所以蓝绿发布不太适合高并发的场景中,比较适合后台这样的系统发布。


滚动发布:摘除一个发布一个,当然前提是你有多个这样的服务。那如果是一个呢?那我们为了不停机提供服务,首先得先起一个服务,然后把新进来的流量都打到刚才起的服务上,然后等摘除的服务把它原本处理的流量处理完成之后就可以选择下线了。


这种方式是比较建议的一种部署方式,也是k8s比较推荐的。这个上篇文章已经讲过实操,这里就不再演示了。


金丝雀发布:不用解释太多,看这个故事就知道了。


矿井中的金丝雀 17世纪,英国矿井工人发现,金丝雀对瓦斯这种气体十分敏感。空气中哪怕有极其微量的瓦斯,金丝雀也会停止歌唱;而当瓦斯含量超过一定限度时,虽然鲁钝的人类毫无察觉,金丝雀却早已毒发身亡。当时在采矿设备相对简陋的条件下,工人们每次下井都会带上一只金丝雀作为“瓦斯检测指标”,以便在危险状况下紧急撤离。


故事结束之后我们总结下经验:新老服务都在线,只不过新上的服务可能是一个,等新的服务没有问题之后,把剩余的服务全部升级到新的服务。


这种发布也是灰度的一种,也是比较推荐的。

接下来看下蓝绿发布和金丝雀发布实操。


1. 蓝绿发布


  1. 准备好两个版本的Deployment

deploy.yaml(v1.0.0)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8sdemo-deploy
  labels:
    app: k8sdemo
    version: 1.0.0 # pod版本
spec:
  replicas: 1
  selector:
    matchLabels:
      app: k8sdemo
      version: 1.0.0
  template:
    metadata:
      labels:
        app: k8sdemo
        version: 1.0.0
    spec:
      containers:
      - name: k8sdemo
        image: k8s-grpc-demo:v2
        imagePullPolicy: Never


deploy1.yaml(v1.0.1)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8sdemo-deploy-old
  labels:
    app: k8sdemo
    version: 1.0.1 # pod版本
spec:
  replicas: 1
  selector:
    matchLabels:
      app: k8sdemo
      version: 1.0.1
  template:
    metadata:
      labels:
        app: k8sdemo
        version: 1.0.1
    spec:
      containers:
      - name: k8sdemo
        image: k8s-grpc-demo:v6
        imagePullPolicy: Never


service.yaml

apiVersion: v1
kind: Service
metadata:
  name: k8sdemo-svc
spec:
  ports:
    - name: k8sdemo-svc
      port: 8000
      targetPort: 60001
  selector:
    app: k8sdemo
    version: 1.0.0 # 关联pod的版本
  type: NodePort


ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: k8sdemo-ingress-prefix
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
    - host: hi.k8sdemo.com
      http:
        paths:
          - path: "/hello"
            pathType: ImplementationSpecific
            backend:
              service:
                name: k8sdemo-svc # 关联service
                port:
                  number: 8000


直接kubectl apply -f .就都创建好了。


我们首先访问下老的服务:

docker@minikube:~$ curl -X POST http://hi.k8sdemo.com:31721/hello -d '{"name": "fromGW"}'
{"message":"Hello fromGW from 172.17.0.3:50009"}


没问题之后我们最后升级发布新的版本:在service.yaml中只需修改version=1.0.1就可以了。

apiVersion: v1
kind: Service
metadata:
  name: k8sdemo-svc
spec:
  ports:
    - name: k8sdemo-svc
      port: 8000
      targetPort: 60001
  selector:
    app: k8sdemo
    version: 1.0.1 # 这里从1.0.0 到 1.0.1
  type: NodePort


再次kubectl apply -f service.yaml


我们访问看下:

docker@minikube:~$ curl -X POST http://hi.k8sdemo.com:31721/hello -d '{"name": "fromGW"}'
{"message":"[gray] Hello fromGW from 172.17.0.7:50009"}


可以看到这次返回的内容就是我们新增加或者修改的内容,因为它带有[gray]标识‼️


最后我们就可以把老的服务下线:

kubectl delete deploy k8sdemo-deploy

这样就完成了服务的蓝绿部署。


2. 金丝雀发布


还是上面几个yaml文件,只不过策略上有点区别,就是老的v1.0.0多起几个pod,比如这里我们扩容到3个pod;我们新的服务就一个v1.0.1的pod。


大家可以看下:

640.png


接下来为了测试,service.yaml需要把version标签去掉,因为这次我们允许新的服务也提供线上服务(新老共存)。service.yaml:


apiVersion: v1
kind: Service
metadata:
  name: k8sdemo-svc
spec:
  ports:
    - name: k8sdemo-svc
      port: 8000
      targetPort: 60001
  selector:
    app: k8sdemo
  type: NodePort


我们访问看下:


docker@minikube:~$ while true; do curl -X POST http://hi.k8sdemo.com:31721/hello -d '{"name": "fromGW"}'; done
{
 "message": "Hello fromGW from 172.17.0.3:50009"
} 
{
 "message": "Hello fromGW from 172.17.0.8:50009"
} 
{
 "message": "Hello fromGW from 172.17.0.8:50009"
} 
{
 "message": "[gray] Hello fromGW from 172.17.0.7:50009"
}


我们看到是RR轮循的方式把流量负载均衡到各个pod中。最后我们也看到[gray]出现在我们的打印中。


当我们验证没有问题之后我们就可以把流量全部切换到新的版本中,只需要修改service.yaml加上新的版本号即可,然后通过kubectl scale扩容到和老的服务一样的数量。


这种就是按照1:3的流量做灰度的。这在规模比较小的时候可以使用,当规模达到成千上万的时候,不建议这么做了。


写到这里我不禁感叹:技术的发展就是把人变得懒惰一点,原本部署很复杂的事情,但是你两行命令就搞定了,剩下的时间干什么呢?喝杯咖啡打发掉还能怎样?


3. 小结


基于k8s的ingress和service实现的灰度发布方案到这里就结束了,因为k8s对细粒度的灰度支持不太友好,所以我们需要借助第三方组件帮助我们完成,比如云厂商提供的ingress以及istio提供的ingress,像这样的ingress就可以做到真正的全方位的灰度发布。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
14天前
|
存储 Kubernetes 负载均衡
Kubernetes设计架构
Kubernetes 是一个开源的容器编排平台,用于自动化应用的部署、扩展和管理。其设计架构高度可扩展且灵活,能管理大规模分布式系统。核心组件包括集群(含主节点和工作节点)、API 服务器、etcd、控制器管理器、调度器、Pod、服务、命名空间、配置管理、持久化存储、网络模型及扩展性支持。这些组件共同实现了应用的高效运行与管理。
46 7
|
13天前
|
Kubernetes API 调度
Kubernetes 架构解析:理解其核心组件
【8月更文第29天】Kubernetes(简称 K8s)是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用。它提供了一个可移植、可扩展的环境来运行分布式系统。本文将深入探讨 Kubernetes 的架构设计,包括其核心组件如何协同工作以实现这些功能。
36 0
|
5天前
|
Kubernetes Go Docker
在K8s编程中如何使用Go
一文带你了解在K8s编程中如何使用Go
23 3
|
10天前
|
缓存 安全 Java
如何利用Go语言提升微服务架构的性能
在当今的软件开发中,微服务架构逐渐成为主流选择,它通过将应用程序拆分为多个小服务来提升灵活性和可维护性。然而,如何确保这些微服务高效且稳定地运行是一个关键问题。Go语言,以其高效的并发处理能力和简洁的语法,成为解决这一问题的理想工具。本文将探讨如何通过Go语言优化微服务架构的性能,包括高效的并发编程、内存管理技巧以及如何利用Go生态系统中的工具来提升服务的响应速度和资源利用率。
|
17天前
|
Kubernetes 应用服务中间件 API
【Ingress 秘籍】集群进出流量的总管:揭秘 Kubernetes 中 Ingress 的终极奥秘!
【8月更文挑战第25天】Ingress是Kubernetes中用于管理HTTP与HTTPS流量进入集群的核心功能。作为集群内外通信的桥梁,Ingress通过定义规则将外部请求导向内部服务。本文详细介绍了Ingress的基本概念、配置方法及其实现方式。通过使用不同的Ingress控制器(如Nginx、Traefik等),用户可以根据需要选择最适合的方案。文中还提供了示例代码展示如何创建服务、部署应用及配置Ingress规则。
49 6
|
23天前
|
Kubernetes 负载均衡 应用服务中间件
在k8S中,ingress是什么?
在k8S中,ingress是什么?
|
23天前
|
Kubernetes 监控 测试技术
在K8S中,如何实现金丝雀发布(灰度发布)?蓝绿发布?
在K8S中,如何实现金丝雀发布(灰度发布)?蓝绿发布?
|
11天前
|
API UED 开发者
超实用技巧大放送:彻底革新你的WinForms应用,从流畅动画到丝滑交互设计,全面解析如何在保证性能的同时大幅提升用户体验,让软件操作变得赏心悦目不再是梦!
【8月更文挑战第31天】在Windows平台上,使用WinForms框架开发应用程序时,如何在保持性能的同时提升用户界面的吸引力和响应性是一个常见挑战。本文探讨了在不牺牲性能的前提下实现流畅动画与交互设计的最佳实践,包括使用BackgroundWorker处理耗时任务、利用Timer控件创建简单动画,以及使用Graphics类绘制自定义图形。通过具体示例代码展示了这些技术的应用,帮助开发者显著改善用户体验,使应用程序更加吸引人和易于使用。
29 0
|
16天前
|
消息中间件 NoSQL Kafka
go-zero微服务实战系列(九、极致优化秒杀性能)
go-zero微服务实战系列(九、极致优化秒杀性能)
|
16天前
|
NoSQL 关系型数据库 API
你还在手撕微服务?快试试 go-zero 的微服务自动生成
你还在手撕微服务?快试试 go-zero 的微服务自动生成