DUICUO

プログラマーが Docker ログによってどのように騙されるかをご覧ください。

[[426544]]

最近、「コンピュータ プログラムの構造と解釈」という本を読んでいるのですが、その中に「コードは人間が読めるものでなければならないが、たまたま機械が実行できるものでなければならない」という一文があります。

また、次のような格言も思いつきました。「バグは常に誰かが書くものであり、たまたま私がたくさん書いているというだけである。」

話せば長くなるので、ここでは苦い経験だけをお話しします。最近遭遇した問題についてお話ししましょう。

質問

ある日、私は普通のコンピューターを起動し、普通のサーバーにログインし、普通のコマンドを入力しました。

コマンド補完を使用すると、異常なメッセージが表示されました。

  1. -bash:作成できません ヒアドキュメント一時ファイル:いいえ 空間  デバイス上でls -bash

ディスクがいっぱいなのはなぜですか?

`df -h` を使用してそれが真実であることが確認されました。

理由は何でしょう?

解決する

まず、システム内の大きなファイルをチェックして、その背後にどんな小さな悪魔がいるのかを確認します。

  1. du -sh /* | grep G

ディレクトリはすぐに見つかりました: /var/lib/docker/containers。

どうやらDockerのようです。このディレクトリにはコンテナ操作中に生成されたログが含まれています。

これらのファイルをサイズ順に並べ替えるには、次のコマンドを使用します。

  1. du -d1 -h /var/lib/docker/containers |ソート -h
  2.  
  3. 32K /var/lib/docker/コンテナ/d607c06e475191fff1abd0c2b4b672e7fe8a96cb197f4e8557b18600de2e60af
  4. 36K /var/lib/docker/コンテナ/0d4321106721b9d26335fefef7b9e8e23629691684a4da2f953ac8223c8240c3
  5. 36K /var/lib/docker/containers/7525aab4aa917aa1016169114762261726ac7b9cc712bef35cdc7035b50d20ce
  6. 36K /var/lib/docker/containers/9252e1c373d59ef5613c2b6122eb6e43aa2bd822bd2c199aa67d6eb659c4adb7
  7. 142M /var/lib/docker/コンテナ
  8. 142M /var/lib/docker/コンテナ/15700ee92cd2831554b9a1e78127df0f07248c1498d35c17525407bc8a98bc1a

ファイル名はコンテナIDです。各ファイルはコンテナに対応しており、大量のログを生成したコンテナを特定できます。

このコマンドを使用すると、大きなファイルをすばやく空にすることができます。

  1. sh -c "cat /dev/null > ${log_file_name}"  

しかし、ファイルを単に消去するだけでは問題は解決しません。新しいログエントリが継続的に追加され続けているのです。ログの内容を見ると、見覚えのある内容でした。数日前にプログラムのデバッグのために、このprint文を追加したばかりだったのです。

コードを編集し、`print` ステートメントを削除してコンテナを再起動します。これで、ログが無差別に追加されなくなります。

なぜ print ステートメントはログをファイルに出力するのでしょうか? 心配しないでください。後で詳しく説明します。

まずは差し迫った問題に対処しましょう。ログを無制限に大きくし続けるのは絶対に避けるべきです。個々のファイルのサイズに制限を設ける必要があります。そうしないと、Zhang Sanが明日またprint文を追加した途端、ディスクが再びいっぱいになってしまいます。

次の 2 つのオプションがあります。

  1. 単一コンテナ構成
  2. グローバル構成

単一コンテナ構成

コンテナを起動するときに、パラメータを使用してログ ファイルの数と各ファイルのサイズを制御できます。

  1. docker run -it --log-opt 最大サイズ=10m --log-opt 最大ファイル=3 redis  

ただし、これはかなり面倒なので、グローバル構成アプローチがより一般的に使用されます。

グローバル構成

/etc/docker/daemon.json を編集します。

  1. {
  2. 「ログドライバー」 : 「jsonファイル」
  3. 「ログオプション」 :{
  4. 「最大サイズ」 : 「50m
  5. 「最大ファイル数」 : 「3」  
  6. }
  7. }

Docker サービスを再起動します。

  1. systemctlデーモンリロード
  2. systemctl で docker を再起動します。

注意: 既存のコンテナは動作しません。再構築する必要があります。

次に、前述の印刷の問題についてお話しします。

Dockerログ

Docker ログは 2 つのカテゴリに分けられます。

  • Docker エンジン ログ (つまり、dockerd 実行時に生成されるログ)
  • コンテナ ログ、コンテナ内のサービスによって生成されるログ。

エンジンログ

Dockerエンジンのログは通常、Upstart(Ubuntu 14.04)またはsystemd(CentOS 7、Ubuntu 16.04)によって処理されます。前者は通常/var/log/upstart/docker.logに保存され、後者は通常journalctl -u dockerで確認できます。

場所はシステムによって異なります。オンラインで誰かがリストをまとめてくれたので、少し修正しましたので、以下をご覧ください。

コンテナログ

次のコマンドを使用して、現在実行中のコンテナのログ情報を表示できます。

  1. docker ログコンテナ

UNIXおよびLinuxコマンドには、STDIN、STDOUT、STDERRの3つの入出力方法があります。dockerログの出力には、STDOUTとSTDERRの両方が含まれます。

実稼働環境では、アプリケーションがログ ファイルに出力する場合、通常、docker ログを使用しても重要な情報をあまり収集できません。

nginx と httpd がどのようにそれを実行するかを見てみましょう。

  • 公式 nginx ミラーは、ログを STDOUT に出力する方法を使用しており、これには /dev/stdout へのシンボリック リンク /var/log/nginx/access.log の作成が含まれます。
  • httpd は指定されたファイルへの出力に使用されます。通常のログは /proc/self/fd/1 (STDOUT) に出力され、エラー ログは /proc/self/fd/2 (STDERR) に出力されます。

ログの量が多い場合、docker logs を使用してログを表示すると、docker デーモンに大きな負担がかかり、コンテナの作成が遅くなるなどの一連の問題が簡単に発生する可能性があります。

ローカル、json-file、または journald ログ ドライバーを使用するコンテナーのみが docker ログを使用してログをキャプチャできます。他のログ ドライバーを使用するコンテナーは docker ログを使用できません。

Docker はデフォルトのログ ドライバーとして json-file を使用します。

これらに加えて、Docker は他にも多くのログドライバを提供していますが、ここでは詳しくは触れません。ログ管理ソリューションもいくつかありますが、私はあまり経験がありません。興味があればご自身で調べてみてください。