【Kubernetes】第十篇 - 灰度发布的介绍与实现

这篇具有很好参考价值的文章主要介绍了【Kubernetes】第十篇 - 灰度发布的介绍与实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一,前言

前几篇,已经介绍了环境搭建、Deployment 部署对象、Service 服务、Ingress 路由转发;

本篇,介绍灰度发布的实现;


二,灰度发布简介

灰度发布,也叫金丝雀发布;是一种应用的发布方式;

金丝雀发布的命名:金丝雀对瓦斯气体非常敏感,矿工在下井前会先向井里放一只金丝雀,如果金丝雀不叫了,代表瓦斯浓度高;

灰度发布,一般会在现存旧版本应用的基础上,启动一个新版本应用,这个新版本应用并不会直接让用户访问,而是提供给测试人员测试使用,若测试通过才会将真实的用户流量逐步导入到新版本应用中;

期间,将持续对新版本应用的运行状态进行监控,直至全部切换完成,这就是所谓的 A/B 测试;

过程中,也可以招募部分灰度用户,为他们设置独有的灰度标示(如:Cookie,Header 等),使这部分用户能够访问到新版本应用;

如果切换过程中出现问题,也能够迅速地将流量切换回旧版本的应用,时间版本回滚;


三,灰度发布

准备新版本 service

目前我有的 k8s 集群有 k8s-master 和 k8s-node 主从两个节点

查看当前 pods

当前,有 user-v1、pay-v1各 3 个副本

[root@k8s-master ~]# kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
mysql-g2zst                1/1     Running   52         43h
nginx-6799fc88d8-2wvl2     1/1     Running   0          44h
nginx-6799fc88d8-lkct4     1/1     Running   0          44h
nginx-6799fc88d8-pktqq     1/1     Running   0          44h
pay-v1-655587b6f5-lpft2    1/1     Running   0          77m
pay-v1-655587b6f5-pcnrp    1/1     Running   0          78m
pay-v1-655587b6f5-spj85    1/1     Running   0          77m
user-v1-5895c69847-649g5   1/1     Running   0          38h
user-v1-5895c69847-chrjk   1/1     Running   0          38h
user-v1-5895c69847-qnwg2   1/1     Running   0          38h
查看当前版本的 deployment 配置
[root@k8s-master ~]# cd deployment/
[root@k8s-master deployment]# ls
deployment-pay-v1.yaml  deployment-user-v1.yaml  deploy.yaml  
ingress.yaml  pay-service-v1.yaml  user-service-v1.yaml
v2 版本配置- deployment

拷贝 deployment

cp deployment-user-v1.yaml deployment-user-v2.yaml

修改 deployment-user-v2.yaml

将 4 处 user-v1,改为 user-v2 即可

[root@k8s-master deployment]# vi deployment-user-v2.yaml

apiVersion: apps/v1  #API版本号
kind: Deployment     #资源类型部署
metadata:
  name: user-v2      #资源名称
spec:
  selector:
    matchLabels:
      app: user-v2   #告诉deployment根据规则匹配相应的Pod进行控制和管理,matchLabels字段匹配Pod的label值
  replicas: 3        #声明Pod副本的数量
  template:
    metadata:
      labels:
        app: user-v2 #Pod名称
    spec:            #描述Pod内的容器信息
      containers:
      - name: nginx  #容器的名称
        image: nginx:user-v2 #镜像
        ports:
        - containerPort: 80 #容器内映射的端口
v2 版本配置- service

拷贝 service(之前的命名不规范,这次拷贝改好):

cp user-service-v1.yaml service-user-v2.yaml

修改 service-user-v2.yaml 指向新的部署对象 user-v2

vi service-user-v2.yaml

apiVersion: v1
kind: Service
metadata:
  name: service-user-v2
spec:
  selector:
    app: user-v2     #指向新的部署对象 user-v2
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: NodePort

v2 版本配置生效

这样,新建了一套 deployment、service,应用:

