サイドカーインジェクションの問題

サイドカーインジェクションの結果が期待どおりではありませんでした

これには、予期しない場合に注入されたサイドカーと、予期したときに注入されたサイドカーがない場合が含まれます。

  1. Podがkube-systemまたはkube-public名前空間にないことを確認してください。これらの名前空間のPodでは、自動サイドカーインジェクションは無視されます。

  2. PodのPodスペックにhostNetwork: trueがないことを確認してください。ホストネットワーク上にあるPodでは、自動サイドカーインジェクションは無視されます。

    サイドカーモデルは、Envoyがトラフィックをインターセプトするために必要なiptablesの変更がポッド内にあることを前提としています。ホストネットワーク上のポッドの場合、この前提が violated され、ホストレベルでルーティングエラーが発生する可能性があります。

  3. WebhookのnamespaceSelectorを確認して、Webhookがターゲットの名前空間に対してオプトインまたはオプトアウトのどちらにスコープされているかを判断します。

    オプトインのnamespaceSelectorは次のようになります。

    $ kubectl get mutatingwebhookconfiguration istio-sidecar-injector -o yaml | grep "namespaceSelector:" -A5
      namespaceSelector:
        matchLabels:
          istio-injection: enabled
      rules:
      - apiGroups:
        - ""
    

    インジェクションWebhookは、istio-injection=enabledラベルが付いた名前空間で作成されたポッドに対して呼び出されます。

    $ kubectl get namespace -L istio-injection
    NAME           STATUS    AGE       ISTIO-INJECTION
    default        Active    18d       enabled
    istio-system   Active    3d
    kube-public    Active    18d
    kube-system    Active    18d
    

    オプトアウトのnamespaceSelectorは次のようになります。

    $ kubectl get mutatingwebhookconfiguration istio-sidecar-injector -o yaml | grep "namespaceSelector:" -A5
      namespaceSelector:
        matchExpressions:
        - key: istio-injection
          operator: NotIn
          values:
          - disabled
      rules:
      - apiGroups:
        - ""
    

    インジェクションWebhookは、istio-injection=disabledラベルのない名前空間で作成されたポッドに対して呼び出されます。

    $ kubectl get namespace -L istio-injection
    NAME           STATUS    AGE       ISTIO-INJECTION
    default        Active    18d
    istio-system   Active    3d        disabled
    kube-public    Active    18d       disabled
    kube-system    Active    18d       disabled
    

    アプリケーションポッドの名前空間に適切なラベルが付けられていることを確認し、必要に応じて(再)ラベル付けします。例:

    $ kubectl label namespace istio-system istio-injection=disabled --overwrite
    

    (インジェクションWebhookが新しいポッドに対して呼び出されるべきすべての名前空間に対して繰り返します)

    $ kubectl label namespace default istio-injection=enabled --overwrite
    
  4. デフォルトポリシーを確認する

    istio-sidecar-injector configmapでデフォルトのインジェクションポリシーを確認します。

    $ kubectl -n istio-system get configmap istio-sidecar-injector -o jsonpath='{.data.config}' | grep policy:
    policy: enabled
    

    許可されるポリシー値はdisabledenabledです。デフォルトポリシーは、WebhookのnamespaceSelectorがターゲットの名前空間と一致する場合にのみ適用されます。認識されないポリシーは、インジェクションを完全に無効にします。

  5. ポッドごとのオーバーライドアノテーションを確認する

    デフォルトポリシーは、*ポッドテンプレートスペックのメタデータ*のsidecar.istio.io/injectラベルでオーバーライドできます。デプロイメントのメタデータは無視されます。ラベル値trueはサイドカーの挿入を強制し、値falseはサイドカーの挿入を強制的に*行いません*。

    次のラベルは、デフォルトのpolicyが何であってもオーバーライドして、サイドカーの挿入を強制します。

    $ kubectl get deployment curl -o yaml | grep "sidecar.istio.io/inject:" -B4
    template:
      metadata:
        labels:
          app: curl
          sidecar.istio.io/inject: "true"
    

Podをまったく作成できません

失敗したポッドのデプロイメントでkubectl describe -n namespace deployment nameを実行します。インジェクションWebhookの呼び出しに失敗した場合は、通常、イベントログに記録されます。

Warning  FailedCreate  3m (x17 over 8m)  replicaset-controller  Error creating: Internal error occurred: \
    failed calling admission webhook "sidecar-injector.istio.io": Post https://istiod.istio-system.svc:443/inject: \
    x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying \
    to verify candidate authority certificate "Kubernetes.cluster.local")

x509: certificate signed by unknown authorityエラーは、通常、Webhook設定のcaBundleが空であることが原因です。

mutatingwebhookconfigurationcaBundleが、istiodポッドにマウントされているルート証明書と一致することを確認します。

$ kubectl get mutatingwebhookconfiguration istio-sidecar-injector -o yaml -o jsonpath='{.webhooks[0].clientConfig.caBundle}' | md5sum
4b95d2ba22ce8971c7c92084da31faf0  -
$ kubectl -n istio-system get configmap istio-ca-root-cert -o jsonpath='{.data.root-cert\.pem}' | base64 -w 0 | md5sum
4b95d2ba22ce8971c7c92084da31faf0  -

CA証明書は一致するはずです。一致しない場合は、istiodポッドを再起動します。

