Kubenetesで稼働中のNode.jsのアプリケーションをinspectする方法
はじめに
Node.jsのアプリケーションでメモリリークが発生している場合などにNode.jsのinspect機能を使ってheapdumpを取得したいケースがある。通常インスペクターの接続にはアプリケーション起動時に --inspect
フラグを付与する必要があるが、稼働中のアプリケーションにおいて--inspect
フラグを付与していることは稀であるし、かといって--inspect
フラグを付与するためにアプリケーションを再起動してしまうと状態が失われてしまって検証が困難となる。今回の記事では稼働中のアプリケーションにインスペクターを付与する方法を解説する。
稼働中のNode.jsアプリケーションのインスペクターを有効にする
https://nodejs.org/en/guides/debugging-getting-started#enable-inspector によると、インスペクターを有効にする方法として起動時に--inspect
を付与する以外にSIGUSR1シグナルを送信することでも開始できると記載がある。
Node.js will also start listening for debugging messages if it receives a SIGUSR1 signal. (SIGUSR1 is not available on Windows.) In Node.js 7 and earlier, this activates the legacy Debugger API. In Node.js 8 and later, it will activate the Inspector API.
こちらに従ってインスペクターを有効にしてみる。
SIGUSR1のシグナルを送るにはアプリケーションのPIDを特定する必要がある。(以下の例では25932)
ps | grep node
25932 ttys042 0:00.96 node dist/server.js
特定したIDに対して以下のコマンドでSIGUSR1のシグナルを送信する
kill -usr1 25932
するとアプリケーションの標準出力に以下の様なメッセージが出る。
Debugger listening on ws://127.0.0.1:9229/56d15639-8814-4706-8b9e-869b30cc4d3d
For help, see: https://nodejs.org/en/docs/inspector
あとは chrome://inspect などからインスペクターを利用すれば良い。
Kubernetes上で稼働中のNode.jsアプリケーションに対してインスペクターを利用する
Kubernetes上でも以下の様にコンテナに入って前述のコマンドを実行すればインスペクターを利用可能になる。
kubectl exec --stdin --tty ${pod名} -- /bin/bash
ただしこのままではローカルのPCからインスペクターを接続することはできないので、port-forward機能を使用して接続を行う。
kubectl port-forward ${pod名} 9229:9229
Discussion