部署与发布策略 灰度发布

 灰度/滚动发布


灰度发布是金丝雀发布的延伸,是将发布分成不同的阶段/批次,每个阶段/批次的用户数量逐级增加。如果新版本在当前阶段没有发现问题,就再增加用户数量进入下一个阶段,直至扩展到全部用户。

灰度发布可以减小发布风险,是一种零宕机时间的发布策略。它通过切换线上并存版本之间的路由权重,逐步从一个版本切换为另一个版本。整个发布过程会持续比较长的时间, 在这段时间内,新旧代码共存,所以在开发过程中,需要考虑版本之间的兼容性,新旧代码共存不能影响功能可用性和用户体验。当新版本代码出现问题时,灰度发布能够比较快的回滚到老版本的代码上。

结合特性开关等技术,灰度发布可以实现更复杂灵活的发布策略。

部署与发布策略 灰度发布

优势:

  1. 用户体验影响比较小, 不需要停机发布

  2. 能够控制发布风险

劣势:

  1. 发布时间会比较长

  2. 需要复杂的发布系统和负载均衡器

  3. 需要考虑新旧版本共存时的兼容性

适用场景:

  1. 适合可用性较高的生产环境发布

通过注解来实现流量的分发 

灰度也是有一个线上的环境,现在要发灰度的时候,要让一小部分用户去收到这个新版本,这一小部分用户可以通过cooki或者header,或者通过ingress权重的方式去分配。

部署与发布策略 灰度发布

  • V1 旧版本正常运行中, 用户请求流量都在V1
  • V2 新版本开始发布, ingress控制, 通过header/cookie/weight 将一部分流量引到V2   10%
  • 更新Ingress ,    流量扩大到30%
  • 更新Ingress ,    流量扩大到60%
  • 更新Ingress ,    流量扩大到90%
  • 更新Ingress ,    流量扩大到100%
  • 此时测试没问题, 用V2 helm chart 部署替换V1旧版本。
[root@master devops]# kubectl get svc -n devops
NAME       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
nginxapp   ClusterIP   10.233.34.137   <none>        80/TCP    46h
nginxnpm   ClusterIP   10.233.18.40    <none>        80/TCP    46h


[root@master devops]# kubectl get pod -n devops
NAME                                   READY   STATUS    RESTARTS   AGE
nginx-npm-blue-6c5ddc9ffd-jl25q        1/1     Running   1          46h
nginx-npm-blue-6c5ddc9ffd-qx2kw        1/1     Running   1          46h
nginx-npm-blue-6c5ddc9ffd-vhtnx        1/1     Running   1          46h
nginxapp-1.20-green-5668c79ff7-9l7kl   1/1     Running   1          46h
nginxapp-1.20-green-5668c79ff7-fckpc   1/1     Running   1          46h
nginxapp-1.20-green-5668c79ff7-vmvq9   1/1     Running   1          46h
[root@master ~]# curl 10.233.18.40  
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>vuedemo</title><link href=/static/css/app.30790115300ab27614ce176899523b62.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.2ae2e69a05c33dfc65f8.js></script><script type=text/javascript src=/static/js/vendor.0aad2172a75b8ed4f46c.js></script><script type=text/javascript src=/static/js/app.2f2e5edd9af2c59aa514.js></script></body></html>[root@master ~]# 
[root@master ~]# 

[root@master ~]# curl 10.233.34.137
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

现在生产 

[root@master devops]# cat ingress.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginxnpm-ingress
  namespace: devops
spec:
  rules:
  - host: nginxnpm.devops.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginxapp
          servicePort: 80

基于权重的发布


[root@master devops]# cat ingress-weight.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginxapp-canary
  namespace: devops
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "50"
spec:
  rules:
  - host: nginxnpm.devops.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginxnpm
          servicePort: 80

部署与发布策略 灰度发布

部署与发布策略 灰度发布 

 访问同一个页面两次,分别请求到了不同的版本。

Header报头流量分发


在访问的时候可以通过请求头进行区分的,比如来自于北京的,那么可以先让来自北京的用户先看到,那么就可以根据请求头里面的信息来匹配。

下面就是北京来的请求访问新版本。

[root@master devops]# cat ingress-header.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginxapp-canary
  namespace: devops
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-header: "Region"
    nginx.ingress.kubernetes.io/canary-by-header-value: "bj"
spec:
  rules:
  - host: nginxnpm.devops.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginxnpm
          servicePort: 80

杭州来的用户访问,流量用的还是老版本

[root@master devops]# for i in {1..2};do curl -H "region: hz" nginxnpm.devops.com && sleep 5s;done
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>


<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

 北京来的用户访问,用的流量是新版本

[root@master devops]# for i in {1..2};do curl -H "region: bj" nginxnpm.devops.com && sleep 5s;done
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>vuedemo</title><link href=/static/css/app.30790115300ab27614ce176899523b62.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.2ae2e69a05c33dfc65f8.js></script><script type=text/javascript src=/static/js/vendor.0aad2172a75b8ed4f46c.js></script><script type=text/javascript src=/static/js/app.2f2e5edd9af2c59aa514.js></script></body></html>

<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>vuedemo</title><link href=/static/css/app.30790115300ab27614ce176899523b62.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.2ae2e69a05c33dfc65f8.js></script><script type=text/javascript src=/static/js/vendor.0aad2172a75b8ed4f46c.js></script><script type=text/javascript src=/static/js/app.2f2e5edd9af2c59aa514.js></script></body></html>[root@master devops]# 

根据cookie流量分发


cookie只有两个值,一个是always(新版本),还有一个是never

[root@master devops]# cat ingress-cookie.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginxapp-canary
  namespace: devops
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-by-cookie: "from"
spec:
  rules:
  - host: nginxnpm.devops.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginxnpm
          servicePort: 80
[root@master devops]#  curl  nginxnpm.devops.com --cookie "from=always"
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>vuedemo</title><link href=/static/css/app.30790115300ab27614ce176899523b62.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.2ae2e69a05c33dfc65f8.js></script><script type=text/javascript src=/static/js/vendor.0aad2172a75b8ed4f46c.js></script><script type=text/javascript src=/static/js/app.2f2e5edd9af2c59aa514.js></script></body></html>[root@master devops]# 
[root@master devops]# 
[root@master devops]# 
[root@master devops]# 
[root@master devops]#  curl  nginxnpm.devops.com --cookie "from=a"
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
上一篇:基于Jenkins的DevOps工程实践学习资料


下一篇:数字化转型:敏捷和DevOps如何降低风险,提高速度