サイドカーインジェクションの問題
サイドカーインジェクションの結果が期待どおりではありませんでした
これには、予期しない場合に注入されたサイドカーと、予期したときに注入されたサイドカーがない場合が含まれます。
Podが
kube-system
またはkube-public
名前空間にないことを確認してください。これらの名前空間のPodでは、自動サイドカーインジェクションは無視されます。PodのPodスペックに
hostNetwork: true
がないことを確認してください。ホストネットワーク上にあるPodでは、自動サイドカーインジェクションは無視されます。サイドカーモデルは、Envoyがトラフィックをインターセプトするために必要なiptablesの変更がポッド内にあることを前提としています。ホストネットワーク上のポッドの場合、この前提が violated され、ホストレベルでルーティングエラーが発生する可能性があります。
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
デフォルトポリシーを確認する
istio-sidecar-injector configmap
でデフォルトのインジェクションポリシーを確認します。$ kubectl -n istio-system get configmap istio-sidecar-injector -o jsonpath='{.data.config}' | grep policy: policy: enabled
許可されるポリシー値は
disabled
とenabled
です。デフォルトポリシーは、WebhookのnamespaceSelector
がターゲットの名前空間と一致する場合にのみ適用されます。認識されないポリシーは、インジェクションを完全に無効にします。ポッドごとのオーバーライドアノテーションを確認する
デフォルトポリシーは、*ポッドテンプレートスペックのメタデータ*の
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の呼び出しに失敗した場合は、通常、イベントログに記録されます。
x509証明書関連のエラー
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
が空であることが原因です。
mutatingwebhookconfiguration
のcaBundle
が、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
サイドカーコンテナの準備ができていない場合、これによりアプリケーションコンテナがハングまたは再起動する可能性があります。
これを回避するには、holdApplicationUntilProxyStarts
をtrue
に設定します。これにより、サイドカーインジェクターはポッドのコンテナリストの先頭にサイドカーを挿入し、プロキシの準備ができるまで他のすべてのコンテナの起動をブロックするように構成します。
これは、グローバル設定オプションとして追加できます。
values.global.proxy.holdApplicationUntilProxyStarts: true
または、ポッドアノテーションとして追加できます。
proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'