Kubernetes Nginx:如何实现零停机部署?

前端之家收集整理的这篇文章主要介绍了Kubernetes Nginx:如何实现零停机部署?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我试图让kubernetes Nginx部署零停机时间.该过程的一部分是启动rollingUpdate,确保至少有一个pod始终在运行Nginx.这非常有效.

当旧的Nginx pod终止时,我遇到了错误.
根据termination的kubernetes文档,kubernetes将:

>从服务的端点列表中删除pod,所以它是
终止开始时没有收到任何新的流量
>如果已定义,则调用预停止挂钩,并等待它完成
>将SIGTERM发送到所有剩余进程
>在宽限期到期后,将SIGKILL发送给任何剩余的进程.

我知道命令Nginx -s quit应该通过在主服务器终止之前等待所有worker完成请求来优雅地终止Nginx.它优雅地响应SIGQUIT命令,而SIGTERM导致暴力终止.其他论坛说它就像在部署中添加以下preStop挂钩一样简单:

lifecycle:
  preStop:
    exec:
      command: ["/usr/sbin/Nginx","-s","quit"]

但是,通过测试此命令,我发现Nginx -s quit立即返回,而不是等待worker完成.它也不会返回主进程的PID,这是我希望D:

会发生什么,kubernetes调用Nginx -s quit,它会向工作人员发送一个正确的SIGQUIT,但不要等待它们完成.相反,它会直接跳到第3步,而SIGTERM会转向那些进程,导致暴力终止,从而导致连接丢失.

问题:有没有人想出一个在滚动部署期间优雅地关闭他们的Nginx控制器并且没有停机时间的好方法?睡眠解决方法不够好,我正在寻找更强大的东西.

以下是完整部署yaml:

apiVersion: extensions/v1beta1
kind: Deployment
Metadata:
name: Nginx-ingress-controller
spec:
  replicas: 1
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
 template:
    Metadata:
      labels:
        app: Nginx-ingress-lb
    spec:
      terminationGracePeriodSeconds: 60
      serviceAccount: Nginx
      containers:
        - name: Nginx-ingress-controller
          image: gcr.io/google_containers/Nginx-ingress-controller:0.9.0-beta.8
          imagePullPolicy: Always
          readinessProbe:
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
          livenessProbe:
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            timeoutSeconds: 5
          args:
            - /Nginx-ingress-controller
            - --default-backend-service=$(POD_NAMESPACE)/default-backend
            - --v=2
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: Metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: Metadata.namespace
          ports:
            - containerPort: 80
          lifecycle:
            preStop:
              exec:
                command: ["/usr/sbin/Nginx","quit"]
最佳答案
我讨厌回答我自己的问题,但是在涂了一点之后,这就是我到目前为止所拥有的.

我创建了一个半阻塞的bash脚本,称为杀手:

#!/bin/bash

sleep 3
PID=$(cat /run/Nginx.pid)
Nginx -s quit

while [ -d /proc/$PID ]; do
  sleep 0.1
done

我发现在Nginx pod中有一个文件/run/Nginx.pid,它有主进程的PID.如果你调用Nginx -s quit并启动等待直到进程消失,你基本上已经使quit命令“阻塞”了.

请注意,在发生任何事情之前有一个睡眠3.这是由于竞争条件导致Kubernetes将一个吊舱标记为终止,但需要一点时间(<1s)将该吊舱从指向其的流量的服务中移除. 我已将此脚本安装到我的pod中,并通过preStop指令调用它.它主要工作,但在测试期间仍然偶尔会出现一些问题,我发现卷曲错误表明连接是“由同行重置”.但这是朝着正确方向迈出的一步.

猜你在找的Nginx相关文章