灰度发布在实际生产部署中是经常被使用的方式,常规的方法是手动从前端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. 在配置和销售凭证 GET_CONFIG_MODE 间通信时内部出错

    “在配置和销售凭证 GET_CONFIG_MODE 间通信时内部出错” 订单打开出现这种错误提示,多半是配置对象号问题. SAP NOTE 2019-09-27 901893901893 - Repo ...

  2. java之maven之初识maven

    1.maven是一个项目管理工具. 包括项目创建.资源管理.项目运行.项目发布等功能. 2.为什么使用 maven? a. jar 依赖管理(升级.降级)等 b. 项目之间依赖管理 c. 资源文件管理 ...

  3. python自动备份阿里云数据库binlog

    #coding:utf8from aliyunsdkcore import clientfrom aliyunsdkrds.request.v20140815 import DescribeBacku ...

  4. JavaScript 之 页面加载事件

    一.onload 加载事件 onload 是 window 对象的一个事件,也可以省略 window 直接使用. 常用方式: <head><script> windown.on ...

  5. JS工程师的成长路径

    JS 说起来必须是一个神器,这个当年10天内被开发出来的神器,以一种谁也想象不到的速度快速发展,它击败了Java Applet,逼死Flash,当Android和IOS看似一统全球的时候,JS慢条斯理 ...

  6. unittest管理用例生成测试报告

    #登录方法的封装 from appium import webdriver from time import sleep from python_selenium.Slide import swipe ...

  7. 机器学习笔记4:SVM支持向量积的推导过程

    内容来自:https://github.com/GreedyAIAcademy/Machine-Learning 最初 支持向量机的目的:找到一条好的分割线 什么杨的分割线最好? 有最大间隔的分割线最 ...

  8. 图论篇3——最短路径 Dijkstra算法、Floyd算法

    最短路径 问题背景:地图上有很多个城市,已知各城市之间距离(或者是所需时间,后面都用距离了),一般问题无外乎就是以下几个: 从某城市到其余所有城市的最短距离[单源最短路径] 所有城市之间相互的最短距离 ...

  9. Jmeter跨线程组传递cookie,以禅道系统为例;BeanShell的存取数据的使用

    先看下脚本结构: 思路:将登陆请求放在setUp Thread Group中:把登陆后的cookie通过正则提取出来,然后存为全局变量,传递到下一个线程组中: 第一步:添加setUp Thread G ...

  10. GitHub小知识与教程

    如果你是一枚Coder,但是你不知道Github,那么我觉的你就不是一个菜鸟级别的Coder,因为你压根不是真正Coder,你只是一个Code搬运工. 但是你如果已经在读这篇文章了,我觉的你已经知道G ...