sternを使ったpodのログ出力

[Japan Container Days v18.12](https://containerdays.jp/) で聴講した下記セッションで知った、"stern"というログ出力ユーティリティを使ってみた。

[コードを書くことに集中したい全てのアプリ開発者に贈るKubernetesの話(スライド)](https://speakerdeck.com/yoshiaki_mizukura/kubernetes-tips-for-all-application-engineers-who-want-to-focus-on-coding)

[wercker/stern: ⎈ Multi pod and container log tailing for Kubernetes](https://github.com/wercker/stern)

一言でいうと、スケーリング状態を意識することなくpodのログを見続けることができる、という代物。

ちなみにKubernetesでなくOpenShift(Minishift環境)での確認

# install

ソースのビルド手順がGitHubに載っているが、ビルド済みバイナリを入れてもよい。
https://github.com/wercker/stern/releases

セットアップ例はWindows版だが、例えばUbuntu18.04なら`stern_linux_amd64`を落とせば動作した。

```
zaki@mascarpone% curl -LO https://github.com/wercker/stern/releases/download/1.10.0/stern_windows_amd64.exe
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   613    0   613    0     0    613      0 --:--:-- --:--:-- --:--:--  1058
100 20.9M  100 20.9M    0     0  3572k      0  0:00:06  0:00:06 --:--:-- 4372k
zaki@mascarpone% ls
stern_windows_amd64.exe*
zaki@mascarpone% mv stern_windows_amd64.exe stern.exe
zaki@mascarpone% ./stern.exe
Tail multiple pods and containers from Kubernetes

Usage:
  stern pod-query [flags]

Flags:
      --all-namespaces             If present, tail across all namespaces. A specific namespace is ignored even if specified with --namespace.
      --color string               Color output. Can be 'always', 'never', or 'auto' (default "auto")
      --completion string          Outputs stern command-line completion code for the specified shell. Can be 'bash' or 'zsh'
  -c, --container string           Container name when multiple containers in pod (default ".*")
      --container-state string     If present, tail containers with status in running, waiting or terminated. Default to running. (default "running")
      --context string             Kubernetes context to use. Default to current context configured in kubeconfig.
  -e, --exclude strings            Regex of log lines to exclude
  -E, --exclude-container string   Exclude a Container name
  -h, --help                       help for stern
      --kubeconfig string          Path to kubeconfig file to use
  -n, --namespace string           Kubernetes namespace to use. Default to namespace configured in Kubernetes context
  -o, --output string              Specify predefined template. Currently support: [default, raw, json] (default "default")
  -l, --selector string            Selector (label query) to filter on. If present, default to ".*" for the pod-query.
  -s, --since duration             Return logs newer than a relative duration like 5s, 2m, or 3h. Defaults to 48h.
      --tail int                   The number of lines from the end of the logs to show. Defaults to -1, showing all logs. (default -1)
      --template string            Template to use for log lines, leave empty to use --output flag
  -t, --timestamps                 Print timestamps
  -v, --version                    Print the version and exit
zaki@mascarpone% ./stern.exe --version
stern version 1.10.0
```

# 実行例

podの実行状態

```
zaki@mascarpone% oc get pod
NAME                      READY     STATUS    RESTARTS   AGE
javaee-memoapp2-1-khhzs   1/1       Running   0          25m
javaee-memoapp2-1-xtrp4   1/1       Running   0          23m
memoapp-db-1-4l5w6        1/1       Running   3          2d
```

2つ起動している javaee-memoapp2 のログをまとめて見たい場合、`pod-query`に実行中にpod名にマッチする正規表現を指定する。

```
zaki@mascarpone% stern "javaee-memoapp2-\w"
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/256859/d1620eda-c6d3-13cb-47fb-806cd45da381.png)

pod毎に色分けして表示してくれる。

※ Windows標準のコマンドプロンプトやPowerShellのターミナルだとエスケープシーケンスを解釈されずにそのままコードが出力されるので、`--color=never`をつける

# podの再作成

```
zaki@mascarpone% oc get pod
NAME                      READY     STATUS    RESTARTS   AGE
javaee-memoapp2-1-khhzs   1/1       Running   0          3h
memoapp-db-1-4l5w6        1/1       Running   3          2d
zaki@mascarpone% oc delete pod/javaee-memoapp2-1-khhzs
pod "javaee-memoapp2-1-khhzs" deleted
zaki@mascarpone% oc get pod
NAME                      READY     STATUS    RESTARTS   AGE
javaee-memoapp2-1-84rq6   1/1       Running   0          15s
memoapp-db-1-4l5w6        1/1       Running   3          2d
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/256859/c5f835ed-1a6c-c5aa-f366-42e43ede15ed.png)

podが消えると`- podname`が出力され、podが追加されると`+ podname`が出力される。

# stern実行中にpodのスケールを変更

```
zaki@mascarpone% oc scale --replicas=4 dc/javaee-memoapp2
deploymentconfig.apps.openshift.io/javaee-memoapp2 scaled
zaki@mascarpone% oc get pod
NAME                      READY     STATUS    RESTARTS   AGE
javaee-memoapp2-1-h6fxf   1/1       Running   0          11s
javaee-memoapp2-1-khhzs   1/1       Running   0          2h
javaee-memoapp2-1-lzz58   1/1       Running   0          11s
javaee-memoapp2-1-xtrp4   1/1       Running   0          2h
memoapp-db-1-4l5w6        1/1       Running   3          2d
```

`h6fxf`と`lzz58`が追加された

![image.png](https://qiita-image-store.s3.amazonaws.com/0/256859/138da514-b8f7-293e-26b4-877b65bc7f93.png)

sternも追従してログを出力してくれる。

停止時も同様

```
zaki@mascarpone% oc scale --replicas=2 dc/javaee-memoapp2
deploymentconfig.apps.openshift.io/javaee-memoapp2 scaled
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/256859/c60061f3-58e8-7c7f-9a17-ee3e6c3fef32.png)

# 日時の追加

デフォルトだと生ログが出力されるだけなので、独自に時刻出力してなければ時間はわからない。
ただし`-t`を付けると時刻も出力されるようになる。
※ タイムゾーンはpodに依存する

```
zaki@mascarpone% stern -t "javaee-memoapp2-\w"
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/256859/e8059508-bcd7-e2de-db05-47fa3576f493.png)

# namespaceの指定/横断

namespaceの指定は`oc`と同様に`-n`を付加

```
zaki@mascarpone% stern "kube-\w" -n kube-dns
```

namespace横断も`oc`と同様に`--all-namespaces`が使用できる

```
zaki@mascarpone% stern "kube-\w" --all-namespaces
```