// 部署生效
[root@k8s-master deployment]# kubectl apply -f deployment-user-v2.yaml
deployment.apps/user-v2 created

// 服务生效
[root@k8s-master deployment]# kubectl apply -f service-user-v2.yaml 
service/service-user-v2 created

这时,已经可以访问了

查看部署对象:
// 查看部署对象
kubectl get deploy user-v2

// 实际执行
[root@k8s-master deployment]# kubectl get deploy user-v2
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
user-v2   3/3     3            3           76s
查看 service
// 查看部署对象
kubectl get service service-user-v2

// 实际执行
[root@k8s-master deployment]# kubectl get service service-user-v2
NAME              TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service-user-v2   NodePort   10.100.196.142   <none>        80:30289/TCP   106s

端口是 30289

查看 pod
// 查看部署对象
kubectl get pods

// 实际执行
[root@k8s-master deployment]# kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
mysql-g2zst                1/1     Running   52         43h
nginx-6799fc88d8-2wvl2     1/1     Running   0          44h
nginx-6799fc88d8-lkct4     1/1     Running   0          44h
nginx-6799fc88d8-pktqq     1/1     Running   0          44h
pay-v1-655587b6f5-lpft2    1/1     Running   0          91m
pay-v1-655587b6f5-pcnrp    1/1     Running   0          92m
pay-v1-655587b6f5-spj85    1/1     Running   0          91m
user-v1-5895c69847-649g5   1/1     Running   0          38h
user-v1-5895c69847-chrjk   1/1     Running   0          38h
user-v1-5895c69847-qnwg2   1/1     Running   0          38h
user-v2-fc9d84585-2zztd    1/1     Running   0          3m
user-v2-fc9d84585-ss2ss    1/1     Running   0          3m
user-v2-fc9d84585-xrvnf    1/1     Running   0          3m
查看 pod 详情
kubectl describe pods user-v2-fc9d84585-2zztd


[root@k8s-master deployment]# kubectl describe pods user-v2-fc9d84585-2zztd
Name:         user-v2-fc9d84585-2zztd
Namespace:    default
Priority:     0
Node:         k8s-node/172.17.178.106
Start Time:   Fri, 24 Dec 2021 11:21:53 +0800
Labels:       app=user-v2
              pod-template-hash=fc9d84585
Annotations:  <none>
Status:       Running
IP:           10.244.1.18
IPs:
  IP:           10.244.1.18
Controlled By:  ReplicaSet/user-v2-fc9d84585
Containers:
  nginx:
    Container ID:   docker://a9fa59653011df69396209ae3cb889de00cbd7d09833e64c7268a97fecbb0265
    Image:          nginx:user-v2
    Image ID:      nginx@sha256:f35c8618b9732397dbfca6e1ab2b9ada1513fb79cf00b18b7dead1c66ac7386a
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Fri, 24 Dec 2021 11:21:58 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-q4qxd (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-q4qxd:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-q4qxd
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  4m5s  default-scheduler  Successfully assigned default/user-v2-fc9d84585-2zztd to k8s-node
  Normal  Pulling    4m4s  kubelet            Pulling image "nginx:user-v2"
  Normal  Pulled     4m1s  kubelet            Successfully pulled image "nginx:user-v2" in 3.651009469s
  Normal  Created    4m    kubelet            Created container nginx
  Normal  Started    4m    kubelet            Started container nginx

主要看 Events 事件:

1,成功分配任务 default/user-v2 给到 k8s-node 节点处理

2,拉取镜像

3,拉取镜像成功

4,创建 nginx 容器

4,启动 nginx 容器

部署流程分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TgXGMPOj-1677328224477)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9e95a6bdc6bb47c0abddd68e2c810a79~tplv-k3u1fbpfcp-zoom-1.image)]

deployment 创建 replicateSetController

replicateSetController 控制 pod,负责 pod 的创建、扩容、缩容

