在Kubernetes集群中,对于通过TCP/UDP访问的服务来说,七层的Ingress不能很好地实现灰度发布的需求。本文介绍如何使用SLB来进行四层的金丝雀发布。

前提条件

步骤一:部署旧版本服务

  1. 登录容器服务管理控制台
  2. 在控制台左侧导航栏中,单击集群
  3. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
  4. 在集群管理页左侧导航栏中,选择工作负载 > 无状态
  5. 无状态页面单击右上角的使用YAML创建资源
  6. 选择示例模板,然后单击创建
    示例模板

    本例是一个Nginx的编排,通过SLB对外暴露的服务。

     apiVersion: apps/v1
     kind: Deployment
     metadata:
       labels:
         run: old-nginx
       name: old-nginx
     spec:
       replicas: 1
       selector:
         matchLabels:
           run: old-nginx
       template:
         metadata:
           labels:
             run: old-nginx
             app: nginx
         spec:
           containers:
           - image: registry.cn-hangzhou.aliyuncs.com/xianlu/old-nginx
             imagePullPolicy: Always
             name: old-nginx
             ports:
             - containerPort: 80
               protocol: TCP
           restartPolicy: Always
     ---
     apiVersion: v1
     kind: Service
     metadata:
       labels:
         run: nginx
       name: nginx
     spec:
       ports:
       - port: 80
         protocol: TCP
         targetPort: 80
       selector:
         app: nginx
       sessionAffinity: None
       type: LoadBalancer                       #通过阿里云SLB对外暴露服务。
    无状态页面可以看到创建的应用。
  7. 在集群管理页面左侧导航栏选择网络 > 服务,在服务页面,您可单击服务右侧的外部端点,进入Nginx默认欢迎页面,本示例中的Nginx欢迎页面会显示old,表示当前访问的服务对应后端old-nginx容器。
    old

    为了方便展示多次发布的情况,建议登录Master节点,后面都将通过curl命令查看部署的效果。

    bash  
    for x in {1..10} ; do curl EXTERNAL-IP; done                    #EXTERNAL-IP为服务的外部端点。
    old
    old
    old
    old
    old
    old
    old
    old
    old
    old

步骤二:上线新版本Deployment

  1. 在控制台左侧导航栏中,单击集群
  2. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
  3. 在集群管理页左侧导航栏中,选择工作负载 > 无状态
  4. 无状态页面单击右上角的使用YAML创建资源
  5. 选择示例模板,然后单击创建

    本示例是一个Nginx的新版本的Deployment,其中的Labels,也是含有app:nginx标签。这个标签就是为了使用与旧版本Deployment相同的Nginx服务,这样就可以将对应的流量导入进来。

    本示例的编排模板如下。

     apiVersion: apps/v1
     kind: Deployment
     metadata:
       labels:
         run: new-nginx
       name: new-nginx
     spec:
       replicas: 1
       selector:
         matchLabels:
           run: new-nginx
       template:
         metadata:
           labels:
             run: new-nginx
             app: nginx
         spec:
           containers:
           - image: registry.cn-hangzhou.aliyuncs.com/xianlu/new-nginx
             imagePullPolicy: Always
             name: new-nginx
             ports:
             - containerPort: 80
               protocol: TCP
           restartPolicy: Always
  6. 无状态页面,可以看到名为new-nginx的Deployment。
  7. 登录Master节点,执行curl命名,查看服务访问的情况。
    bash  
    for x in {1..10} ; do curl EXTERNAL-IP; done                    #EXTERNAL-IP为服务的外部端点。
    new
    new
    new
    old
    new
    old
    new
    new
    old
    old

    可看到五次访问到旧的服务,五次访问到新的服务。主要原因是Service对于流量请求是平均的负载均衡策略,而且新老Deployment均为一个Pod,因此它们的流量百分比为1:1。

步骤三:调整流量权重

基于SLB的金丝雀发布需要通过调整后端的Pod数量来调整对应的权重。例如我们这里希望新的服务权重更大一些,假如将新的Pod数量调整到4个。

说明 新旧版本应用同时存在时,某个样本的Curl命令返回的结果并非严格按照设置的权重,本例中执行10次Curl命令,您可通过观察更大的样本获取接近的效果。
  1. 在控制台左侧导航栏中,单击集群
  2. 集群列表页面中,单击目标集群名称或者目标集群右侧操作列下的详情
  3. 在集群管理页左侧导航栏中,选择工作负载 > 无状态
  4. 选择命名空间,选择所需的Deployment,单击目标应用右侧操作列的伸缩
  5. 在弹出的对话框中,设置所需容器组的数量,将其调整为4。
    说明 Kubernetes的Deployment资源默认的更新方式就是rollingUpdate,所以在更新过程中,会保证最小可服务的容器个数,该个数也可以在模板里面调整。
  6. 待部署完成后,登录Master节点,执行Curl命令,查看效果。
    bash  
     for x in {1..10} ; do curl EXTERNAL-IP; done                    #EXTERNAL-IP为服务的外部端点。
     new
     new
     new
     new
     new
     old
     new
     new
     new
     old

    可以看到,10个请求里面,有8个请求到新的服务,2个到老的服务。

    您可通过动态地调整Pod的数量来调整新老服务的权重,实现金丝雀发布。