灰度发布在实际生产部署中是经常被使用的方式,常规的方法是手动从前端LB(负载均衡)上将后端服务器摘掉,然后,停服务,最后上传代码,完成软连接更新。在使用CI/CD工具时,这个过程变得自动化了,我们只需要通过Jenkins这个功能强大的开源持续集成和部署工具,就可以联合Gitlab 或 Gogs 来实现自动拉取代码,并根据自己编写的pipeline脚本,实现自动连接到LB上摘掉后端Server,并自动连接到后端Server上,上传代码,并重启服务,最后通过邮件通知管理员整个过程的结果报告。但今天,K8s的更让我们看到了一种更便捷高效的灰度发布的实现方法,下面就来说说:

由于本人能力有限,对k8s的理解尚浅,原理部分在后续研究透彻后,在来详细说明,本编仅供初学者参考

首先需要制作此次实验的基础镜像:
1. Dockerfile的编写:
  mkdir dockerfile && cd dockerfile
  vim Dockerfile    #注意: Dockerfile的文件名首字母要大写
    FROM alpine:latest

    MAINTAINER "ZCF <zcf@zczf.com>"

    ENV NGX_DOC_ROOT="/var/lib/nginx/html" HOSTNAME="" IP="" PORT="" INDEX_PAGE=""
    RUN apk --no-cache add nginx && mkdir -p ${NGX_DOC_ROOT}/shop /run/nginx

    COPY chk.html   ${NGX_DOC_ROOT}
    COPY entrypoint.sh /bin

    CMD ["/usr/sbin/nginx","-g","daemon off;"] #定义启动nginx服务为前端启动, -g:是global段,中修改daemon off;
    ENTRYPOINT ["/bin/entrypoint.sh"] #将CMD的命令,作为参数传递给/bin/entrypoint.sh 脚本.

    #准备Dockerfile配套的基础文件:
    1) 启动容器时,执行的脚本文件: entrypoint.sh
      vim entrypoint.sh
        #!/bin/sh

        echo "<h1>WELCOME TO ${HOSTNAME:-www.zcf.com} WEB SITE | `date` | `hostname` | `hostname -i` | -${YOU_INFO:-v1}- | </h1>" > ${NGX_DOC_ROOT}/index.html
        cat > /etc/nginx/conf.d/default.conf <<EOF
        server {
          server_name ${HOSTNAME:-www.zcf.com};
          listen ${IP:-0.0.0.0}:${PORT:-80};
          root ${NGX_DOC_ROOT};
          location / {
            index ${INDEX_PAGE} index.html index.htm;
          }
          location = /404.html {
            internal;
          }
        }
        EOF

        exec "$@"      #它就是来接受CMD传入的参数的.

  2 ) 给entrypoint.sh 添加执行权限
    chown +x entrypoint.sh

  3) 后期做健康检查时,使用的html文件:
    echo OK > chk.html

2. 开始制作docker镜像文件:
  docker build --tag myapp:v1 ./

3. 将制作好的镜像文件,打上标签,并上传到harbor上。
  docker login harbor.zcf.com -u admin -p 123456      #登录harbor
  docker tag myapp:v1 harbor.zcf.com/k8s/myapp:v1      #先打上harbor仓库路径
  docker push harbor.zcf.com/k8s/myapp:v1         #再上传镜像到harbor上。

4. 为了方便延时恢复发布的效果,我们还需要在制作一个镜像
  docker run -d --name ngx1 -e YOU_INFO="DIY-HelloWorld-v2" harbor.zcf.com/k8s/myapp:v1
    #说明: -e 是指定要传递给容器的环境变量, 因为我提前在myapp中启动脚本entrypoint.sh中使用的了YOU_INFO这个环境变量,
    # 因此,这里我可以直接给容器传递这个变量,来实现修改nginx首页的效果.

  docker commit --pause ngx1      #将ngx1暂停,并将当前容器状态,导出为一个新镜像。

  docker kill ngx1 && docker rm -fv ngx1  #制作完镜像,就直接删除测试ngx1容器.

  root@k8s-n1:~# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    <none> <none> 85355d4af36c 6 seconds ago 7.02MB    #这个就上刚制作的新镜像.

  #给刚制作好的镜像打上标签:harbor.zcf.com/k8s/myapp:v2,便于上传到harbor上。
  docker tag 85355d4af36c harbor.zcf.com/k8s/myapp:v2

  #测试运行镜像,若没有问题,就可以上传到本地harbor上了。

  docker run -p 83:80 --rm -d --name ngx1 harbor.zcf.com/k8s/myapp:v2

  root@k8s-n1:~# curl http://192.168.111.80:83/    #测试镜像是否修改了nginx的首页为YOU_INFO的内容.
  <h1>WERCOME TO www.zcf.com WEB SITE | Fri Jul 19 02:31:13 UTC 2019 | ec4f08f831de | 172.17.0.2 | -DIY-HelloWorld-v2- | </h1>

  docker kill ngx1      #删除ngx1容器.

  docker push harbor.zcf.com/k8s/myapp:v2     #最后,上传新镜像到harbor上.

