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

What is the difference between docker and conta...

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/

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 ではフォーマットや分割されたログへの対応ができているかどうか、必要 かどうかの確認が必要