Kubernetes Nginx: How to have a deployment with zero downtime?

I am trying to use kubernetes nginx deployment with zero downtime. Part of this process was to initiate rollUpdate, which ensures that at least one module runs nginx at all times. This works great.

I encountered errors when the old nginx module ends. According to kubernetes docs on termination , kubernets will:

  • remove the module from the list of endpoints for the service so that it is not receiving any new traffic when terminating
  • call a preliminary capture, if defined, and wait for it to complete.
  • send SIGTERM to all remaining processes
  • send SIGKILL to any remaining processes after the expiration of the grace period.

I understand that the team nginx -s quitmust gracefully terminate nginx, waiting for all employees to fill out requests before the wizard completes. He gracefully responds to the SIGQUIT command, and SIGTERM leads to violent termination. Other forums say this is as simple as adding the following preStop capture to your deployment:

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

However, checking this command, I found that it was nginx -s quitimmediately returning, and was not waiting for the completion of work. It also does not return the PID of the host process, as I hoped for D:

What happens, the kubernetes calls nginx -s quit, which sends the proper SIGQUIT to the workers, but does not wait for them to complete. Instead, it will go directly to step 3 and SIGTERM for these processes, which will lead to a violent termination and, consequently, to lost connections.

. - , nginx ? A 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"]
+4
1

, , .

bash script, , 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 , , ​​ quit "".

, sleep 3, - . , , , (< 1s), , .

script preStop. , , , "reset by peer". .

+1

Source: https://habr.com/ru/post/1681371/


All Articles