Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What is the difference between docker and conta...

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

What is the difference between docker and containerd about logging?

Kubernetes 1.20 から Runtime としての Docker が非推奨となるが、containerd に変更した場合のロギング周りの違いについて紹介

3-shake SRE Tech Talk #2 での発表資料
https://3-shake.connpass.com/event/214041/

Avatar for Teraoka Yoshinori

Teraoka Yoshinori

June 29, 2021
Tweet

More Decks by Teraoka Yoshinori

Other Decks in Technology

Transcript

  1. © 2021 3-shake Inc. 2 自己紹介 - 所属 - Sreake

    事業部 - YAML 書いたり、HCL 書いたり - tcpdump したり - OSS に PullRequest 出したり - 木陰から若者を見守っています Yoshinori Teraoka (@yteraoka)
  2. © 2021 3-shake Inc. 3 目次 Kubernetes の Runtime が

    Docker から containerd に変わることによる ログ周りへの影響 • 出力先の変更とシンボリックリンク • ローテーションの担当変更 • ログフォーマットの変更 • GKE での Cloud Logging への転送
  3. © 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
  4. © 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
  5. © 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
  6. © 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 のログローテーション
  7. © 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)
  8. © 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)
  9. © 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 でのログローテーション
  10. © 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 でのログローテーション
  11. © 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 のログフォーマット
  12. © 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 のログフォーマット
  13. © 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 のログフォーマット
  14. © 2021 3-shake Inc. 21 かつては Fluentd に多くの処理を行わせていたが Fluent Bit

    には極力何もやらせたくない感じを受ける GKE ではどのようにして Cloud Logging に送っているか fluentbit-gke ログファイル Journald Tail と Parse だけ fluentbit-gke fluentbit-gke DaemonSet
  15. © 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 における特殊フィールド
  16. © 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 における特殊フィールド
  17. © 2021 3-shake Inc. 24 まとめ • GKE で標準の fluentbit-gke

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