但是,ingress 和 deploy 之间没有控制关系,只是一个请求转发的关系

ingress 接到请求后,会把请求转发给 service,service 再转发给 pod,pod 是由replicateSetController 创建的,replicateSetController 是由 deployment 创建的

查看 servece
[root@k8s-master deployment]# kubectl get services
NAME              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes        ClusterIP   10.96.0.1        <none>        443/TCP        2d11h
nginx             NodePort    10.107.223.32    <none>        80:32117/TCP   44h
service-pay-v1    NodePort    10.106.98.218    <none>        80:30872/TCP   98m
service-user-v1   NodePort    10.104.13.40     <none>        80:31071/TCP   23h
service-user-v2   NodePort    10.100.196.142   <none>        80:30289/TCP   18m

service-user-v2 的端口号是 30289

访问 service-user-v2

// 本地访问
curl http://127.0.0.1:30289
// k8s-master,内网 ip  
curl http://172.17.178.105:30289
// k8s-node,内网 ip  
curl http://172.17.178.106:30289

// 实际执行
[root@k8s-master deployment]# curl http://127.0.0.1:30289
user-v2
[root@k8s-master deployment]# curl http://172.17.178.105:30289
user-v2
[root@k8s-master deployment]# curl http://172.17.178.106:30289
user-v2

至此,新版本部署完成

\

下一步进行分发,让测试和灰度用户进行测试

如何标识这些用户呢?服务器的 ingress 怎么知道是普通用户还是灰度用户呢?需要标识

根据 Cookie 切分流量

\

canary:金丝雀

介绍

\

  • 基于 Cookie 切分流量。这种实现原理主要根据用户请求中的 Cookie 是否存在灰度标示 Cookie去判断是否为灰度用户,再决定是否返回灰度版本服务
  • nginx.ingress.kubernetes.io/canary:可选值为 true / false 。代表是否开启灰度功能
  • nginx.ingress.kubernetes.io/canary-by-cookie:灰度发布 cookie 的 key。当 key 值等于 always 时,灰度触发生效。等于其他值时,则不会走灰度环境 ingress-gray.yaml
具体实现

查看之前的 ingress.yaml 配置文件

[root@k8s-master deployment]# vi ingress.yaml 

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - http:
      paths:
       - path: /user
         backend:
          serviceName: service-user-v1
          servicePort: 80
       - path: /pay
         backend:
          serviceName: service-pay-v1
          servicePort: 80
  backend:
     serviceName: service-user-v1
     servicePort: 80

/user 访问 service-user-v1

/pay 访问 service-pay-v1

默认访问 service-pay-v1

创建灰度配置文件 ingress-gray.yaml
vi ingress-gray.yaml

apiVersion: extensions/v1beta1
kind: Ingress   #类型
metadata: #元数据
  name: user-canary
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/canary: "true" #启用灰度发布功能
    nginx.ingress.kubernetes.io/canary-by-cookie: "vip_user" #根据cookie标识vip_user区分
spec:
  rules:
  - http:
      paths:
      - backend: #后端  
          serviceName: service-user-v2
          servicePort: 80
  backend: #默认值
    serviceName: service-user-v2
    servicePort: 80

如果请求 cookie 中包含 vip_user,并且值为 always,访问 service-user-v2

生效配置文件
kubectl apply -f ingress-gray.yaml

// 实际执行
[root@k8s-master deployment]# kubectl apply -f ingress-gray.yaml
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
ingress.extensions/user-canary created
查看服务
  • 获取 ingress 的外部端口
  • -n: 根据资源名称进行模糊查询
kubectl -n ingress-nginx get service

// 实际执行
[root@k8s-master deployment]# kubectl -n ingress-nginx get service
NAME                                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.108.212.237   <none>        80:31234/TCP,443:31235/TCP   22h
ingress-nginx-controller-admission   ClusterIP   10.97.160.200    <none>        443/TCP                      22h

ingress-nginx-controller 端口号 31234

