Slide 1

Slide 1 text

Docker と containerd の違い - コンテナログ編 3-shake SRE Tech Talk #2 / 2021-06-29

Slide 2

Slide 2 text

© 2021 3-shake Inc. 2 自己紹介 - 所属 - Sreake 事業部 - YAML 書いたり、HCL 書いたり - tcpdump したり - OSS に PullRequest 出したり - 木陰から若者を見守っています Yoshinori Teraoka (@yteraoka)

Slide 3

Slide 3 text

© 2021 3-shake Inc. 3 目次 Kubernetes の Runtime が Docker から containerd に変わることによる ログ周りへの影響 ● 出力先の変更とシンボリックリンク ● ローテーションの担当変更 ● ログフォーマットの変更 ● GKE での Cloud Logging への転送

Slide 4

Slide 4 text

© 2021 3-shake Inc. 4 出力先の変更とシンボリックリンク

Slide 5

Slide 5 text

© 2021 3-shake Inc. 5 出力先の変更とシンボリックリンク ※ Log Driver によって異なりますが json-file 前提です /var/lib/containers 配下に CONTAINER_ID のディレクトリがあり、 CONTAINER_ID-json.log というファイルにログが出力される /var/lib/containers/ffd16c..4bbce6/ffd16c..4bbce6-json.log
 
 Docker

Slide 6

Slide 6 text

© 2021 3-shake Inc. 6 出力先の変更とシンボリックリンク /var/log/containers/nginx-1-754ddbcd6c-5tqgd_default_nginx-1-7888a2..acab96.log ↓ /var/log/pods/default_nginx-1-754ddbcd6c-5tqgd_5ee88da6-2fd9-49ba-9d63-c1196abce6 3f/nginx-1/0.log ↓ /var/lib/docker/containers/7888a2..acab96/7888a2..acab96-json.log Fluentd や FluentBit は /var/log/containers にあるシンボリックリンクとそのリンク先 を watch しています。リンクの名前から Pod を識別し、さらに filter で Kubernetes の API サーバーから label や annotation などを補完します。 Docker PodName Namespace ContainerName ContainerID PodUID

Slide 7

Slide 7 text

© 2021 3-shake Inc. 7 出力先の変更とシンボリックリンク /var/log/containers/nginx-1-754ddbcd6c-5tqgd_default_nginx-1-7888a2..acab96.log ↓ /var/log/pods/default_nginx-1-754ddbcd6c-5tqgd_5ee88da6-2fd9-49ba-9d63-c1196abce6 3f/nginx-1/0.log ↓ /var/lib/docker/containers/7888a2..acab96/7888a2..acab96-json.log コンテナのリスタートが行われる度に、中間層の 0.log が 1.log, 2.log と切り替わり、 現在のコンテナと一つ前のコンテナのものが維持される。 kubectl logs の --previous が機能するのはこのため。 Docker PodName Namespace ContainerName ContainerID PodUID

Slide 8

Slide 8 text

© 2021 3-shake Inc. 8 出力先の変更とシンボリックリンク Docker の場合の中間にあったシンボリックリンクの場所に出力される。 つまり、 /var/log/pods/NamespaceName_PodName_PodUID/ContainerName/0.log である。Docker の場合と同様に 0.log はコンテナが restart される度に 1.log, 2.log という名前になる。 containerd

Slide 9

Slide 9 text

© 2021 3-shake Inc. 9 出力先の変更とシンボリックリンク /var/log/containers/nginx-1-754ddbcd6c-mmzls_default_nginx-1-2de50eb987c16508cfac e3c390cf1cd220b995e981197d0d79379fd9ec04a3ac.log ↓ /var/log/pods/default_nginx-1-754ddbcd6c-mmzls_2a2b3e2a-77bc-4227-993e-4131b9d0ff a5/nginx-1/0.log containerd

Slide 10

Slide 10 text

© 2021 3-shake Inc. 10 ローテーションの担当変更

Slide 11

Slide 11 text

© 2021 3-shake Inc. 11 ローテーションの担当変更 ログ出力先ディレクトリ内で .1, .2 という suffix をつける形でローテーションされる。 この設定は /etc/docker/daemon.json やコマンドラインオプションで指定が可能。 { “log-driver”: “json-file”, “log-opts”: { “max-size”: “10m”, “max-file”: “5” } } Docker のログローテーション

Slide 12

Slide 12 text

© 2021 3-shake Inc. 12 ローテーションの担当変更 GKE では docker のコマンドラインオプションで次のように指定されている。 (/etc/default/docker) --log-driver=json-file --log-opt=max-size=10m --log-opt=max-file=5 max-file=5 の場合、出力中のファイル + 4 (.1, .2, .3. .4) となる。 Docker のログローテーション (GKE)

Slide 13

Slide 13 text

© 2021 3-shake Inc. 13 ローテーションの担当変更 EKS の AMI (amazon-eks-node-1.19-v20210621) では /etc/docker/daemon.json で次のように指定されている。 "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "10" } Docker のログローテーション (EKS)

