2017-07-13 8 views
4

ダウンタイムゼロでkubernetes nginxを導入しようとしています。そのプロセスの一部は、少なくとも1つのポッドが常にnginxを実行していることを確認するrollingUpdateを開始することでした。これは完璧に機能します。Kubernetes Nginx:停止時間ゼロの展開方法

古いnginxポッドが終了しているときにエラーが発生しています。 termination上kubernetesのドキュメントによると、kubernetesはします:終了は停止前のフックを呼び出す

  • を開始したとき、それは 新たなトラフィックを受信して​​いないので、

    1. は、サービスのエンドポイントのリストからポッドを削除します定義されていれば完了するまで待ちます。
    2. 残っているすべてのプロセスにSIGTERMを送信します。
    3. 猶予期間が終了した後、残りのプロセスにSIGKILLを送信します。

    コマンドnginx -s quitは、マスターが終了する前にすべてのワーカーが要求を完了するのを待って、正常にnginxを終了させることを理解しています。 SIGQUITコマンドは正常に応答しますが、SIGTERMコマンドを実行すると暴力的に終了します。

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

    をしかし、私はnginx -s quitすぐに戻って、代わりの労働者が完了するのを待っていることを発見した、このコマンドをテストから:他のフォーラムには、それはあなたの展開に以下のPRESTOPフックを追加するのと同じくらい簡単であると言います。また、私が望んでいたマスタープロセスのPIDも返しません。

    kubernetesは、nginx -s quitを呼び出して、適切なSIGQUITをワーカーの子に送信しますが、それらを待たないようにします。コンプリート。代わりに、それはステップ3へと右にジャンプし、代わりにそれらのプロセスを呼び出すため、暴力的な終了が発生し、接続が失われます。

    質問:ローリング展開中に正常に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"] 
    
  • 答えて

    1

    が、少しのヌードリングした後、これは私がこれまで持っているものです。

    私は半ブロックしているbashスクリプトを作成したが、killerと呼ばれる:

    #!/bin/bash 
    
    sleep 3 
    PID=$(cat /run/nginx.pid) 
    nginx -s quit 
    
    while [ -d /proc/$PID ]; do 
        sleep 0.1 
    done 
    

    私はnginxのポッド内のマスター・プロセスのPIDを持つファイル/run/nginx.pidがあることがわかりました。 nginx -s quitに電話して、プロセスが消えるまで待機を開始すると、基本的にquitコマンド "blocking"が作成されています。

    何かが起こる前にsleep 3があることに注意してください。これは、Kubernetesがポッドを着信としてマークする競合状態に起因しますが、このポッドをサービスから削除してトラフィックを指すようにするには少し時間がかかります(< 1秒)。

    私はこのスクリプトをポッドにマウントし、preStopディレクティブで呼び出しました。ほとんどの場合動作しますが、テスト中に接続が「ピアによってリセットされました」というカールエラーが発生することがあります。しかしこれは正しい方向への一歩です。

    関連する問題