我正在尝试以零停机时间部署 kubernetes nginx。该过程的一部分是启动 rollingUpdate,以确保至少有一个 pod 始终运行 nginx。这工作得很好。
当旧的 nginx pod 终止时,我遇到了错误。
根据 termination 上的 kubernetes 文档,kubernetes 将:
终止开始时未收到任何新流量
我理解命令
nginx -s quit
应该通过在主节点终止之前等待所有工作人员完成请求来优雅地终止 nginx。它优雅地响应 SIGQUIT 命令,而 SIGTERM 导致暴力终止。其他论坛说,将以下 preStop 钩子(Hook)添加到您的部署中一样简单:lifecycle:
preStop:
exec:
command: ["/usr/sbin/nginx", "-s", "quit"]
但是,通过测试此命令,我发现
nginx -s quit
立即返回,而不是等待 worker 完成。它也不会返回主进程的 PID,这正是我希望的 D:发生的情况是,kubernetes 调用
nginx -s quit
,这将向 worker child 发送适当的 SIGQUIT,但不等待他们完成。相反,它会直接跳到第 3 步并 SIGTERM 那些进程,从而导致暴力终止,从而丢失连接。问题 : 有没有人想出一个在滚动部署期间优雅地关闭 nginx Controller 并实现零停机的好方法?一个
sleep
解决方法还不够好,我正在寻找更强大的东西。以下是完整的部署 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", "-s", "quit"]
最佳答案
我讨厌回答我自己的问题,但经过一番思考之后,这就是我目前所拥有的。
我创建了一个半阻塞的 bash 脚本,称为 killer
:
#!/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
并开始等待,直到进程消失,您实际上已经使退出命令“阻塞”了。请注意,有一个
sleep 3
在任何事情发生之前。这是由于 Kubernetes 将 pod 标记为终止的竞争条件,但需要一点时间(< 1 秒)才能将这个 pod 从指向它的流量的服务中删除。我已将此脚本安装到我的 pod 中,并通过
preStop
调用它指示。它主要是有效的,但在测试过程中,仍然偶尔会出现一些问题,我得到一个 curl 错误,表明连接是“由对等方重置的”。但这是朝着正确方向迈出的一步。
关于nginx - Kubernetes Nginx : How to have zero-downtime deployments?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45083275/