不携带 cookie 方法访问
curl http://172.17.178.105:31234/user

[root@k8s-master deployment]# curl http://172.17.178.105:31234/user
user-v1

当没有设置 cookie 时,就是 v1 版本

携带 cookise 访问
curl --cookie "vip_user=always" http://172.17.178.105:31234/user

[root@k8s-master deployment]# curl --cookie "vip_user=always" http://172.17.178.105:31234/user
user-v2

这样就实现了根据 cookie 进行流量分发

基于 Header 切分流量

介绍
  • 基于 Header 切分流量,这种实现原理主要根据用户请求中的 header 是否存在灰度标示 header去判断是否为灰度用户,再决定是否返回灰度版本服务
修改灰度配置文件
vi ingress-gray.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: user-canary
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/canary: "true"
+    nginx.ingress.kubernetes.io/canary-by-header: "role"
+    nginx.ingress.kubernetes.io/canary-by-header-value: "test"
spec:
  rules:
  - http:
      paths: 
       - backend:
          serviceName: service-user-v2
          servicePort: 80
  backend:
     serviceName: service-user-v2
     servicePort: 80

如果请求头中有 role 属性,值为test,进入 service-user-v2

启用配置并访问
[root@k8s-master deployment]# kubectl apply -f ingress-gray.yaml
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
ingress.extensions/user-canary configured

[root@k8s-master deployment]# curl --header "role:test" http://172.17.178.105:31234/user
user-v2

基于权重切分流量

介绍
  • 这种实现原理主要是根据用户请求,通过根据灰度百分比决定是否转发到灰度服务环境中
  • nginx.ingress.kubernetes.io/canary-weight:值是字符串,为 0-100 的数字,代表灰度环境命中概率。如果值为 0,则表示不会走灰度。值越大命中概率越大。当值 = 100 时,代表全走灰度
修改灰度配置
vi ingress-gray.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: user-canary
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/canary: "true"
+   nginx.ingress.kubernetes.io/canary-weight: "50"
spec:
  rules:
  - http:
      paths: 
       - backend:
          serviceName: service-user-v2
          servicePort: 80
  backend:
     serviceName: service-user-v2
     servicePort: 80
启用配置并访问
[root@k8s-master deployment]# kubectl apply -f ingress-gray.yaml
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
ingress.extensions/user-canary configured

[root@k8s-master deployment]# for ((i=1; i<=10; i++)); do curl http://172.17.178.105:31234/user; done
user-v2
user-v1
user-v2
user-v1
user-v1
user-v1
user-v2
user-v1
user-v1
user-v2

50%权重灰度

优先级

如果 3 种策略都设置了文章来源地址https://www.toymoban.com/news/detail-587268.html

  • canary-by-header -> canary-by-cookie -> canary-weight
  • k8s 会优先去匹配 header ,如果未匹配则去匹配 cookie ,最后是 weight

