kubernetes - Kubernetes上的RollingUpdate不会阻止网关超时

标签 kubernetes kubernetes-ingress traefik-ingress

我关注了http://rahmonov.me/posts/zero-downtime-deployment-with-kubernetes/博客,创建了两个带有index.html的docker镜像,返回了“应用程序的版本1”和“应用程序的版本2”。我要实现的是零停机时间释放。我正在使用

kubectl apply -f mydeployment.yaml

里面有image: mynamespace/nodowntime-test:v1

将v1版本部署到k8s,然后运行:
while True
    do
            printf "\n---------------------------------------------\n"
            curl "http://myhosthere"
            sleep 1s
    done

到目前为止,一切正常。短暂的时间后,curl返回“应用程序的版本1”。
然后,我使用image: mynamespace/nodowntime-test:v2应用相同的k8s部署文件。很好,它可以工作,但是在v1和v2之间只有一个(总是一个)网关超时响应。因此它并不是没有停机时间释放; )这比没有RollingUpdate更好,但是还不完美。

我正在使用RollingUpdate策略和readinessProbe:
---                              
apiVersion: apps/v1              
kind: Deployment                 
metadata:                        
  name: nodowntime-deployment    
spec:                            
  replicas: 1                    
  strategy:                      
    type: RollingUpdate          
    rollingUpdate:               
      maxUnavailable: 0          
      maxSurge: 1                
  selector:                      
    matchLabels:                 
      app: nodowntime-test       
  template:                      
    metadata:                    
      labels:                    
        app: nodowntime-test     
    spec:                        
      containers:                
      ...                        
        readinessProbe:          
          httpGet:               
            path: /              
            port: 80             
          initialDelaySeconds: 5 
          periodSeconds: 5       
          successThreshold: 5 

我可以做得更好吗?将所有这些与入口 Controller 同步是否存在问题?我知道我可以使用minReadySeconds进行调整,因此新旧Pod会重叠一段时间,但这是唯一的解决方案吗?

最佳答案

我已经重新创建了上述实验,并通过同时启动以下三个过程,将请求数更改为接近每秒30个请求:

While True
    do
        curl -s https://<NodeIP>:<NodePort>/ -m 0.1 --connect-timeout 0.1 | grep Version || echo "fail"
done

多次编辑部署并更改镜像版本后,在过渡过程中完全没有数据包丢失。
我什至在同一时间捕捉了两个图像的请求请求。
  Version 1 of my awesome app! Money is pouring in!
  Version 1 of my awesome app! Money is pouring in!
  Version 1 of my awesome app! Money is pouring in!
  Version 2 of my awesome app! More Money is pouring in!
  Version 1 of my awesome app! Money is pouring in!
  Version 1 of my awesome app! Money is pouring in!
  Version 2 of my awesome app! More Money is pouring in!
  Version 2 of my awesome app! More Money is pouring in!
  Version 2 of my awesome app! More Money is pouring in!

因此,如果您将请求直接发送给服务,它将按预期工作。

“Gateway Timeout”错误是Traefik代理的回复。它通过一组iptables规则打开与后端的TCP连接。
当您执行RollingUpdates时,iptables规则已更改,但是Traefic不知道,因此从Traefik的 Angular 来看,该连接仍被视为开放的。在第一次尝试通过不存在的iptables失败之后,Traefik报告“网关超时”并关闭tcp连接。在下一次尝试中,它将通过新的iptables规则打开与后端的新连接,一切都会恢复正常。

它可以由Traefik中的enabling retries修复。
# Enable retry sending request if network error
[retry]

# Number of attempts
#
# Optional
# Default: (number servers in backend) -1
#
# attempts = 3

更新:

最终,我们在不使用traefik的“重试”功能的情况下解决了该问题,该功能可能需要对所有服务进行幂等处理(无论如何都很好,但我们不能强制所有项目都这样做)。您需要的是配置了kubernetes RollingUpdate策略+ ReadinessProbe,并在您的应用中实现了正常关机。

关于kubernetes - Kubernetes上的RollingUpdate不会阻止网关超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51745924/

相关文章:

kubernetes - 如何将角色与服务帐户绑定(bind) - Kubernetes

kubernetes - 来自服务器的错误 (ServiceUnavailable) : the server is currently unable to handle the request (get nodes. metrics.k8s.io)

kubernetes - 运行 kubectl 命令时出错

kubernetes - 解析 templates/deployment.yaml 时出错 : json: line 1: invalid character '{' looking for beginning of object key string

kubernetes - 在 Digitalocean 单节点集群上通过 helm 安装时的 Traefik 仪表板/Web UI 404

kubernetes - 我如何获取traefik Controller 配置以及有关入口路径的一些问题

azure - 使用应用程序网关在 AKS 上自定义域和证书

nginx - 我是否需要 Kubernetes pod 中的 nginx 容器用于 Web 应用程序?

docker - Nginx入口 Controller 返回404 Kubernetes

kubernetes - kubernetes 中的入口和服务网格有什么区别?