メインコンテンツへスキップ
  1. Posts/

メインコンテナの起動前に istio-proxy の起動を完了させる

Istio Kubernetes

2020年8月21日に Istio 1.7 がリリースされました。その RELEASE NOTEProduction operability improvements 項に次の節を見つけました。

You can delay the application start until after the sidecar is started . This increases the reliability for deployments where the application needs to access resources via its proxy immediately upon its boot.

サイドカーの起動が完了するまでアプリケーションの開始を遅らせることが出来るよ」とありますね、みんなが待ち望んでいたやつです。istoi-proxy (envoy) の起動が完了する前にアプリが起動しちゃって通信でコケるということにならないように envoy の status port にアクセスして起動を確認してからアプリのプロセスを起動するとか書かなくても良くなります。ステキ!

仕組みはリンク先で説明されています、kubelet は manifest の containers に書かれた順にシーケンシャルに起動させ、postStart があればそれを待つから、サイドカーをリストの先に定義して postStart でそのサイドカープロセスの起動が完了するのを待てば良いということのようです。

これを実現するための変更が istio/istio #24737 で、Istio 1.7.0 に含まれています。

IstioOperator 用の manifest で次の設定を入れるか、istioctl manifest generate --set values.global.proxy.holdApplicationUntilProxyStarts=true などとすれば istio-proxy サイドカーが containers の先頭に挿入され、postStart hook が挿入されます。

  values:
    global:
      proxy:
        holdApplicationUntilProxyStarts: true

istio-sidecar-injector という ConfigMap に次のような箇所があります。

      {{- if .Values.global.proxy.lifecycle }}
        lifecycle:
          {{ toYaml .Values.global.proxy.lifecycle | indent 4 }}
      {{- else if .Values.global.proxy.holdApplicationUntilProxyStarts}}
        lifecycle:
          postStart:
            exec:
              command:
              - pilot-agent
              - wait
      {{- end }}

あれ?このコードだと lifecyle を すでに指定してた postStart も自前で書く必要がありますね。Pod 停止時に先に istio-proxy が停止してしまうと通信できなくなってしまうため、istio-proxy の preStop には すでになんらかの処理を入れてます よね? ということはそこで postStart も設定する必要があります。

こういうことですね。

  values:
    global:
      proxy:
        holdApplicationUntilProxyStarts: true
        lifecycle:
          preStop:
            exec:
              command:
                - "/bin/sh"
                - "-c"
                - "while [ $(netstat -plnt | grep tcp | egrep -v 'envoy|pilot-agent' | wc -l) -ne 0 ]; do sleep 1; done"
          postStart:
            exec:
              command:
                - pilot-agent
                - wait

検証してね!