🐥

Docker コンテナのメモリ使用量を合計する方法

に公開

はじめに

Docker や docker-compose で複数のコンテナを実行している場合、システムリソースの使用状況を監視することは重要です。特にメモリ使用量は、システムのパフォーマンスや安定性に直接影響します。

この記事では、実行中のすべての Docker コンテナのメモリ使用量を合計する方法について解説します。特に jq を使って GiB と MiB の両方の単位に対応した集計方法に焦点を当てます。

基本的なメモリ使用量の確認方法

まず、Docker コンテナのメモリ使用量を確認する基本的な方法からおさらいしましょう。

# すべてのコンテナのリアルタイム統計情報を表示
docker stats

# 特定のコンテナの統計情報を表示
docker stats コンテナ名1 コンテナ名2

# docker-compose で実行しているコンテナの統計情報を表示
docker-compose ps -q | xargs docker stats

docker stats コマンドは、CPU 使用率、メモリ使用量、ネットワーク I/O など、様々な情報を表示します。しかし、これだけでは合計値を確認することはできません。

メモリ使用量の合計値を計算する

jq を使った方法(GiB 単位対応)

jq は JSON データを処理するための強力なコマンドラインツールです。これを使用して、メモリ使用量の合計を計算することができます。特に、MiB と GiB の両方の単位に対応する方法を紹介します。

docker stats --no-stream --format '{"memory":"{{.MemUsage}}"}' | 
jq -s '[.[] | .memory | split(" / ")[0] | 
  if endswith("GiB") then (rtrimstr("GiB") | tonumber) * 1024
  elif endswith("MiB") then rtrimstr("MiB") | tonumber
  else 0 end] | add as $sum | 
  if $sum >= 1024 then "\($sum/1024 | floor * 100 / 100) GiB" 
  else "\($sum) MiB" end'

このコマンドの解説:

  1. docker stats --no-stream --format '{"memory":"{{.MemUsage}}"}'

    • --no-stream オプションでリアルタイム更新を無効にし、1回だけ情報を取得
    • --format オプションで出力形式を JSON 形式に指定
  2. jq での処理

    • .memory | split(" / ")[0] でメモリ使用量の部分だけを抽出(例: "123.4 MiB / 2 GiB" → "123.4 MiB")
    • if endswith("GiB") then ... で単位が GiB か MiB かを判断
    • GiB の場合は MiB に変換(× 1024)して合計
    • 最終的な合計値が 1024 MiB 以上の場合は GiB 単位で表示、それ以下の場合は MiB 単位で表示

このコマンドを実行すると、例えば以下のような出力が得られます:

2.35 GiB

または

756.5 MiB

より簡潔なバージョン

やや簡略化したバージョンも紹介しておきます:

docker stats --no-stream --format '{{.MemUsage}}' | 
jq -Rs '[split("\n")[:-1] | .[] | split(" / ")[0] | 
  if endswith("GiB") then (rtrimstr("GiB") | tonumber) * 1024
  elif endswith("MiB") then rtrimstr("MiB") | tonumber
  else 0 end] | add as $sum | 
  if $sum >= 1024 then "\($sum/1024 | floor * 100 / 100) GiB" 
  else "\($sum) MiB" end'

awk を使った代替方法

jq が利用できない環境では、awk を使った方法も有効です:

docker stats --no-stream --format "{{.MemUsage}}" | 
awk '{
    value=substr($1, 1, length($1)-3); 
    unit=substr($1, length($1)-2, 3); 
    if(unit=="GiB") 
        sum+=value*1024; 
    else if(unit=="MiB") 
        sum+=value; 
} 
END {
    if(sum>=1024) 
        printf "%.2f GiB\n", sum/1024; 
    else 
        printf "%.2f MiB\n", sum
}'

スクリプトとして保存する

これらのコマンドは長いので、スクリプトファイルとして保存しておくと便利です。以下に jq バージョンをスクリプト化した例を示します:

#!/bin/bash

# docker-memory-total.sh
docker stats --no-stream --format '{"memory":"{{.MemUsage}}"}' | 
jq -s '[.[] | .memory | split(" / ")[0] | 
  if endswith("GiB") then (rtrimstr("GiB") | tonumber) * 1024
  elif endswith("MiB") then rtrimstr("MiB") | tonumber
  else 0 end] | add as $sum | 
  if $sum >= 1024 then "\($sum/1024 | floor * 100 / 100) GiB" 
  else "\($sum) MiB" end'

実行権限を付与して使用します:

chmod +x docker-memory-total.sh
./docker-memory-total.sh

特定のプロジェクトのコンテナのみ集計する

docker-compose プロジェクト内のコンテナだけを対象にする場合は、以下のようにします:

docker-compose ps -q | xargs docker stats --no-stream --format '{"memory":"{{.MemUsage}}"}' | 
jq -s '[.[] | .memory | split(" / ")[0] | 
  if endswith("GiB") then (rtrimstr("GiB") | tonumber) * 1024
  elif endswith("MiB") then rtrimstr("MiB") | tonumber
  else 0 end] | add as $sum | 
  if $sum >= 1024 then "\($sum/1024 | floor * 100 / 100) GiB" 
  else "\($sum) MiB" end'

まとめ

Docker コンテナのメモリ使用量を合計する方法を紹介しました。特に jq を使った方法は、GiB と MiB の両方の単位に適切に対応できるため、大規模な環境でも正確な合計値を取得できます。

環境やニーズに応じて、これらのコマンドをカスタマイズして活用してください。定期的なモニタリングスクリプトの一部として組み込むことで、システムリソースの管理が容易になります。

参考リンク

Discussion