Stern について
Stern は Kubernetes のログを確認するためのコマンドラインツールで、コマンドは stern です。名前で指定した複数の Pod の出力を同時に表示でき、スクリプトや繰り返しの運用作業にも組み込みやすいです。
主な機能
- 01stern api で名前に一致する Pod のログを追跡
- 02--since 10m で直近 10 分に絞り込み
- 03自動化に向いたコマンド
- 04繰り返し実行できる運用ワークフロー
活用シーン
- 01障害調査で複数レプリカのログを同時に確認
- 02デプロイ後の直近の出力を確認
- 03コーディングエージェントがスクリプトからクラスターのログを収集
インストール
OS またはパッケージマネージャーを選び、コマンドをターミナルで実行します。
インストール後にstern --versionを実行して確認します。
コマンド例
よく使うコマンドを使う順に並べています。
詳細
stern
開発終了となった wercker/stern のフォークです
Stern を使うと、Kubernetes 上の複数のポッドや、ポッド内の複数のコンテナに対して tail を実行できます。デバッグをすばやく行えるよう、それぞれの結果は色分けされます。
クエリには正規表現、または <resource>/<name> の形式の Kubernetes リソースを指定します。これにより、ポッド名を簡単に絞り込むことができ、正確な ID(たとえば、デプロイメント ID)を指定する必要はありません。ポッドが削除されると tail の対象から外れ、新しいポッドが追加されると自動的に tail の対象になります。
ポッドに複数のコンテナが含まれている場合、コンテナごとに手動で実行しなくても、Stern ですべてのコンテナを tail できます。表示するコンテナを絞り込むには、container フラグを指定します。デフォルトでは、すべてのコンテナが対象になります。
インストール
バイナリをダウンロードする
バイナリリリースをダウンロードします。
ソースからビルドする
go install github.com/stern/stern@latest
asdf(Linux/macOS)
asdf を使用している場合は、次のようにインストールできます。
asdf plugin add stern
asdf install stern latest
Homebrew(Linux/macOS)
Homebrew を使用している場合は、次のようにインストールできます。
brew install stern
Krew(Linux/macOS/Windows)
kubectl プラグインのパッケージマネージャーである Krew を使用している場合は、次のようにインストールできます。
kubectl krew install stern
WinGet(Windows)
Windows を使用している場合、通常は Windows に組み込まれているパッケージマネージャーである WinGet を使ってインストールするのが最適です。次のようにインストールできます。
winget install stern.stern
使い方
stern pod-query [flags]
pod-query は正規表現、または <resource>/<name> の形式の Kubernetes リソースです。
クエリが Kubernetes リソースではない場合、正規表現として扱われます。そのため、"web-\w" を指定すると、web-backend と web-frontend のポッドを tail し、web-123 は対象にしません。
クエリを <resource>/<name> の形式(完全一致)で指定すると、deployment/nginx のように、指定した Kubernetes リソースに属するすべてのポッドを選択できます。
サポートされている Kubernetes リソースは、pod、replicationcontroller、service、daemonset、deployment、
replicaset、statefulset、job です。
cli フラグ
| flag | default | purpose |
|---|---|---|
--all-namespaces, -A | false | 指定すると、すべての名前空間を対象にログを追跡します。--namespace が指定されていても、特定の名前空間は無視されます。 |
--burst | 0 | Kubernetes API サーバーへのスロットリングにおける最大バースト数です。デフォルトは 0(client-go のデフォルトを使用)です。--qps=-1 の場合は無視されます。 |
--color | auto | 出力の色付けを強制的に設定します。'auto':TTY が接続されている場合に色付けします。'always':常に色付けします。'never':色付けしません。 |
--completion | 指定したシェル用の stern コマンドライン補完コードを出力します。'bash'、'zsh'、'fish' のいずれかを指定できます。 | |
--condition | フィルターに使用する条件です:[condition-name[=condition-value]。condition-value のデフォルトは true です。一致判定では大文字と小文字を区別しません。現在は --tail=0 または --no-follow と併用する場合のみサポートされています。 | |
--config | ~/.config/stern/config.yaml | stern 設定ファイルのパス |
--container, -c | .* | Pod 内に複数のコンテナーがある場合のコンテナー名です。(正規表現) |
--container-colors | コンテナー名の強調表示に使用する色を指定します。--pod-colors と同じ形式を使用します。省略した場合は --pod-colors の値が使われ、その長さと一致している必要があります。 | |
--container-state | all | running、waiting、terminated、または all の状態にあるコンテナーのログを追跡します。'all' はすべてのコンテナー状態に一致します。複数の状態を指定するには、このオプションを繰り返すか、カンマ区切りの値を設定します。 |
--context | 使用する kubeconfig コンテキストの名前 | |
--diff-container, -d | false | コンテナーごとに異なる色で表示します。 |
--ephemeral-containers | true | エフェメラルコンテナーを含めるか除外します。 |
--exclude, -e | [] | 除外するログ行です。(正規表現) |
--exclude-container, -E | [] | Pod 内に複数のコンテナーがある場合に除外するコンテナー名です。(正規表現) |
--exclude-pod | [] | 除外する Pod 名です。(正規表現) |
--field-selector | フィルターに使用するセレクター(フィールドクエリ)です。指定すると、Pod クエリのデフォルト値は ".*" になります。 | |
--highlight, -H | [] | 強調表示するログ行です。(正規表現) |
--include, -i | [] | 含めるログ行です。(正規表現) |
--init-containers | true | init コンテナーを含めるか除外します。 |
--kubeconfig | CLI リクエストで使用する kubeconfig ファイルのパスです。 | |
--max-log-requests | -1 | 要求するログの同時取得数の上限です。デフォルトは 50 ですが、--no-follow を指定した場合は 5 です。 |
--namespace, -n | 使用する Kubernetes 名前空間です。デフォルトでは、Kubernetes コンテキストに設定された名前空間を使用します。複数の名前空間を指定するには、このオプションを繰り返すか、カンマ区切りの値を設定します。 | |
--no-follow | false | すべてのログを表示した時点で終了します。 |
--node | フィルターに使用するノード名です。 | |
--only-log-lines | false | ログ行のみを出力します。 |
--output, -o | default | 定義済みテンプレートを指定します。現在サポートされている値:[default, raw, json, extjson, ppextjson] |
--pager | stern の出力を渡すコマンドです(例:'less')。標準出力がターミナルの場合にのみ使用され、--color=always を指定しなくても色が保持されます。 | |
--pod-colors | Pod 名の強調表示に使用する色を指定します。SGR(Select Graphic Rendition)シーケンスを使用し、カンマ区切りで指定します。例:"91,92,93,94,95,96"。 | |
--prompt, -p | false | 'app.kubernetes.io/instance' ラベル値を選択するための対話型プロンプトを切り替えます。 |
--qps | 0 | Kubernetes API サーバーへの最大 QPS です。デフォルトは 0(client-go のデフォルトを使用)です。クライアント側のスロットリングを無効にするには -1 を指定します。 |
--selector, -l | フィルターに使用するセレクター(ラベルクエリ)です。指定すると、Pod クエリのデフォルト値は ".*" になります。 | |
--show-hidden-options | false | 非表示のオプション一覧を出力します。 |
--since, -s | 48h0m0s | 5s、2m、3h などの相対時間より新しいログを返します。 |
--stdin | false | 標準入力からログを解析します。有効にすると、Kubernetes 関連のフラグはすべて無視されます。 |
--tail | -1 | 表示するログ末尾の行数です。デフォルトは -1 で、すべてのログを表示します。 |
--template | ログ行に使用するテンプレートです。空の場合は --output フラグを使用します。 | |
--template-file, -T | ログ行に使用するテンプレートのパスです。空の場合は --output フラグを使用します。--template オプションより優先されます。 | |
--timestamps, -t | 指定した形式でタイムスタンプを出力します。'default' または 'short' を '--timestamps=format' の形式で指定します('=' は省略できません)。値を指定せずにオプションを指定した場合は、'default' が使われます。 | |
--timezone | Local | タイムスタンプのタイムゾーンを設定します。 |
--verbosity | 0 | ログレベルの詳細度です。 |
--version, -v | false | バージョンを出力して終了します。 |
詳細については stern --help を参照してください。 |
$KUBECONFIG 環境変数が設定されている場合、stern はその値を使用します。環境変数と --kubeconfig フラグの両方が指定された場合は、コマンドラインフラグが使用されます。
設定ファイル
設定ファイルを使用すると、stern オプションのデフォルト値を変更できます。デフォルトの設定ファイルのパスは ~/.config/stern/config.yaml です。
# <flag name>: <value>
tail: 10
max-log-requests: 999
timestamps: short
--config フラグまたは STERNCONFIG 環境変数を使用して、設定ファイルのパスを変更できます。
テンプレート
stern は、カスタムログメッセージを出力できます。--output フラグを指定して使用できる、いくつかの定義済みテンプレートがあります。
| output | description |
|---|---|
default | 名前空間、ポッド、コンテナを表示し、--color に応じた色で装飾します |
raw | ログメッセージ自体のみを出力します。ログが JSON で、jq にパイプしたい場合に便利です |
json | ログ構造体を JSON にマーシャリングします。プログラムでの利用に便利です |
extjson | ポッド名とコンテナ名を色付けした拡張 JSON を出力します |
ppextjson | ポッド名とコンテナ名を色付けした拡張 JSON を整形して出力します |
--template フラグを使ってカスタムテンプレートを指定できます。テンプレートは Go テンプレートにコンパイルされ、すべてのログメッセージに使用されます。この Go テンプレートには、次の構造体が渡されます。
| property | type | description |
|---|---|---|
Message | string | ログメッセージ自体 |
Timestamp | string | --timestamps/--timezone に従ってフォーマットされたログのタイムスタンプ。--timestamps が設定されていない場合は空です |
NodeName | string | ポッドがスケジュールされているノード名 |
Namespace | string | ポッドの名前空間 |
PodName | string | ポッド名 |
ContainerName | string | コンテナ名 |
Labels | map[string]string | ポッドのラベル |
Annotations | map[string]string | ポッドのアノテーション |
テンプレート内では、以下の関数を使用できます(組み込み関数を除く)。
| 関数 | 引数 | 説明 |
|---|---|---|
json | object | オブジェクトをマーシャルし、JSON テキストとして出力します |
color | color.Color, string | テキストを色で囲みます(.ContainerColor と .PodColor が用意されています) |
parseJSON | string | 文字列を JSON として解析します |
tryParseJSON | string | 文字列を JSON として解析し、失敗した場合は nil を返します |
extractJSONParts | string, ...string | 文字列を JSON として解析し、指定されたキーを連結します。キーにはドット表記(例:python.levelname)を使用して、ネストされたフィールドにアクセスできます。 |
tryExtractJSONParts | string, ...string | 文字列を JSON として解析し、指定されたキーを連結します(ドット表記でネストされたフィールドにアクセスできます)。失敗した場合はテキストを返します。 |
prettyJSON | any | 入力を解析して整形済み JSON として出力し、解析に失敗した場合は文字列をそのまま出力します。 |
toRFC3339Nano | object | タイムスタンプ(string、int、json.Number)を解析し、RFC3339Nano 形式で出力します |
toUTC | object | タイムスタンプ(string、int、json.Number)を解析し、UTC の time.Time として返します |
toTimestamp | object, string [, string] | タイムスタンプ(string、int、json.Number)を解析し、指定されたレイアウトで出力します。タイムゾーンを任意で指定できます(デフォルトは UTC)。 |
levelColor | string | ログレベルを適切な色で表示します |
bunyanLevelColor | string | bunyan の数値ログレベルを適切な色で表示します |
colorBlack | string | テキストを黒色で表示します |
colorRed | string | テキストを赤色で表示します |
colorGreen | string | テキストを緑色で表示します |
colorYellow | string | テキストを黄色で表示します |
colorBlue | string | テキストを青色で表示します |
colorMagenta | string | テキストをマゼンタ色で表示します |
colorCyan | string | テキストをシアン色で表示します |
colorWhite | string | テキストを白色で表示します |
colorCustom | string, int [, int] | テキストをカスタムカラーで表示します。たとえば、{{colorCustom "Hi" 3 96}} は "Hi" をイタリック体のシアン色で表示します |
ログレベルの詳細度
--verbosity フラグでログレベルの詳細度を設定できます。
トラブルシューティングの際に、stern が Kubernetes API サーバーとどのようにやり取りするかを確認するのに便利です。
詳細度を上げると、ログの数が増えます。まずは --verbosity 6 から始めるとよいでしょう。
ログリクエストの最大数
stern は、クラスターに意図しない負荷がかからないよう、同時にリクエストできるログ数に上限を設けています。
この数は --max-log-requests フラグで設定できます。
--no-follow フラグの有無によって、動作とデフォルト値が異なります。
--no-follow | デフォルト | 動作 |
|---|---|---|
| 指定あり | 5 | 同時にリクエストするログ数を制限します |
| 指定なし | 50 | 同時実行数の上限に達するとエラーで終了します |
ログを順番に表示したい場合は、--max-log-requests 1 と --no-follow の組み合わせが便利です。
ハイライトの色をカスタマイズする
以下に示すように、設定ファイルで、ポッドとコンテナーのハイライト色を、カンマ区切りのSGR(Select Graphic Rendition)シーケンスのリストを使って設定できます。container-colors を省略すると、ポッドの色がコンテナーの色にも使用されます。
stern はこのリストから色を選ぶため、未使用の色が残っている限り、同じワークロード(Deployment や StatefulSet のレプリカなど)によって作成されたポッドには、それぞれ異なる色が割り当てられます。
# Green, Yellow, Blue, Magenta, Cyan, White
pod-colors: "32,33,34,35,36,37"
# Colors with underline (4)
# If empty, the pod colors will be used as container colors
container-colors: "32;4,33;4,34;4,35;4,36;4,37;4"
この形式では、端末が対応していれば、下線、背景色、8 ビットカラー、24 ビットカラーなど、さまざまな属性を使用できます。
同等のフラグとして --pod-colors と --container-colors も使用できます。次のコマンドでは、--pod-colors フラグを使って24 ビットカラーを適用します。
# Monokai theme
podColors="38;2;255;97;136,38;2;169;220;118,38;2;255;216;102,38;2;120;220;232,38;2;171;157;242"
stern --pod-colors "$podColors" deploy/app
ページャーの使用
--pager フラグを使うと、stern の出力をページャーにパイプできます。シェルでパイプする場合(stern --color=always backend | less -R)とは異なり、追加のフラグなしで色が保持され、ページャーを終了すると stern はログの追跡を停止します。
stern --pager less backend
ページャーが使用されるのは、標準出力が端末の場合のみです。常にページャーを使用するには、設定ファイルで設定します。
pager: less
stern は、LESS=FRX と LV=-c の環境変数がすでに設定されていない限り、それらを設定してページャーを実行します。これにより、less と lv では初期設定のままで色が表示されます。
例:
すべての名前空間のすべてのログを追跡します
stern . --all-namespaces
過去のログを表示せずに、kube-system 名前空間を追跡します
stern . -n kube-system --tail 0
staging 上の envvars Pod 内で実行されている gateway コンテナーを追跡します
stern envvars --context staging --container gateway
istio-proxy コンテナーのログを除外して、staging 名前空間を追跡します
stern -n staging --exclude-container istio-proxy .
kube-apiserver Pod のログを除外して、kube-system 名前空間を追跡します
stern -n kube-system --exclude-pod kube-apiserver .
15 分前からの認証アクティビティをタイムスタンプ付きで表示します
stern auth -t --since 15m
過去 5 分間のすべてのログを時刻順に表示します
stern --since=5m --no-follow --only-log-lines -A -t . | sort -k4
特定のタイムゾーンのタイムスタンプ付きで認証アクティビティを表示します(デフォルトはローカルのタイムゾーンです)
stern auth -t --timezone Asia/Tokyo
minikube で some-new-feature の開発状況を追跡します
stern some-new-feature --context minikube
別の名前空間の Pod を表示します
stern kubernetes-dashboard --namespace kube-system
すべての名前空間で、run=nginx ラベルセレクターに一致する Pod を追跡します
stern --all-namespaces -l run=nginx
canary リリースの frontend Pod を追跡します
stern frontend --selector release=canary
すべての名前空間で、kind-control-plane ノード上の Pod を追跡します
stern --all-namespaces --field-selector spec.nodeName=kind-control-plane
deployment/nginx によって作成された Pod を追跡します
stern deployment/nginx
ログメッセージを jq にパイプします:
stern backend -o json | jq .
ログメッセージのみを出力します:
stern backend -o raw
カスタムテンプレートを使って出力します:
stern --template '{{printf "%s (%s/%s/%s/%s)\n" .Message .NodeName .Namespace .PodName .ContainerName}}' backend
stern が提供する色を使って、カスタムテンプレートで出力します:
stern --template '{{.Message}} ({{.Namespace}}/{{color .PodColor .PodName}}/{{color .ContainerColor .ContainerName}}){{"\n"}}' backend
parseJSON を使ったカスタムテンプレートで出力します:
stern --template='{{.PodName}}/{{.ContainerName}} {{with $d := .Message | parseJSON}}[{{$d.level}}] {{$d.message}}{{end}}{{"\n"}}' backend
JSON の解析を試み、失敗した場合は生の形式にフォールバックするカスタムテンプレートで出力します:
stern --template='{{.PodName}}/{{.ContainerName}} {{ with $msg := .Message | tryParseJSON }}[{{ colorGreen (toRFC3339Nano $msg.ts) }}] {{ levelColor $msg.level }} ({{ colorCyan $msg.caller }}) {{ $msg.msg }}{{ else }} {{ .Message }} {{ end }}{{"\n"}}' backend
JSON を(JSON の場合は)整形して出力します:
# Will try to parse .Message as JSON and pretty print it, if not json will output as is
stern --template='{{ .Message | prettyJSON }}{{"\n"}}' backend
# Or with parsed json, will drop non-json logs because of `with`
stern --template='{{ with $msg := .Message | tryParseJSON }}{{ prettyJSON $msg }}{{"\n"}}{{end}}' backend
ドット記法を使って、ネストされたフィールドを含む JSON のフィールドを抽出します:
# Given a message like {"python": {"levelname": "INFO", "module": "router"}}
stern --template='{{ levelColor (extractJSONParts .Message "python.levelname") }} {{ extractJSONParts .Message "python.module" }}{{"\n"}}' backend
カスタムテンプレートをファイルから読み込みます:
stern --template-file=~/.stern.tpl backend
「app.kubernetes.io/instance」ラベルの値を選択する対話型プロンプトを起動します:
stern -p
ログ行のみを出力します:
stern . --only-log-lines
標準入力から読み込みます:
stern --stdin < service.log
Ready ではない Pod のログのみを表示します:
stern . --condition=ready=false --tail=0
補完
Stern は bash、zsh、fish のコマンドライン自動補完に対応しています。stern --completion=(bash|zsh|fish) は、指定したシェル用の補完コードを出力します。このコードは .bashrc などで評価することで動作します。さらに、Stern は --namespace、--context、--node、<resource>/<name> 形式のリソースクエリー、および選択肢が事前定義されたフラグの動的補完にも対応しています。
bash を使用している場合、stern の bash 補完コードは bash-completion に依存します。macOS では、次のように Homebrew でインストールできます:
# If running Bash 3.2
brew install bash-completion
# or, if running Bash 4.1+
brew install bash-completion@2
.bashrc で stern の bash 補完コードを読み込む前に、bash-completion を読み込む必要があることに注意してください。
source "$(brew --prefix)/etc/profile.d/bash_completion.sh"
source <(stern --completion=bash)
Krew 経由でインストールした場合は、次のようにします:
source <(kubectl stern --completion bash)
complete -o default -F __start_stern kubectl stern
zsh を使用している場合は、stern の zsh 補完コードを .zshrc で読み込むだけです。
source <(stern --completion=zsh)
fish シェルを使用している場合は、stern の fish 補完コードを読み込むだけです。
stern --completion=fish | source
# To load completions for each session, execute once:
stern --completion=fish >~/.config/fish/completions/stern.fish
コンテナーでの実行
stern はコンテナーを使って実行することもできます:
docker run ghcr.io/stern/stern --version
minikube クラスターを使用している場合は、次のようにコンテナーを実行する必要があります:
docker run --rm -v "$HOME/.minikube:$HOME/.minikube" -v "$HOME/.kube:/$HOME/.kube" -e KUBECONFIG="$HOME/.kube/config" ghcr.io/stern/stern .
イメージタグは https://github.com/orgs/stern/packages/container/package/stern で確認できます。
Kubernetes Pod での実行
Kubernetes Pod で stern を使用するには、次の ClusterRole を作成し、ServiceAccount にバインドする必要があります。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: stern
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "watch", "list"]
このリポジトリへの貢献
詳細については、CONTRIBUTING を参照してください。