Kubernetes上で動くGoサーバーでプロファイラを動かしWeb UIで表示する
Goにはプロファイラとして標準パッケージにpprofが搭載されています。
pprofの使い方としてはすでに多数の優良記事が存在するため、ここでは扱いません。
今回はpprofをk8s上で動くサーバーに対して実行し、結果をWebUIで表示する必要があったのでそのやり方を紹介します。
環境
インフラ構成
- GoサーバーのHTTP API用のPortが80
- Ingress経由でアクセス
- pprof用のPortが6060
- プロファイラ結果のWeb UI用のPortが8080
- このPortをServiceのNodePortでMacに公開
やり方
pprofの設定
まずは通常通りpprofの設定をしてGoをビルドします。
import ( ... _ "net/http/pprof" ) func main() { ... go func() { log.Println(http.ListenAndServe("localhost:6060", nil)) }() ... }
このバイナリがk8sのPodで動いているとします。
Serviceの定義
通常のAPIへのアクセスに使うServiceが以下です。
apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-service ports: - name: http protocol: TCP port: 80 targetPort: 80
これに追加してpprofのWebページにアクセスするためのServiceを定義します。
このServiceのTypeをNodePortにすることでお手軽にアクセスできるようになります。
apiVersion: v1 kind: Service metadata: name: my-service-pprof spec: selector: app: my-service-api type: NodePort ports: - name: http-pprof protocol: TCP port: 8080 targetPort: 8080 nodePort: 30080
pprofの実行
Goのバイナリが動くPodに入り以下のコマンドでpprofを実行します。
$ pprof -http=0.0.0.0:8080 /usr/local/bin/my-api http://localhost:6060/debug/pprof/profile
ここで大事なのはpprofのWebページのアドレスを 0.0.0.0
にすることです。ここを 127.0.0.1
にしていると外部からアクセスできなくなってしまいます。
あとは計測したいエンドポイントにアクセスし以下のようなメッセージが表示された後、ホストからNodePortの 30080
にアクセスすればプロファイル結果がWebUIで表示されます。
Saved profile in /root/pprof/pprof.my-api.samples.cpu.001.pb.gz Serving web UI on http://0.0.0.0:8080 Couldn't find a suitable web browser! Set the BROWSER environment variable to your desired browser.