5. 现在已经有了,myapp:v1 和 myapp:v2 那就可以开始K8s的灰度发布测试了。

  #先创建三个pod,一个Client,两个Nginx
  #1. 先创建 Client
    kubectl run client --image=harbor.zcf.com/k8s/alpine:v1 --replicas=1
    #注意: alpine:是一个最小化的Linux系统,很多开源镜像站都可以下载到.
    kubectl get pods -o wide      #查看Pod的创建详情.

  #2. 创建Nginx
  kubectl run nginx --image=harbor.zcf.com/k8s/myapp:v1 --port=80 --replicas=2

  kubectl get deployment -w      #watch着监控k8s帮我们创建2个pod的过程.

  kubectl get pod -o wide

  #3. 登录Client,测试访问Nginx
  root@k8s-m1:/etc/ansible# kubectl get pod
    NAME READY STATUS RESTARTS AGE
    client-f5cdb799f-2wsmr 1/1 Running 2 16h
    nginx-6d6d8b685-7t7xj 1/1 Running 0 99m
    nginx-6d6d8b685-xpx5r 1/1 Running 0 99m

  kubectl exec -it client-f5cdb799f-2wsmr sh
  / # ip addr
  / # for i in `seq 1000`; do wget -O - -q http://nginx/ ; sleep 1; done
  / #    #说明: 若你的kube-dns没有部署成功,这里的nginx可换成Service的IP.
  / #    #   kubectl get svc |grep nginx    #这个就是Nginx的Service的集群IP.

  #4. 以上测试可看到,已经能够实现负载均衡的效果了。
    接着,开始进行灰度发布测试
    #更新myapp的镜像为myapp:v2
    kubectl set image --help
    kubectl set image deployment myapp myapp=harbor.zcf.com/k8s/myapp:v2    #升级myapp的镜像为myapp:v2

  #上面执行命令时,就可以看着,另一个终端中Client的访问变化情况,你可以发现,访问逐渐从 v1 变成 DIY-HelloWorld-v2了。

  #5.测试动态调整nginx Pod的数量
    kubectl scale --replicas=5 deployment nginx    #修改nginx的Pod副本数量为5个.
    kubectl get pods

  #接着在到Client所在的终端上,查看变化,你会发现,主机名和IP部分开始有更多变化了。

  #6. 查看nginx镜像升级状态,是否成功
    kubectl rollout status deployment nginx

  #7. 再查看myapp的镜像是否已经升级为最新的了
    kubectl describe pods nginx-xxx-xx

  #8. 将myapp回滚到之前的版本,即v1版本
    kubectl rollout undo --help
    kubectl rollout undo deployment nginx

6. 测试K8s集群外部访问nginx
  #修改 myapp service的类型,让它能被集群外部的客户端访问.
    kubectl edit svc myapp
      #type: ClusterIP 把它修改为 type:NodePort

  #查看svc的更新信息:
    kubectl get svc #这里就可以看到,myap service的端口将动态增加一个. 如:80:30020/TCP,注意:30020是随机分配的。
             #它的范围是,你在使用kubeasz部署时,设置 NODE_PORT_RANGE="30000-60000"中随机选的.

  #接着就可以在集群外部的客户端去访问myapp了
    http://Master或Node的物理IP:30020/

#好了,以上测试结果,我就不截图了,想看到结果的道友们要多多动手测试,然后多多总结,多多思考,就可以看到,并且明白了。