$ kubectl -n istio-system patch deployment istiod \
    -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"`date +'%s'`\"}}}}}"
deployment.extensions "istiod" patched

デプロイメントステータスのエラー

ポッドに対して自動サイドカーインジェクションが有効になっている場合、何らかの理由でインジェクションが失敗すると、ポッドの作成も失敗します。このような場合は、ポッドのデプロイメントステータスを確認してエラーを特定できます。エラーは、デプロイメントに関連付けられた名前空間のイベントにも表示されます。

たとえば、ポッドをデプロイしようとしたときにistiodコントロールプレーンポッドが実行されていなかった場合、イベントには次のエラーが表示されます。

$ kubectl get events -n curl
...
23m Normal   SuccessfulCreate replicaset/curl-9454cc476   Created pod: curl-9454cc476-khp45
22m Warning  FailedCreate     replicaset/curl-9454cc476   Error creating: Internal error occurred: failed calling webhook "namespace.sidecar-injector.istio.io": failed to call webhook: Post "https://istiod.istio-system.svc:443/inject?timeout=10s": dial tcp 10.96.44.51:443: connect: connection refused
$ kubectl -n istio-system get pod -lapp=istiod
NAME                            READY     STATUS    RESTARTS   AGE
istiod-7d46d8d9db-jz2mh         1/1       Running     0         2d
$ kubectl -n istio-system get endpoints istiod
NAME           ENDPOINTS                                                  AGE
istiod   10.244.2.8:15012,10.244.2.8:15010,10.244.2.8:15017 + 1 more...   3h18m

istiodポッドまたはエンドポイントの準備ができていない場合は、ポッドのログとステータスを確認して、Webhookポッドが起動してトラフィックを処理できない理由を示す兆候がないか確認します。

$ for pod in $(kubectl -n istio-system get pod -lapp=istiod -o jsonpath='{.items[*].metadata.name}'); do \
    kubectl -n istio-system logs ${pod} \
done


$ for pod in $(kubectl -n istio-system get pod -l app=istiod -o name); do \
kubectl -n istio-system describe ${pod}; \
done
$

Kubernetes APIサーバーにプロキシ設定がある場合、自動サイドカーインジェクションは失敗します

Kubernetes APIサーバーに次のようなプロキシ設定が含まれている場合

env:
  - name: http_proxy
    value: http://proxy-wsa.esl.foo.com:80
  - name: https_proxy
    value: http://proxy-wsa.esl.foo.com:80
  - name: no_proxy
    value: 127.0.0.1,localhost,dockerhub.foo.com,devhub-docker.foo.com,10.84.100.125,10.84.100.126,10.84.100.127

これらの設定では、サイドカーインジェクションは失敗します。関連する唯一の failure ログは、kube-apiserverログにあります。

W0227 21:51:03.156818       1 admission.go:257] Failed calling webhook, failing open sidecar-injector.istio.io: failed calling admission webhook "sidecar-injector.istio.io": Post https://istio-sidecar-injector.istio-system.svc:443/inject: Service Unavailable

*_proxy変数に従って、ポッドとサービスの両方のCIDRがプロキシされていないことを確認してください。 kube-apiserverファイルとログを確認して、設定と、リクエストがプロキシされているかどうかを確認します。

1つの回避策は、kube-apiserverマニフェストからプロキシ設定を削除することです。もう1つの回避策は、no_proxy値にistio-sidecar-injector.istio-system.svcまたは.svcを含めることです。各回避策の後で、kube-apiserverが再起動されていることを確認してください。

これに関してKubernetesにissueが提出され、その後クローズされました。 https://github.com/kubernetes/kubernetes/pull/58698#discussion_r163879443

PodでのTcpdumpの使用に関する制限事項

Tcpdumpはサイドカーポッドでは機能しません。コンテナはrootとして実行されていないためです。ただし、ネットワーク名前空間が共有されているため、同じポッド内の他のコンテナはすべてのパケットを認識します。 iptablesもポッド全体の構成を認識します。

Envoyとアプリ間の通信は127.0.0.1で行われ、暗号化されていません。

クラスタが自動的にスケールダウンされません

サイドカーコンテナがローカルストレージボリュームをマウントしているため、ノードオートスケーラーは、挿入されたポッドを持つノードを削除できません。これは既知の問題です。回避策は、挿入されたポッドにポッドアノテーション"cluster-autoscaler.kubernetes.io/safe-to-evict": "true"を追加することです。

istio-proxyの準備ができていない場合、Podまたはコンテナはネットワークの問題で起動します

多くのアプリケーションは、起動中にネットワーク接続を必要とするコマンドまたはチェックを実行します。 istio-proxyサイドカーコンテナの準備ができていない場合、これによりアプリケーションコンテナがハングまたは再起動する可能性があります。

これを回避するには、holdApplicationUntilProxyStartstrueに設定します。これにより、サイドカーインジェクターはポッドのコンテナリストの先頭にサイドカーを挿入し、プロキシの準備ができるまで他のすべてのコンテナの起動をブロックするように構成します。

これは、グローバル設定オプションとして追加できます。

values.global.proxy.holdApplicationUntilProxyStarts: true

または、ポッドアノテーションとして追加できます。

proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
この情報は役に立ちましたか?
改善のための提案はありますか?

フィードバックありがとうございます!