【发布时间】:2017-12-18 09:25:10
【问题描述】:
我正在尝试以零停机时间部署 kubernetes nginx。该过程的一部分是启动 rollingUpdate,以确保至少有一个 pod 始终在运行 nginx。这很好用。
当旧的 nginx pod 终止时,我遇到了错误。 根据termination 上的 kubernetes 文档,kubernetes 将:
- 从服务的端点列表中删除 pod,因此它是 终止开始时未收到任何新流量
- 如果定义了预停止钩子,则调用它,并等待它完成
- 向所有剩余进程发送 SIGTERM
- 在宽限期到期后向所有剩余进程发送 SIGKILL。
我知道命令nginx -s quit 应该通过在主节点终止之前等待所有工作人员完成请求来优雅地终止 nginx。它优雅地响应 SIGQUIT 命令,而 SIGTERM 导致暴力终止。其他论坛说,只需将以下 preStop 挂钩添加到您的部署中即可:
lifecycle:
preStop:
exec:
command: ["/usr/sbin/nginx", "-s", "quit"]
但是,通过测试此命令,我发现nginx -s quit 立即返回,而不是等待工作人员完成。它也不会返回主进程的 PID,这是我希望的 D:
发生的情况是,kubernetes 调用nginx -s quit,它将向工作子进程发送适当的 SIGQUIT,但不等待它们完成。相反,它会直接跳到第 3 步并 SIGTERM 那些进程,从而导致暴力终止,从而丢失连接。
问题:有没有人想出一种在滚动部署期间优雅地关闭其 nginx 控制器并实现零停机的好方法? 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"]
【问题讨论】:
标签: nginx kubernetes termination