Knative Eventingのデバッグ¶
これは、動作していないKnative Eventingの設定をデバッグする方法に関する発展途上のドキュメントです。
対象読者¶
このドキュメントは、Knative Eventingのオブジェクトモデルに精通している人を対象としています。専門家である必要はありませんが、大まかに物事がどのように連携しているかを理解する必要があります。
前提条件¶
- Knative EventingとEventing-contribリソース をセットアップします。
例¶
このガイドでは、イベントを関数に送信するイベントソースからなる例を使用します。
example.yamlでYAML全体を参照してください。このガイドのすべてのコマンドが機能するには、example.yamlを適用する必要があります。
kubectl apply --filename example.yaml
イベントのトリガー¶
Knativeイベントは、knative-debug
名前空間でKubernetes Event
が発生するたびに発生します。これは、次のコマンドを使用して発生させることができます。
kubectl --namespace knative-debug run to-be-deleted --image=image-that-doesnt-exist --restart=Never
# 5 seconds is arbitrary. We want K8s to notice that the Pod needs to be scheduled and generate at least one event.
sleep 5
kubectl --namespace knative-debug delete pod to-be-deleted
次に、Kubernetes Event
(これらはKnativeイベントではありません!)を確認できます。
kubectl --namespace knative-debug get events
これにより、次のような出力が生成されるはずです。
LAST SEEN FIRST SEEN COUNT NAME KIND SUBOBJECT TYPE REASON SOURCE MESSAGE
20s 20s 1 to-be-deleted.157aadb9f376fc4e Pod Normal Scheduled default-scheduler Successfully assigned knative-debug/to-be-deleted to gke-kn24-default-pool-c12ac83b-pjf2
イベントはどこにありますか?¶
example.yamlを適用し、fn
のログを検査しています。
kubectl --namespace knative-debug logs -l app=fn -c user-container
しかし、到着するイベントが見つかりません。何が問題ですか?
作成されたリソースの確認¶
最初に確認する必要があるのは、作成されたすべてのリソースであり、そのステータスにready
trueが含まれていますか?
最も基本的な部分から原因を特定しようとします。
fn
-Deployment
には、Knative内の依存関係がありません。svc
-Service
には、Knative内の依存関係がありません。chan
-Channel
は、そのバッキングchannel implementation
に依存し、ある程度sub
にも依存します。src
-Source
はchan
に依存します。sub
-Subscription
はchan
とsvc
の両方に依存します。
fn
¶
kubectl --namespace knative-debug get deployment fn -o jsonpath='{.status.availableReplicas}'
1
を確認したいです。そうでない場合は、Deployment
をデバッグする必要があります。status
に明らかに間違っていることはありますか?
kubectl --namespace knative-debug get deployment fn --output yaml
何が間違っているのかが明らかでない場合は、このドキュメントの範囲外であるDeployment
をデバッグする必要があります。
Pod
がReady
であることを確認します。
kubectl --namespace knative-debug get pod -l app=fn -o jsonpath='{.items[*].status.conditions[?(@.type == "Ready")].status}'
これはTrue
を返す必要があります。そうでない場合は、Kubernetesアプリケーションデバッグガイドを使用してDeployment
のデバッグを試みてください。
svc
¶
kubectl --namespace knative-debug get service svc
存在し、正しい名前を持っていることを確認するだけです。存在しない場合は、おそらくexample.yamlを再適用する必要があります。
期待されるpodを指していることを確認します。
svcLabels=$(kubectl --namespace knative-debug get service svc -o go-template='{{range $k, $v := .spec.selector}}{{ $k }}={{ $v }},{{ end }}' | sed 's/.$//' )
kubectl --namespace knative-debug get pods -l $svcLabels
これは、検査するとfn
によって生成されたものになる単一のPodを返す必要があります。
chan
¶
chan
はin-memory-channel
を使用します。これは非常に基本的なチャネルであり、chan
のstatus
に表示される失敗モードはほとんどありません。
kubectl --namespace knative-debug get channel.messaging.knative.dev chan -o jsonpath='{.status.conditions[?(@.type == "Ready")].status}'
これはTrue
を返す必要があります。そうでない場合は、完全なリソースを取得します。
kubectl --namespace knative-debug get channel.messaging.knative.dev chan --output yaml
status
が完全に欠落している場合、in-memory-channel
コントローラに問題があることを意味します。チャネルコントローラを参照してください。
次に、chan
がアドレス指定可能であることを確認します。
kubectl --namespace knative-debug get channel.messaging.knative.dev chan -o jsonpath='{.status.address.hostname}'
これは、おそらく'.cluster.local'で終わるURIを返す必要があります。そうでない場合は、調整中に何かが間違っていたことを意味します。チャネルコントローラを参照してください。
chan
が作成する2つのリソースが存在し、Ready
であることを確認します。
Service
¶
chan
はK8s Service
を作成します。
kubectl --namespace knative-debug get service -l messaging.knative.dev/role=in-memory-channel
Istioはその仕様を完全に無視するため、仕様はまったく重要ではありません。src
がイベントを送信できるようにするために、存在する必要があるだけです。存在しない場合、chan
の調整中に何かが間違っていたことを意味します。チャネルコントローラを参照してください。
src
¶
src
はApiServerSource
です。
最初に、src
がchan
に書き込んでいることを確認します。
kubectl --namespace knative-debug get apiserversource src -o jsonpath='{.spec.sink}'
これはmap[apiVersion:messaging.knative.dev/v1 kind:Channel name:chan]
を返す必要があります。そうでない場合、src
が正しく設定されておらず、そのspec
を修正する必要があります。修正は、そのspec
を更新して正しいsink
を持つようにするだけなので簡単です(example.yamlを参照)。
src
がchan
に送信していることがわかったため、Ready
であることを確認します。
kubectl --namespace knative-debug get apiserversource src -o jsonpath='{.status.conditions[?(.type == "Ready")].status}'
sub
¶
sub
はchan
からfn
へのSubscription
です。
sub
がReady
であることを確認します。
kubectl --namespace knative-debug get subscription sub -o jsonpath='{.status.conditions[?(.type == "Ready")].status}'
これはTrue
を返す必要があります。そうでない場合は、すべてのステータスエントリを確認してください。
kubectl --namespace knative-debug get subscription sub --output yaml
コントローラ¶
各リソースには、それを監視しているコントローラがあります。今日現在、それらは失敗ステータスメッセージとイベントを書き込むのが苦手である傾向があるため、コントローラのログを確認する必要があります。
注記
fn
を制御するKubernetes Deploymentコントローラは、このドキュメントの範囲外です。
サービスコントローラ¶
svc
を制御するKubernetes Serviceコントローラは、このドキュメントの範囲外です。
チャネルコントローラ¶
単一のChannel
コントローラはありません。代わりに、各Channel CRDに1つのコントローラがあります。chan
はInMemoryChannel
Channel CRD
を使用し、そのコントローラは次のとおりです。
kubectl --namespace knative-eventing get pod -l messaging.knative.dev/channel=in-memory-channel,messaging.knative.dev/role=controller --output yaml
そのログを次を使用して確認します。
kubectl --namespace knative-eventing logs -l messaging.knative.dev/channel=in-memory-channel,messaging.knative.dev/role=controller
ログレベルがwarning
またはerror
の行に特に注意してください。
ソースコントローラ¶
各ソースには、独自のコントローラがあります。src
はApiServerSource
であるため、そのコントローラは次のとおりです。
kubectl --namespace knative-eventing get pod -l app=sources-controller
これは実際には複数のSourceコントローラ(特にApiServerSourceコントローラを含む)を実行する単一のバイナリです。
ApiServerSourceコントローラ¶
ApiServerSource
コントローラは、Eventingの他のいくつかのSourceコントローラと同じバイナリで実行されます。それは次のとおりです。
kubectl --namespace knative-debug get pod -l eventing.knative.dev/sourceName=src,eventing.knative.dev/source=apiserver-source-controller
そのログを次を使用して確認します。
kubectl --namespace knative-debug logs -l eventing.knative.dev/sourceName=src,eventing.knative.dev/source=apiserver-source-controller
ログレベルがwarning
またはerror
の行に特に注意してください。
サブスクリプションコントローラ¶
Subscription
コントローラはsub
を制御します。Channel
がイベントを送信する必要があるアドレスを解決しようと試み、解決されると、それらをChannel
のspec.subscribable
に注入します。
kubectl --namespace knative-eventing get pod -l app=eventing-controller
そのログを次を使用して確認します。
kubectl --namespace knative-eventing logs -l app=eventing-controller
ログレベルがwarning
またはerror
の行に特に注意してください。
データプレーン¶
制御プレーン全体は正常に機能していますが、それでもイベントを取得していません。ここで、データプレーンを調査する必要があります。
Knativeイベントは次のパスを取ります。
-
イベントは
src
によって生成されます。 -
この場合、Kubernetesの
Event
がトリガーしていますが、Knative の観点からは、Source
がイベントを新規に(何もないところから)生成しています。 -
src
は、chan
のアドレスhttp://chan-kn-channel.knative-debug.svc.cluster.local
にイベントをPOSTしています。 -
Channel Dispatcherはリクエストを受信し、Hostヘッダーを検査してどの
Channel
に対応するかを決定します。knative-debug/chan
に対応していると判断し、sub
で定義されたサブスクライバ、特にfn
をバックエンドとするsvc
にリクエストを転送します。 -
fn
はリクエストを受信し、ログに記録します。
イベントの移動順にコンポーネントを調査します。
Channel Dispatcher¶
Channel Dispatcherは、Channel
にイベントをプッシュするPOSTを受信し、イベント受信時にそれらのChannel
のサブスクライバにPOSTするコンポーネントです。この例で使用されているin-memory-channel
では、すべてのin-memory-channel
Channel
の受信と配信の両方を処理する単一のバイナリがあります。
最初に、Dispatcherのログを検査して、明らかな問題がないか確認します。
kubectl --namespace knative-eventing logs -l messaging.knative.dev/channel=in-memory-channel,messaging.knative.dev/role=dispatcher -c dispatcher
理想的には、次のような行が表示されます。
{"level":"info","ts":"2019-08-16T13:50:55.424Z","logger":"inmemorychannel-dispatcher.in-memory-channel-dispatcher","caller":"provisioners/message_receiver.go:147","msg":"Request mapped to channel: knative-debug/chan-kn-channel","knative.dev/controller":"in-memory-channel-dispatcher"}
{"level":"info","ts":"2019-08-16T13:50:55.425Z","logger":"inmemorychannel-dispatcher.in-memory-channel-dispatcher","caller":"provisioners/message_dispatcher.go:112","msg":"Dispatching message to http://svc.knative-debug.svc.cluster.local/","knative.dev/controller":"in-memory-channel-dispatcher"}
{"level":"info","ts":"2019-08-16T13:50:55.981Z","logger":"inmemorychannel-dispatcher.in-memory-channel-dispatcher","caller":"provisioners/message_receiver.go:140","msg":"Received request for chan-kn-channel.knative-debug.svc.cluster.local","knative.dev/controller":"in-memory-channel-dispatcher"}
これは、リクエストが受信され、svc
に送信され、2XXの応答コード(おそらく200、202、または204)が返されていることを示しています。
しかし、次のようなものが見られる場合
{"level":"info","ts":"2019-08-16T16:10:16.859Z","logger":"inmemorychannel-dispatcher.in-memory-channel-dispatcher","caller":"provisioners/message_receiver.go:140","msg":"Received request for chan-kn-channel.knative-debug.svc.cluster.local","knative.dev/controller":"in-memory-channel-dispatcher"}
{"level":"info","ts":"2019-08-16T16:10:16.859Z","logger":"inmemorychannel-dispatcher.in-memory-channel-dispatcher","caller":"provisioners/message_receiver.go:147","msg":"Request mapped to channel: knative-debug/chan-kn-channel","knative.dev/controller":"in-memory-channel-dispatcher"}
{"level":"info","ts":"2019-08-16T16:10:16.859Z","logger":"inmemorychannel-dispatcher.in-memory-channel-dispatcher","caller":"provisioners/message_dispatcher.go:112","msg":"Dispatching message to http://svc.knative-debug.svc.cluster.local/","knative.dev/controller":"in-memory-channel-dispatcher"}
{"level":"error","ts":"2019-08-16T16:10:38.169Z","logger":"inmemorychannel-dispatcher.in-memory-channel-dispatcher","caller":"fanout/fanout_handler.go:121","msg":"Fanout had an error","knative.dev/controller":"in-memory-channel-dispatcher","error":"Unable to complete request Post http://svc.knative-debug.svc.cluster.local/: dial tcp 10.4.44.156:80: i/o timeout","stacktrace":"knative.dev/eventing/pkg/provisioners/fanout.(*Handler).dispatch\n\t/Users/xxxxxx/go/src/knative.dev/eventing/pkg/provisioners/fanout/fanout_handler.go:121\nknative.dev/eventing/pkg/provisioners/fanout.createReceiverFunction.func1.1\n\t/Users/i512777/go/src/knative.dev/eventing/pkg/provisioners/fanout/fanout_handler.go:95"}
http://svc.knative-debug.svc.cluster.local/
への投稿に問題があったことが分かります。