Slide 14

Slide 14 text

© 2021 3-shake Inc. 14 ローテーションの担当変更 CRI コンテナランタイムの場合、ログローテーションを司るのは kubelet になり、 --container-log-max-size と --container-log-max-files で指定可能。デフォルト 設定は 10Mi と 5 となっている。 GKE (COS_CONTAINERD) と EKS (Bottlerocket 1.1.2) はともにデフォルトのま まであった。 https://kubernetes.io/docs/concepts/cluster-administration/logging/ containerd でのログローテーション

Slide 15

Slide 15 text

© 2021 3-shake Inc. 15 containerd でどう変わるか Docker とは異なり、ローテーションされたファイルの suffix には時刻がつき、さらに2 つ前以前は圧縮される。 395679 -rw-r----- 1 root root 3.1M May 4 16:12 0.log 395683 -rw-r--r-- 1 root root 525K May 4 16:06 0.log.20210504-160355.gz 395684 -rw-r--r-- 1 root root 539K May 4 16:08 0.log.20210504-160636.gz 395685 -rw-r--r-- 1 root root 526K May 4 16:11 0.log.20210504-160856.gz 395669 -rw-r----- 1 root root 11M May 4 16:11 0.log.20210504-161116 定期的に監視して超えていたらローテーションや掃除を行う。 containerd でのログローテーション

Slide 16

Slide 16 text

© 2021 3-shake Inc. 16 ログフォーマットの変更

Slide 17

Slide 17 text

© 2021 3-shake Inc. 17 ログフォーマットの変更 ファイル名に json と入っているように JSON Lines である {“log”:”message\n”,”stream”:”stdout”,”time”:”2021-06-03T06:17:48.767680017Z”} Docker では1行が 16KiB を超える場合に複数行に分割される。 log フィールドの最後が \n でない場合は、\n で終わる行までを連結する ことで元の1行を復元することができる。 Docker のログフォーマット

Slide 18

Slide 18 text

© 2021 3-shake Inc. 18 ログフォーマットの変更 Docker とは異なり、JSON ではない(毎行 JSON にするのはコストが高過ぎるらし い) 2021-05-04T15:54:06.575226579Z stdout F some log message 時刻、stdout|stderr、F|P、テキストがスペース区切りとなっています。 F と P は Full と Partial 由来だが、行を buffer size まで読み込んだ最後が \n だっ た場合が F でそうでなかった場合が P となっている。 P だったら次の F までを結合することで元の1行となる。 containerd のログフォーマット

Slide 19

Slide 19 text

© 2021 3-shake Inc. 19 ログフォーマットの変更 行を分割する buffer size のデフォルトは 16KiB で、max_container_log_line_size という設定で変更することができる -1 は無制限 GKE ではこの値が 256KiB となっており、Cloud Logging の 1 イベントのサイズ上 限と合わせてあるっぽく。連結する必要がない(しても Cloud Logging に受け入れら れない可能性が高い)。 EKS (Bottlerocket 1.1.2) はデフォルトのままで Docker と同じ 16KiB だった。 containerd のログフォーマット

Slide 20

Slide 20 text

© 2021 3-shake Inc. 20 GKE での Cloud Logging への転送

Slide 21

Slide 21 text

© 2021 3-shake Inc. 21 かつては Fluentd に多くの処理を行わせていたが Fluent Bit には極力何もやらせたくない感じを受ける GKE ではどのようにして Cloud Logging に送っているか fluentbit-gke ログファイル Journald Tail と Parse だけ fluentbit-gke fluentbit-gke DaemonSet

Slide 22

Slide 22 text

© 2021 3-shake Inc. 22 GKE ではどのようにして Cloud Logging に送っているか JSON 型式のログを Cloud Logging に送る場合、一部のフィールドが特殊な意味を 持つため、その値には注意が必要。 time, timestamp などはドキュメントにあるフォーマットに合わせておかないとまるっと 捨てられる可能性がある。 https://cloud.google.com/logging/docs/agent/logging/configuration?hl=ja#timestamp-processing Cloud Logging における特殊フィールド

Slide 23

Slide 23 text

© 2021 3-shake Inc. 23 GKE ではどのようにして Cloud Logging に送っているか ログレベルは severity フィールドを使用することで Cloud Logging をより便利に活 用できる。severity がない場合、stderr への出力は全て ERROR レベルとして扱わ れて監視の際のノイズになることがある。 他のフィールドについてもドキュメントを参照。 https://cloud.google.com/logging/docs/agent/logging/configuration?hl=ja#special-fields Cloud Logging における特殊フィールド

Slide 24

Slide 24 text

© 2021 3-shake Inc. 24 まとめ ● GKE で標準の fluentbit-gke を使用している場合は、JSON の特殊フィールド について意識しておけば問題はない ● ログの圧縮が有効となるため、ストレージ容量は減るが、圧縮のための CPU は必要 ● EKS ではフォーマットや分割されたログへの対応ができているかどうか、必要 かどうかの確認が必要