k8s实现灰度发布的更多相关文章

  1. k8s+istio:流量控制之灰度发布

    通过Kubernetes+Istio的流量控制实现灰度发布,主要演示通过流量权重实现蓝绿,通过http自定义头实现金丝雀 准备环境 k8s和istio不想自己装的话可以在云上买个按量付费集群,用完即删 ...

  2. Istio最佳实践:在K8s上通过Istio服务网格进行灰度发布

    Istio是什么? Istio是Google继Kubernetes之后的又一开源力作,主要参与的公司包括Google,IBM,Lyft等公司.它提供了完整的非侵入式的微服务治理解决方案,包含微服务的管 ...

  3. 基于ambassador实现K8S灰度发布

    为什么需要灰度发布 灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式.在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对 ...

  4. K8S基于ingress-nginx实现灰度发布

    之前介绍过使用ambassador实现灰度发布,今天介绍如何使用ingre-nginx实现. 介绍 Ingress-Nginx 是一个K8S ingress工具,支持配置 Ingress Annota ...

  5. ASP.NET Core on K8S学习之旅(14)Ingress灰度发布

    本篇已加入<.NET Core on K8S学习实践系列文章索引>,可以点击查看更多容器化技术相关系列文章. 之前一篇介绍了Ingress的基本概念和Nginx Ingress的基本配置和 ...

  6. K8s 1.18.6版本基于 ingress-nginx 实现金丝雀发布(灰度发布)

    K8s 1.18.6版本基于 ingress-nginx 实现金丝雀发布(灰度发布) 环境 软件 版本 kubernetes v1.18.6 nginx-ingress-controller 0.32 ...

  7. 采用轻量ServiceMesh实现灰度发布的实践

    软件总会有缺陷的,解决问题的同时往往会引入新的问题,关键是看这些问题是否在我们的控制范围内,“灰度发布”就是让问题受控的方法之一. 前言 我们的 CTO 经常说:“研发团队最首要的任务是提供稳定的服务 ...

  8. 基于 K8s 做应用发布的工具那么多, 阿里为啥选择灰姑娘般的 Tekton ?

    作者 | 邓洪超,阿里云容器平台工程师, Kubernetes Operator 第二人,云原生应用标准交付与管理领域知名技术专家   导读:近年来,越来越多专门给 Kubernetes 做应用发布的 ...

  9. CODING DevOps + Nginx-ingress 实现自动化灰度发布

    作者:王炜,CODING DevOps 后端开发工程师,拥有多年研发经验,云原生.DevOps.Kubernetes 资深爱好者,Servicemesher 服务网格中文社区成员.获得 Kuberne ...

随机推荐

  1. kafka controller脑裂(多个controller)问题

    问题:情况一:创建topic成功,但是produce的时候,却报unknown partition的错误,但zk上却显示了每个partition的leader信息:情况二: 给某个topic增加分区, ...

  2. C# vb .NET读取识别条形码线性条码code39

    code39是比较常见的条形码编码规则类型的一种.如何在C#,vb等.NET平台语言里实现快速准确读取该类型条形码呢?答案是使用SharpBarcode! SharpBarcode是C#快速高效.准确 ...

  3. 彻底理解javascript中的this指针

    http://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/ https://www.benn ...

  4. Jemeter学习环境部署。

    本文档中所有软件的下载地址 链接:https://pan.baidu.com/s/1RREUwlH7GtYMUWeiRjtWVg 提取码:zmjy 一.安装jdk 下载网盘中的jdk 双击jdk-8u ...

  5. 在浏览器中输入 url 地址到显示主页的过程

    总体来说分为以下几个过程:1. DNS 解析2. TCP 连接3. 发送 HTTP 请求4. 服务器处理请求并返回 HTTP 报文5. 浏览器解析渲染页面6. 连接结束

  6. 基于OpenGL的三维曲面动态显示实现

    在使用Visual C++的MFC AppWizard建立应用程序框架后,生成了多个类,与OpenGL编程相关的类是视图类,主要的显示任务都在其中完成. 1.基于OpenGL绘图的基本设置 1.1 设 ...

  7. Spring中获取外部配置文件中的属性值

    很多时候需要将配置信息从程序中剥离粗来,Spring现在提供的方法是通过@Value注解和<context:placeholder>来获取配置文件中的配置信息.这里给出一个简单的例子. 首 ...

  8. InvalidOperationException: No file provider has been configured to process the supplied file.

    现在有一个api, 提供图片的下载,如下代码,,调试出现 InvalidOperationException: No file provider has been configured to proc ...

  9. 微博api接口登陆,获取信息,分享微博

    import json from datetime import datetime import MySQLdb import requests from flask import Flask, re ...

  10. 【转】UItraEdit破解

      安装UltraEdit(一路下一步,无难点)成功后,打开软件弹出如下使用模式提示信息.   关掉UltraEdit软件,同时  断本机网络.重新打开UltraEdit软件:   点击[输入许可证密 ...