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

简介: 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搭建和管理企业级网站应用
相关文章
|
25天前
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。
|
1月前
|
Cloud Native Devops 云计算
云计算的未来:云原生架构与微服务的革命####
【10月更文挑战第21天】 随着企业数字化转型的加速,云原生技术正迅速成为IT行业的新宠。本文深入探讨了云原生架构的核心理念、关键技术如容器化和微服务的优势,以及如何通过这些技术实现高效、灵活且可扩展的现代应用开发。我们将揭示云原生如何重塑软件开发流程,提升业务敏捷性,并探索其对企业IT架构的深远影响。 ####
44 3
|
24天前
|
Java 开发者 微服务
从单体到微服务:如何借助 Spring Cloud 实现架构转型
**Spring Cloud** 是一套基于 Spring 框架的**微服务架构解决方案**,它提供了一系列的工具和组件,帮助开发者快速构建分布式系统,尤其是微服务架构。
144 68
从单体到微服务:如何借助 Spring Cloud 实现架构转型
|
23天前
|
运维 监控 持续交付
微服务架构解析:跨越传统架构的技术革命
微服务架构(Microservices Architecture)是一种软件架构风格,它将一个大型的单体应用拆分为多个小而独立的服务,每个服务都可以独立开发、部署和扩展。
157 36
微服务架构解析:跨越传统架构的技术革命
|
26天前
|
设计模式 负载均衡 监控
探索微服务架构下的API网关设计
在微服务的大潮中,API网关如同一座桥梁,连接着服务的提供者与消费者。本文将深入探讨API网关的核心功能、设计原则及实现策略,旨在为读者揭示如何构建一个高效、可靠的API网关。通过分析API网关在微服务架构中的作用和挑战,我们将了解到,一个优秀的API网关不仅要处理服务路由、负载均衡、认证授权等基础问题,还需考虑如何提升系统的可扩展性、安全性和可维护性。文章最后将提供实用的代码示例,帮助读者更好地理解和应用API网关的设计概念。
58 8
|
1月前
|
消息中间件 运维 Kubernetes
后端架构演进:从单体到微服务####
本文将探讨后端架构的演变过程,重点分析从传统的单体架构向现代微服务架构的转变。通过实际案例和理论解析,揭示这一转变背后的技术驱动力、挑战及最佳实践。文章还将讨论在采用微服务架构时需考虑的关键因素,包括服务划分、通信机制、数据管理以及部署策略,旨在为读者提供一个全面的架构转型视角。 ####
37 1
|
1月前
|
弹性计算 运维 开发者
后端架构优化:微服务与容器化的协同进化
在现代软件开发中,后端架构的优化是提高系统性能和可维护性的关键。本文探讨了微服务架构与容器化技术如何相辅相成,共同推动后端系统的高效运行。通过分析两者的优势和挑战,我们提出了一系列最佳实践策略,旨在帮助开发者构建更加灵活、可扩展的后端服务。
|
1月前
|
消息中间件 运维 Cloud Native
云原生架构下的微服务优化策略####
本文深入探讨了云原生环境下微服务架构的优化路径,针对服务拆分、通信效率、资源管理及自动化运维等核心环节提出了具体的优化策略。通过案例分析与最佳实践分享,旨在为开发者提供一套系统性的解决方案,以应对日益复杂的业务需求和快速变化的技术挑战,助力企业在云端实现更高效、更稳定的服务部署与运营。 ####
|
24天前
|
Cloud Native API 持续交付
云原生架构下的微服务治理策略与实践####
本文旨在探讨云原生环境下微服务架构的治理策略,通过分析当前面临的挑战,提出一系列实用的解决方案。我们将深入讨论如何利用容器化、服务网格(Service Mesh)等先进技术手段,提升微服务系统的可管理性、可扩展性和容错能力。此外,还将分享一些来自一线项目的经验教训,帮助读者更好地理解和应用这些理论到实际工作中去。 ####
37 0
|
1月前
|
负载均衡 Java 持续交付
深入解析微服务架构中的服务发现与负载均衡
深入解析微服务架构中的服务发现与负载均衡
66 0