総Dockerリソースを制限する方法は?

総Dockerリソースを制限する方法は?

Dockerがアクセスできるリソースの合計を制限したい(たとえば、RAMの90%とCPUの1500%のみ)。コンテナの起動時にCPUとRAMの制限が利用できないため、Dockerコンテナで利用可能なリソースの合計を制限する必要があります。

最大CPUとメモリを使用できますが、同時には使用できない約20個のコンテナがあるため、CPUとRAMの制限を設定できないため、dockerが使用するリソースの合計を制限する必要があります。

まずスライスを作りました。上記の手順を試しましたが、RAMとCPU使用量を同時に制限することはできませんでした。

# /etc/systemd/system/docker_limit.slice
[Unit]
Description=Slice that limits docker resources
Before=slices.target

[Slice]
CPUAccounting=true
CPUQuota=700%
#Memory Management
MemoryAccounting=true
MemoryHigh=20G
MemoryMax=25G
MemoryMaxSwap=10G

そして私のdaemon.json

{
  "insecure-registries" : [ "url1", "url2"],
  "cgroup-parent": "docker_limit.slice"
}

しかし、コンテナで試してみると、次のようになります。

stress --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1

Docker統計を見ると、111GoのRam(私のサーバーのフル容量)を使用していることがわかります。

stress --cpu 16

Docker統計を見ると、使用量が1600%(私のサーバーの総容量)に近いことがわかります。

何か欠けているようですが、何かわかりません。

答え1

この質問に対する完全な回答が必要な他の人のために完全なレビューを行っています。

まず、docker_limitというスライスを作成しました。

  1. ファイルを作成して/etc/systemd/system/docker_limit.slice

    [Unit]
    Description=Slice that limits docker resources
    Before=slices.target
    
    [Slice]
    CPUAccounting=true
    CPUQuota=700%
    #Memory Management
    MemoryAccounting=true
    MemoryLimit=25G
    
  2. 起動装置:systemctl start docker_limit.slice

  3. 編集する/etc/docker/daemon.json

    {
      "cgroup-parent": "docker_limit.slice"
    }
    
  4. Dockerデーモンを再起動します。systemctl restart docker

すべてが期待どおりに機能していることを確認するには、systemd-cgtop以下のプロセスを確認する必要がありますdocker_limit.slice。たとえば、 ここに画像の説明を入力してください。

@rwosのクレジット

答え2

cgroup_parentcgroup 名前が絶対になるように/etc/docker/daemon.json接頭辞を付けます。/それ以外の場合、dockerはコンテナをデーモンcgroupの子cgroupに配置します。

{
    "cgroup-parent": "/docker_limit.slice"
}

そうでない場合、/システムによってはコンテナが/system.slice/containerd.service/docker_limit.slice同様の状況に遭遇する可能性があります。

systemd-cgtopあるいは、systemd-cglsジョブが終了する場所を確認するために使用できます。

答え3

CPU 1個とRAM 2GB(スワップ無効)を備えた仮想マシンがあります。
そのため、次のパラメータを使用してスライスを作成しました。

# cat /etc/systemd/system/docker_limit.slice
[Unit]
Description=Slice that limits docker resources
Before=slices.target

[Slice]
CPUAccounting=true
CPUQuota=90%
MemoryAccounting=true
MemoryHigh=1G
MemoryMax=1.2G

デーモンのデフォルトのcgroupdriverを除いて、あなたと同じことをしました。

# cat /etc/docker/daemon.json 
{
    "exec-opts": ["native.cgroupdriver=systemd"],
    "cgroup-parent": "docker_limit.slice"
}

次にDockerコンテナを実行します。

docker run --name stress-test -d ubuntu:18.04 sleep 10000

2つのウィンドウで自分の仮想マシンを開きます。最初のウィンドウでstress。 2番目のウィンドウでは、docker stats commandCPUは約90%+ -でした(htopで確認しましたが、91%まで上昇したことを確認しました)。 RAMが1.2Gに達すると、次のメッセージでプロセスが終了しました。

# stress --cpu 1 --vm 1 --vm-bytes 1300M
stress: info: [334] dispatching hogs: 1 cpu, 0 io, 1 vm, 0 hdd
stress: FAIL: [334] (415) <-- worker 336 got signal 9
stress: WARN: [334] (417) now reaping child worker processes
stress: FAIL: [334] (451) failed run completed in 4s

答え4

rwosの上記の提案(残念ながら投稿に直接コメントすることはできません)は私には適していません。

/etc/docker/daemon.json で cgroup_parent プレフィックスに / を付けて cgroup 名が絶対になるようにします。

次のエラーが発生します。

デーモンのエラー応答: コンテナーのジョブを生成できません: shim ジョブを生成できません: OCI ランタイム生成失敗: runc 生成失敗: 無効なスライス名: /docker_limit.slice: 不明

私のドッカーコンテナは "/"プレフィックスなしで起動します。それではそうではありません。

関連情報