【小ネタ】Kubernetesでアプリへのリクエストに503が返って七転八倒斎したお話

この記事はなむゆの個人ブログにマルチポストしています。

はじめに

kubernetes社内最強になりたいなむゆです。
最近Kubernetes上にアプリケーションをデプロイしていて、ルーティング周りでエラーシュートをしました。
その時起きていた問題について色々キーワードで調べても(kubernetes 503 VirtualService とか)あまり問題解決につながる情報が出てこなかったのでメモしておきます。

起きたこと

アプリケーションにAPIを追加したのでVirtualServiceにそのAPIへのルーティングを加え、applyしました。
それ以降、kubernetesにデプロイしているserviceの、新たにVirtualServiceに追加したルーティング以外のアプリのAPIのパスに対するリクエストに対して503が返ってくるようになりました。
ログを見ると、APIのPodログには正常にレスポンスが返っているときのログは残っているのですが、503が返ってくるときのログは残っていませんでした。
istio-ingressgatewayのPodのログを確認すると、503のエラーが返った履歴が残っていました。
そのアプリをローカルで実行すると全APIから正常にレスポンスが返りました。
これらのことから、アプリケーションのPodは正常に動作していてistio-ingressgatewayまでリクエストはやってきているもののVirtualServiceに書いてあるルーティングか何かでコケているんじゃないかと考えました。
VirtualServiceのrouteもちゃんと設定してあるしhostの設定もドキュメントにあるとおりに、{service名}.{namespace}.svc.cluster.localにしてあるし・・・(そもそも一部APIは正常にルーティングされたので当然といえば当然)
ということで謎にハマりました。

原因

別のnamespaceに更新前のVirtualServiceが生きていました。
VirtualServiceの更新時にnamespaceが他と被りそうで怖かったのでそちらも更新していたのですね。
すると、metadataの中身が変わったのでkubernetesとしては「あ、別のオブジェクトなんだな~」と勘違いして、新しいVirtualServiceのオブジェクトを作ってしまっていました。
VirtualServiceは、同じ条件のuriに対してルーティング先が複数あるとエラーを起こして503を返すようです。(一次ソース見つからず。なぜ?)
今回は古いVirtualServiceと新しいVirtualServiceが両方存在してしまっていたためにuriの条件が競合してエラーが起きていたようです。
古い方のVirtualServiceを削除したところ、問題は解決しました。

教訓

マニフェストファイルのmetadataを変更したらkubernetes上の元のオブジェクトは消しましょう。  

同じ部分で詰まったほかの人の役に立ちますように・・・