複数のPodのログをまとめて表示する

Kubernetesを開発環境として使用しプロダクションと同じような環境で開発すると、複数のアプリケーションが可動することになると思います。
そうするとログも複数の場所に出力されることになります。

複数個のターミナルを立ち上げ1つずつログを表示してもいいですが、場所を取りますし確認する箇所が増えて面倒なので、まとめて表示する方法を紹介します。

今回は以下の2つの構成に合わせたやり方を紹介します。

  • ログを標準出力に書き出している場合
  • ログをファイルに書き出している場合

ログを標準出力に書き出している場合

これは stern というアプリケーションを使えば簡単にできます。

github.com

使い方は簡単でPodの名前を引数として渡すだけです。
正規表現でいい感じに検索してくれて、オプションを入れればコンテナで絞り込むこともできます。

Dockerの標準に沿ったアプリケーションならこれを使えば解決です。

ログをファイルに書き出している場合

様々な理由によりDockerの標準に合わせることができず、ファイルにログを書き出している場合もあると思います。

この場合は kubectl exectail することになりますが、複数のPodのログをまとめるためには少し工夫をしなければいけません。

名前付きパイプを使う

名前付きパイプを使って複数の kubectl exec の出力を1つにまとめます。

名前付きパイプについての説明はこの記事がわかりやすいです。

qiita.com

名前付きパイプに kubectl exec を出力し、名前付きパイプを cat することでログをまとめて表示します。

シェルスクリプトで一連の処理を書きます。

#! /usr/bin/env bash

FIFO="/tmp/shout"

mkfifo ${FIFO}
trap 'rm ${FIFO}; exit 1' 1 2 3 15

PODA=$(kubectl get po -o=jsonpath='{.items[?(@.metadata.labels.app=="pod-a")].metadata.name}')
PODB=$(kubectl get po -o=jsonpath='{.items[?(@.metadata.labels.app=="pod-b")].metadata.name}')
PODC=$(kubectl get po -o=jsonpath='{.items[?(@.metadata.labels.app=="pod-c")].metadata.name}')

kubectl exec -i ${PODA} -c hoge -- tail -f /var/app/log/hoge_log > ${FIFO} | \
kubectl exec -i ${PODB} -c hoge -- tail -f /var/app/log/hoge_log > ${FIFO} | \
kubectl exec -i ${PODC} -c hoge -- tail -f /var/app/log/hoge_log > ${FIFO} | \
cat ${FIFO}

stern と比べると見やすさや使いやすさで数段劣りますが、同じようにまとめて出力することができます。