Kubernetes の標準出力と標準エラー出力
Kubernetes では、コンテナの標準出力/標準エラー出力ログを kubectl logs
コマンドで取得できます。実際にどのファイルに標準出力/標準エラー出力ログが出力されて、ローテートはどういう設定になっているのか整理しました。
1. ログの保存場所
まずは標準出力/標準エラー出力ログの保存場所です。
コンテナが標準出力/標準エラー出力に出力したログは Node に保存されます。実体のファイルとシンボリックリンクの構成は以下です。
整理すると以下になります。
# | ログ | 説明 |
---|---|---|
① | /var/lib/docker/containers/< Container ID >/< Container ID >-json.log | ・コンテナの stdout/stderr に出力されたログが保存される実体のファイル ・起動中の Pod のログのみ保存 ・終了した Pod のログは消える ・コンテナが再起動した場合、再起動前のコンテナのログは消えない ・保存されるのは 2 世代分のコンテナ(起動中のコンテナと再起動前のコンテナのログのみ保存) |
② | /var/log/pods/< Namespace >_< Pod Name >_< Pod UID >/< Container Name >/< Index >.log | ・①のファイルへのシンボリックリンク ・0.log が現在起動中のコンテナのログのリンク ・1.log が一つ前に起動していたコンテナのログのリンク ・ kubectl logs コマンドは API Server 経由で /var/log/pods にアクセスしている |
③ | /var/log/containers/< Pod Name >_< Namespace >_< Container Name >-< Container ID >.log | ・②のファイルへのシンボリックリンク |
実際のログです。
- @Node $ ls -lh /var/log/pods/kube-system_coredns-76f4967988-pkkx9_1ab7cf50-3781-4576-8a4d-d918e321ee64/coredns/*
- lrwxrwxrwx 1 root root 165 2月 15 14:07 /var/log/pods/kube-system_coredns-76f4967988-pkkx9_1ab7cf50-3781-4576-8a4d-d918e321ee64/coredns/0.log -> /var/lib/docker/containers/52d7283862b0b64d6bdfc7dc4dce964bb3ca284ec3048325dbb7e5d61a1a00e3/52d7283862b0b64d6bdfc7dc4dce964bb3ca284ec3048325dbb7e5d61a1a00e3-json.log
- lrwxrwxrwx 1 root root 165 2月 15 15:17 /var/log/pods/kube-system_coredns-76f4967988-pkkx9_1ab7cf50-3781-4576-8a4d-d918e321ee64/coredns/1.log -> /var/lib/docker/containers/a402cbab8d63b90c3d76f87579fe73bca77a2bffae2d5e0b3bd1617a1dbc037b/a402cbab8d63b90c3d76f87579fe73bca77a2bffae2d5e0b3bd1617a1dbc037b-json.log
- @Node $ ls -lh /var/log/containers/coredns-76f4967988-pkkx9_kube-system_coredns-*
- lrwxrwxrwx 1 root root 101 2月 15 14:07 /var/log/containers/coredns-76f4967988-pkkx9_kube-system_coredns-52d7283862b0b64d6bdfc7dc4dce964bb3ca284ec3048325dbb7e5d61a1a00e3.log -> /var/log/pods/kube-system_coredns-76f4967988-pkkx9_1ab7cf50-3781-4576-8a4d-d918e321ee64/coredns/0.log
- lrwxrwxrwx 1 root root 101 2月 15 15:17 /var/log/containers/coredns-76f4967988-pkkx9_kube-system_coredns-a402cbab8d63b90c3d76f87579fe73bca77a2bffae2d5e0b3bd1617a1dbc037b.log -> /var/log/pods/kube-system_coredns-76f4967988-pkkx9_1ab7cf50-3781-4576-8a4d-d918e321ee64/coredns/1.log
※ Pod の UID は kubectl get pods -n <Namespace> <Pod Name> -o jsonpath='{.metadata.uid}'
で確認可能
2. コンテナログのローテート、世代
ログが増え続けると Node のディスクが逼迫するので、ローテートと削除の設定が必要です。Kubernetes では /etc/docker/daemon.json
でそれらを設定しています。
オプション | 説明 |
---|---|
log-opts.max-size |
・ログをローテートするファイルサイズ ・単位はキロバイト(k)/メガバイト(m)/ギガバイト(g) |
log-opts.max-file |
・ログの世代数 ・max-size が設定されていない場合は無効 |
例えば、max-size:100m,max-file:10
の場合、一つのコンテナが最大 1 GB のログを保存する状態になります。最初に記載した通り、Pod としては 2 世代のコンテナのログを保存するため最大 2 GB になります。Node のディスクをサイジングする際はこれらを考慮する必要があります。
※ kubelet フラグにも同様の意味の containerLogMaxSize
と containerLogMaxFiles
がありますが、検証したところ /etc/docker/daemon.json
の log-opts
に設定されている値でローテート、削除されていました
3. 検証
3.1. 検証環境構築
eksctl コマンドで EKS Cluster を作成する - YasuBlog の記事で作成した EKS Cluster を使用します。
3.2. EKS の設定値
max-size/max-file
は Node 上の /etc/docker/daemon.json
で確認できます。
- @Node $ cat /etc/docker/daemon.json
- {
- "bridge": "none",
- "log-driver": "json-file",
- "log-opts": {
- "max-size": "10m",
- "max-file": "10"
- },
- "live-restore": true,
- "max-concurrent-downloads": 10,
- "default-ulimits": {
- "memlock": {
- "Hard": -1,
- "Name": "memlock",
- "Soft": -1
- }
- }
- }
max-size
が 10m
, max-file
が 10
に設定されています。
インスタンスタイプ毎の設定値を確認してみました。Node のリソース量に関わらず固定値が設定されているようです。
インスタンスタイプ | max-size | max-file |
---|---|---|
t3.small | 10m | 10 |
t3.medium | 10m | 10 |
m5.large | 10m | 10 |
m5.xlarge | 10m | 10 |
3.3. 挙動確認
つづいて実際の挙動を確認してみます。
3.3.1. ローテートと世代
まずはシンプルな Pod を起動します。
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: deployment
- spec:
- replicas: 1
- selector:
- matchLabels:
- app: app
- template:
- metadata:
- labels:
- app: app
- spec:
- containers:
- - name: amazonlinux
- image: public.ecr.aws/amazonlinux/amazonlinux:latest
- command:
- - "bin/bash"
- - "-c"
- - "sleep 3600"
コンテナ ID を確認します。
- $ kubectl get pods -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- deployment-6bb985c8c9-p7b5w 1/1 Running 0 114s 10.0.102.47 ip-10-0-102-148.ap-northeast-1.compute.internal <none> <none>
- $ kubectl describe pod deployment-6bb985c8c9-7xmm4 | grep 'Container ID'
- Container ID: docker://057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7
Node 上のログを確認します。
- @Node $ ls -lh /var/lib/docker/containers/057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7/
- 合計 12K
- -rw-r----- 1 root root 0 2月 16 14:55 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log
- drwx------ 2 root root 6 2月 16 14:55 checkpoints
- -rw------- 1 root root 4.8K 2月 16 14:55 config.v2.json
- -rw-r--r-- 1 root root 2.1K 2月 16 14:55 hostconfig.json
- drwx--x--- 2 root root 6 2月 16 14:55 mounts
- @Node $ ls -lh /var/log/pods/default_deployment-6bb985c8c9-p7b5w_ef8acb63-8389-47d6-aad8-c2976eac3665/amazonlinux/
- 合計 0
- lrwxrwxrwx 1 root root 165 2月 16 14:55 0.log -> /var/lib/docker/containers/057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7/057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log
標準出力/標準エラー出力に何も出力していないので、上記の通りサイズが 0 のファイルが一つだけあります。この状態で Pod にログインし、標準出力に大量にログを出力してみます。
- $ kubectl exec -it deployment-6bb985c8c9-p7b5w -- /bin/bash
- @Pod $ while true;do cat /etc/services > /proc/1/fd/1;done
Node 上のログを確認します。
- @Node $ ls -lh /var/lib/docker/containers/057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7/
- 合計 90M
- -rw-r----- 1 root root 2.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.1
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.2
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.3
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.4
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.5
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.6
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.7
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.8
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.9
- drwx------ 2 root root 6 2月 16 14:55 checkpoints
- -rw------- 1 root root 4.8K 2月 16 14:55 config.v2.json
- -rw-r--r-- 1 root root 2.1K 2月 16 14:55 hostconfig.json
- drwx--x--- 2 root root 6 2月 16 14:55 mounts
- @Node $ ls -lh /var/log/pods/default_deployment-6bb985c8c9-p7b5w_ef8acb63-8389-47d6-aad8-c2976eac3665/amazonlinux/
- 合計 0
- lrwxrwxrwx 1 root root 165 2月 16 14:55 0.log -> /var/lib/docker/containers/057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7/057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log
max-size/max-file
の設定通り、ログサイズが 10M でローテートされ、10 世代保存されている事が確認できました。/var/log/pods
の 0.log
は常に最新のファイルのシンボリックリンクになっています。
3.3.2. コンテナ再起動
上記の状態で、Node 上で docker stop を実行してコンテナを再起動してみます。
- @Node $ docker ps | grep amazonlinux
- 057fc611f5c4 public.ecr.aws/amazonlinux/amazonlinux "bin/bash -c 'sleep …" 5 minutes ago Up 5 minutes k8s_amazonlinux_deployment-6bb985c8c9-p7b5w_default_ef8acb63-8389-47d6-aad8-c2976eac3665_0
- @Node $ docker stop 057fc611f5c4
- 057fc611f5c4
- $ kubectl get pods -o wide
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- deployment-6bb985c8c9-p7b5w 1/1 Running 1 6m15s 10.0.102.47 ip-10-0-102-148.ap-northeast-1.compute.internal <none> <none>
- $ kubectl describe pod deployment-6bb985c8c9-p7b5w | grep 'Container ID'
- Container ID: docker://89f425cce426a87fad882cfc5f091b3f87dca4942bd5c9f9fbde69fc217ea476
コンテナを再起動したので Pod の RESTARTS が 0 から 1 に変わり、コンテナ ID も変わりました。
Node 上のログを確認します。
- # 旧コンテナ
- @Node $ ls -lh /var/lib/docker/containers/057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7/
- 合計 89M
- -rw-r----- 1 root root 2.6M 2月 16 15:01 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.1
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.2
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.3
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.4
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.5
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.6
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.7
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.8
- -rw-r----- 1 root root 9.6M 2月 16 14:59 057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log.9
- drwx------ 2 root root 6 2月 16 14:55 checkpoints
- -rw------- 1 root root 4.8K 2月 16 15:01 config.v2.json
- -rw-r--r-- 1 root root 2.1K 2月 16 15:01 hostconfig.json
- drwx--x--- 2 root root 6 2月 16 14:55 mounts
- # 新コンテナ
- @Node $ ls -lh /var/lib/docker/containers/89f425cce426a87fad882cfc5f091b3f87dca4942bd5c9f9fbde69fc217ea476/
- 合計 12K
- -rw-r----- 1 root root 0 2月 16 15:01 89f425cce426a87fad882cfc5f091b3f87dca4942bd5c9f9fbde69fc217ea476-json.log
- drwx------ 2 root root 6 2月 16 15:01 checkpoints
- -rw------- 1 root root 4.8K 2月 16 15:01 config.v2.json
- -rw-r--r-- 1 root root 2.1K 2月 16 15:01 hostconfig.json
- drwx--x--- 2 root root 6 2月 16 15:01 mounts
- @Node $ ls -lh /var/log/pods/default_deployment-6bb985c8c9-p7b5w_ef8acb63-8389-47d6-aad8-c2976eac3665/amazonlinux/
- 合計 0
- lrwxrwxrwx 1 root root 165 2月 16 14:55 0.log -> /var/lib/docker/containers/057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7/057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7-json.log
- lrwxrwxrwx 1 root root 165 2月 16 15:01 1.log -> /var/lib/docker/containers/89f425cce426a87fad882cfc5f091b3f87dca4942bd5c9f9fbde69fc217ea476/89f425cce426a87fad882cfc5f091b3f87dca4942bd5c9f9fbde69fc217ea476-json.log
旧コンテナ、新コンテナともにログが存在している事が確認できました。/var/log/pods
の方は 0.log
が旧コンテナにリンクし、1.log
が新コンテナにリンクしてます。
3.3.3. Pod 削除
上記の状態で Pod を削除してみます。
- $ kubectl delete pod deployment-6bb985c8c9-p7b5w
- pod "deployment-6bb985c8c9-p7b5w" deleted
- @Node $ ls -lh /var/lib/docker/containers/057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7/
- ls: /var/lib/docker/containers/057fc611f5c416c77a00cfb02e24714b52e75af0c14c42ed11c58d42ca115ea7/ にアクセスできません: No such file or directory
- @Node $ ls -lh /var/lib/docker/containers/89f425cce426a87fad882cfc5f091b3f87dca4942bd5c9f9fbde69fc217ea476/
- ls: /var/lib/docker/containers/89f425cce426a87fad882cfc5f091b3f87dca4942bd5c9f9fbde69fc217ea476/ にアクセスできません: No such file or directory
- @Node $ ls -lh /var/log/pods/default_deployment-6bb985c8c9-p7b5w_ef8acb63-8389-47d6-aad8-c2976eac3665/amazonlinux/
- 合計 0
Pod を削除するとログも全て消える事が確認できました。
3.4. 設定変更
最後に max-size/max-file
の変更方法です。
Node 上の /etc/docker/daemon.json
を修正して docker デーモンを再起動する事で設定変更が可能です。
Node 再作成時にも同様に設定されるように、カスタム起動テンプレートかカスタム AMI を使用する必要があります。
例えば、max-size
を 100m
、max-file
を 5
にしたい場合は、カスタム起動テンプレートのユーザデータに以下のようなコードを追加する事で設定変更が可能です。
- sed -i -e 's/"max-size".*/"max-size": "100m",/g' /etc/docker/daemon.json
- sed -i -e 's/"max-file".*/"max-file": "5"/g' /etc/docker/daemon.json
- systemctl restart docker
個人的には AWS マネージドという事は AWS が良かれと思って設計した値なのでユーザ側がカスタマイズする必要は無いと思っています。
4. まとめ
コンテナの標準出力/標準エラー出力ログまわりについて整理してみました。EKS 等のマネージドサービスの場合は特別な要件がない限り設定値は変更しなくて良いと思います。
5. 参考
Logging Architecture | Kubernetes
ロギング・ドライバの設定 — Docker-docs-ja 1.9.0b ドキュメント