📝

Kubenetesで稼働中のNode.jsのアプリケーションをinspectする方法

2024/01/29に公開

はじめに

Node.jsのアプリケーションでメモリリークが発生している場合などにchromeの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