Kubernetes是否支持蓝绿色部署?

时间:2019-11-19 10:45:47

标签: sockets networking kubernetes deployment

我想问一下在kubernetes中停止pod的机制。

在问问题之前,我读过https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods

大概我们有一个具有正常关机支持的应用程序 (例如,我们在Go https://play.golang.org/p/5tmkPPMiSSt上使用简单的http服务器)。

服务器有两个端点:

  • /快速,始终发送200个http状态代码。
  • /慢,请等待10秒钟并发送200个http状态代码。

具有该配置的部署/服务资源:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test
spec:
  replicas: 1
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app/name: test
  template:
    metadata:
      labels:
        app/name: test
    spec:
      terminationGracePeriodSeconds: 120
      containers:
        - name: service
          image: host.org/images/grace:v0.1
          livenessProbe:
            httpGet:
              path: /health
              port: 10002
            failureThreshold: 1
            initialDelaySeconds: 1
          readinessProbe:
            httpGet:
              path: /health
              port: 10002
            failureThreshold: 1
            initialDelaySeconds: 1
---
apiVersion: v1
kind: Service
metadata:
  name: test
spec:
  type: NodePort
  ports:
    - name: http
      port: 10002
      targetPort: 10002
  selector:
    app/name: test

为确保吊舱正常删除,我进行了两个测试选项。


第一个选项(端点缓慢)流:

  • 创建副本值为1的部署。
  • 等待豆荚就绪。
  • 在/ slow端点(卷曲http://ip-of-some-node:nodePort/slow)上发送请求,并删除pod(同时,不同步1秒)。

预期

在http服务器完成我的请求之前,播客一定不能结束。

知道

是的,http服务器会在10秒内处理完毕,并为我返回响应。 (如果将-grace-period = 1 选项传递给kubectl,则curl将写入-curl:(52)来自服务器的空回复)

一切正常。


第二个选项(快速端点)流:

  • 创建副本值为10的部署。
  • 等待豆荚就绪。
  • 从“连接:关闭”标题开始 wrk
  • 随机删除一个或两个Pod(kubectl delete pod / xxx)。

预期

无套接字错误。

知道

$ wrk -d 2m --header "Connection: Close" http://ip-of-some-node:nodePort/fast
Running 2m test @ http://ip-of-some-node:nodePort/fast
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   122.35ms  177.30ms   1.98s    91.33%
    Req/Sec    66.98     33.93   160.00     65.83%
  15890 requests in 2.00m, 1.83MB read
  Socket errors: connect 0, read 15, write 0, timeout 0
Requests/sec:    132.34
Transfer/sec:     15.64KB

读取时出现15个套接字错误,即某些Pod在处理所有请求之前可能已与服务断开连接。

应用新的部署版本,按比例缩小和撤消撤消操作时,会出现问题。

问题

  1. 该行为的原因是什么?
  2. 如何解决?

Kubernetes版本:v1.16.2

编辑1。

错误数量每次都会改变,但是在两分钟内删除2-5个容器时,错误数量仍在10-20之间。

P.S。如果我们不删除窗格,则不会出现错误。

1 个答案:

答案 0 :(得分:0)

  

Kubernetes是否支持蓝绿色部署?

是的,确实如此。您可以在Zero-downtime Deployment in Kubernetes with Jenkins上了解它,

  
    

蓝色/绿色部署是用于发布软件代码的变更管理策略。蓝色/绿色部署(也可以称为A / B部署)需要两个完全相同的硬件环境,并且配置方式完全相同。在一个环境处于活动状态并为最终用户提供服务时,另一环境保持空闲状态。

  
     

容器技术提供了运行所需服务的独立环境,这使得创建蓝/绿部署所需的相同环境变得异常容易。松散耦合的服务-ReplicaSets,以及Kubernetes中基于标签/选择器的服务路由,可以轻松在不同的后端环境之间进行切换。

我还建议您阅读Kubernetes Infrastructure Blue/Green deployments

Here是一个存储库,其中包含codefresh.io中有关蓝绿色部署的示例。

  

此存储库包含一个bash脚本,可让您在Kubernetes集群上执行蓝色/绿色部署。另请参见相应的blog post

     

先决条件

     

按照惯例,脚本应该如此

     
      
  1. 您的部署名称为$APP_NAME-$VERSION
  2.   
  3. 您的部署中应该有一个标签来显示版本
  4.   
  5. 您的服务应使用version选择器指向部署,并指向部署中的相应标签
  6.   
     

请注意,脚本创建的新颜色部署将遵循相同的约定。这样,您运行的每个后续管道将以相同的方式工作。

     

您可以在示例应用程序中查看标签示例:

     

您可能也对Canary deployment感兴趣:

  

另一种部署策略是使用Canaries(又称增量部署)。借助canaries,该应用程序的新版本将逐渐部署到Kubernetes集群,同时获得非常少量的实时流量(即一部分实时用户正在连接到新版本,而其余用户仍在使用旧版本)。   ...

     

到新版本的实时通信的一小部分充当对新代码中可能存在的潜在问题的早期警告。随着我们的信心增强,将创建更多的金丝雀,并且现在有更多的用户连接到更新的版本。最后,所有实时流量都流向了金丝雀,因此金丝雀版本成为了新的“生产版本”。

编辑

  

问题

     
      
  1. 该行为的原因是什么?
  2.   

在应用新部署时,将删除旧的Pod,并计划新的Pod。 这是通过控制计划完成的

  

例如,当您使用Kubernetes API创建部署时,将为系统提供新的所需状态。 Kubernetes控制平面记录了对象的创建,并通过启动所需的应用程序并将它们调度到群集节点来执行您的指令,从而使群集的实际状态与所需状态相匹配。

您仅设置了一个readinessProbe,它告诉您的service是否应该将流量发送到广告连播。这不是一个好的解决方案,就像您在示例中看到的那样,如果您有10个吊舱并卸下一个或两个吊舱,则会出现间隙,并且您收到套接字错误。

  
      
  1. 如何解决?
  2.   

您必须了解它没有损坏,因此不需要修复。

可以通过在应用程序中实施检查以确保其将请求发送到工作地址或利用其他功能(如ingress之类的负载平衡)来缓解这种情况。

此外,在更新部署时,您可以在删除Pod之前进行检查,以检查它是否确实有进/出流量,并将更新仅滚动到未使用的Pod。