[自分用メモ][docker][container] docker composeでメモリ制限を行う方法

2019-04-19 17:58:26AIX、UNIX、Linux, Containercompose, container, docker, limit, mem_limit, memory, メモリ, 制限

Screenshot_2019-04-19 Docker Compose — Memory Limits – Linux Hint

もう最近は何でもDockerを始めとしたcontainerに頼ることも多くなりましたが、リソースの制限を使用と思った時、docker composeを使用していると実は色々と条件があったらしいのでメモ。

確認環境:

$ docker version
Client:
 Version:           18.09.5
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        e8ff056
 Built:             Thu Apr 11 04:48:27 2019
 OS/Arch:           linux/arm64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.5
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.8
  Git commit:       e8ff056
  Built:            Thu Apr 11 04:11:17 2019
  OS/Arch:          linux/arm64
  Experimental:     true

まず最初にdockerで何も設定しない場合には基本的にホストのリソース使用に関する制限はありません。なのである分だけ使用します。

で、メモリを制限する場合、docker composeを使用するときでも、formatバージョンによって記述方法が違います。

まずはCompose file version 2の場合、

version: "2.4"
services:

  pdns_rec:
    image: kometchtech/pdnsrec:latest
    labels:
      private.kometch.job: "rec"
    ports:
      - 9953:53/udp
    volumes:
      - ${PWD}/powerdns:/etc/powerdns
    command: ["pdns_recursor", "--disable-syslog", "--log-timestamp=yes", "--daemon=no", "--write-pid=no"]
    restart: "always"
    mem_limit: 2g

最後の行にあるmem_limitがそれにあたります。指定する値については、byte単位でも、Gなどのように単位を付けても認識されます。

で、問題はCompose file version 3の場合です。

一応、deploy > resources という項目が用意されているのですが、公式ドキュメントにも書いてある通り、docker swarmで使用されることが前提の設定項目になります。

Specify configuration related to the deployment and running of services. This only takes effect when deploying to a swarm with docker stack deploy, and is ignored by docker-compose up and docker-compose run.

docker-compose.ymlversion 3に変更して実行してみます。

$ docker-compose up -d pdnsrec
ERROR: The Compose file './docker-compose.yml' is invalid because:
Unsupported config option for services.pdns_rec: 'mem_limit'

はい、ダメでした。

んじゃ、どうしてもdocker compose v3を使用しないといけない時のリソース制限はどうするんじゃいと思ったら、同じように思ってた方がいらっしゃいまして、

https://reboooot.net/post/how-to-specify-mem-limit-on-docker/docker-composeコマンドに–compatibilityというオプションが用意されてるらしい。
$ docker-compose --help
Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
  docker-compose -h|--help

Options:
  -f, --file FILE             Specify an alternate compose file
                              (default: docker-compose.yml)
  -p, --project-name NAME     Specify an alternate project name
                              (default: directory name)
  --verbose                   Show more output
  --log-level LEVEL           Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  --no-ansi                   Do not print ANSI control characters
  -v, --version               Print version and exit
  -H, --host HOST             Daemon socket to connect to

  --tls                       Use TLS; implied by --tlsverify
  --tlscacert CA_PATH         Trust certs signed only by this CA
  --tlscert CLIENT_CERT_PATH  Path to TLS certificate file
  --tlskey TLS_KEY_PATH       Path to TLS key file
  --tlsverify                 Use TLS and verify the remote
  --skip-hostname-check       Don't check the daemon's hostname against the
                              name specified in the client certificate
  --project-directory PATH    Specify an alternate working directory
                              (default: the path of the Compose file)
  --compatibility             If set, Compose will attempt to convert keys
                              in v3 files to their non-Swarm equivalent

説明文まんまですね。

docker-compose.ymlは以下のように編集します。

version: "3"
services:

  pdns_rec:
    image: kometchtech/pdnsrec:latest
    labels:
      private.kometch.job: "rec"
    ports:
      - 9953:53/udp
    volumes:
      - ${PWD}/powerdns:/etc/powerdns
    command: ["pdns_recursor", "--disable-syslog", "--log-timestamp=yes", "--daemon=no", "--write-pid=no"]
    restart: "always"
    deploy:
      resources:
        limits:
          memory: 2g

では--compatibilityを付けて実行します。

$ docker stats --no-stream docker-env_pdns_rec_1
CONTAINER ID        NAME                    CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
36c4be8c2a31        docker-env_pdns_rec_1   0.19%               10.52MiB / 2GiB     0.51%               2.81MB / 3.91MB     94.2kB / 0B         7

2GBで制限されています。これでとりあえずは使えそうです。
と思いきや公式ドキュメントでは非推奨になっているので、どうしても使用したい場合に限った方が良さそうです。

CAUTION

Do not use this in production!

We recommend against using --compatibility mode in production. Because the resulting configuration is only an approximate using non-Swarm mode properties, it may produce unexpected results.

POINT

むやみやたらに最新のフォーマットバージョンでdocker-composeするのではなく、適宜自分が設定したい条件に合わせて記述するようにしましょう。

この記事を書いた人

kometchtech

うつ病を患いながら、IT業界の末席にいるおっさんエンジニア。科学計算をしたことがないのに、HPC分野にお邪魔している。

興味のある分野で学習したことをblogにまとめつつ、うつ病の経過症状のメモも置いておく日々。

じつはRouterboard User Group JPの中の人でもある。

Amazon欲しいものリスト / Arm板を恵んでくれる人募集中