到了这里,关于【Kubernetes】第十篇 - 灰度发布的介绍与实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第十篇【传奇开心果系列】Ant Design Mobile of React 开发移动应用:涉及到的相关基础知识介绍和示例

    第一篇【传奇开心果系列】Ant Design Mobile of React 开发移动应用:从helloworld开始 第二篇【传奇开心果系列】Ant Design Mobile of React 开发移动应用:天气应用 第三篇【传奇开心果系列】Ant Design Mobile of React 开发移动应用:健身追踪 第四篇【传奇开心果系列】Ant Design Mobile of React 开发移

    2024年01月20日
    浏览(43)
  • Kubernetes(k8s)使用ingress发布服务

    目录 一.系统环境 二.前言 三.Kubernetes ingress简介 四.Ingress vs NodePort vs LoadBalancer 五.安装部署Nginx Ingress Controller控制器 六.使用Ingress来发布Kubernetes服务 6.1 创建3个pod 6.2 配置ingress规则发布服务 七.总结 本文主要基于Kubernetes1.21.9和Linux操作系统CentOS7.4。 服务器版本 Nginx Ingress C

    2024年02月08日
    浏览(38)
  • 云原生周刊:Kubernetes v1.28 正式发布 | 2023.8.21

    kurt 一个 Kubernetes 插件,可提供 Kubernetes 集群中重启内容的上下文信息。 Kubean Kubean 是一个基于 kubespray 的 Kubernetes 集群生命周期管理工具。 k8sgpt k8sgpt 是一款用简单的英语扫描 Kubernetes 集群、诊断和分流问题的工具。 它将 SRE 经验编入其分析器中,有助于提取最相关的信息,

    2024年02月11日
    浏览(37)
  • jenkins发布Kubernetes(K8s)集群(基于containerd)

    上一篇文章 Jenkins入门与安装 1、k8s环境 版本 v1.26.5 ,容器为containerd 二进制安装Kubernetes(K8s)集群(基于containerd)—从零安装教程(带证书) 主机名 IP 系统版本 安装服务 master01 10.10.10.21 rhel7.5 nginx、etcd、api-server、scheduler、controller-manager、kubelet、proxy master02 10.10.10.22 rhel7.5 ngin

    2024年02月09日
    浏览(82)
  • 【K8S】Kubernetes 中滚动发布由浅入深实战

    Kubernetes及其强大的特点之一就是超大规模集群应用的自动化部署,这其中包括了应用的扩容、缩容及其自适应扩缩容(HPA、VPA)。 在滚动发布的过程中,Kubernetes会对要进行升级的应用所属Pod进行逐个的替换,直至将所有的Pod都替换为新版本的Pod。整个过程中新老版本的Pod都

    2024年01月24日
    浏览(41)
  • 多线程&并发篇---第十篇

    ArrayBlockingQueue 是一个基于数组结构的 有界阻塞队列, 此队列按 FIFO(先进先出)原则 对元素进行排序。 LinkedBlockingQueue 一个基于链表结构的 阻塞队列 ,此队列按FIFO (先进先出) 排序元 素,吞吐量通常要高于 ArrayBlockingQueue 。 SynchronousQueue 一个不存储元素的 阻塞队列 。

    2024年02月07日
    浏览(28)
  • springcloud+nacos实现灰度发布

    灰度发布实体 灰度发布上下文信息 灰度过滤器设置灰度上下文信息 灰度路由规则 gateway网关需要引入的pom 常量 服务路由规则 需要传递灰度版本号,所以需要把灰度版本请求参数传递下去,以及解决Hystrix的线程切换导致参数无法传递下的问题 使用TransmittableThreadLocal可以跨线

    2024年02月12日
    浏览(23)
  • 13.Kubernetes应用部署完整流程:从Dockerfile到Ingress发布完整流程

    本文以一个简单的Go应用Demo来演示Kubernetes应用部署的完整流程 Dockerfile多阶段构建 结合 12.Harbor构建私有镜像仓库 ,构建镜像并推送的私有仓库

    2024年02月02日
    浏览(48)
  • 微服务开发系列 第十篇:Gateway

    A、技术栈 开发语言:Java 1.8 数据库:MySQL、Redis、MongoDB、Elasticsearch 微服务框架:Spring Cloud Alibaba 微服务网关:Spring Cloud Gateway 服务注册和配置中心:Nacos 分布式事务:Seata 链路追踪框架:Sleuth 服务降级与熔断:Sentinel ORM框架:MyBatis-Plus 分布式任务调度平台:XXL-JOB 消息中间

    2024年02月09日
    浏览(36)
  • 关于标准那些事——第十篇 分类标准

            最近要赶一个极其重要的CANS认证项目,这会是全中国第一个完全数字化CNAS认证的实验室项目,内容分享进度会比较慢。其实,大多数情况也并不是没有时间,俗话说:时间嘛,挤挤总是有的!其实影响进度更重要的是心情,特别是写东西,没时间往往只是给自己

    2024年01月25日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包