これは、なにをしたくて書いたもの?
Dockerコンテナ内で動作するNode.jsが認識するCPU数は、ホスト側のものになってしまうようなので、これを
メモしておこうかなと。
メモリについても同様のようですが、ヒープに限ってはコンテナ側の値を見てくれるようです。
情報元
Node.jsでは、Docker側の問題だとしているようです。
Feature request: os: os.availableProcessors() · Issue #28855 · nodejs/node · GitHub
確認してみましょう。
環境
確認環境。
$ docker version Client: Docker Engine - Community Version: 20.10.12 API version: 1.41 Go version: go1.16.12 Git commit: e91ed57 Built: Mon Dec 13 11:45:33 2021 OS/Arch: linux/amd64 Context: default Experimental: true Server: Docker Engine - Community Engine: Version: 20.10.12 API version: 1.41 (minimum version 1.12) Go version: go1.16.12 Git commit: 459d0df Built: Mon Dec 13 11:43:42 2021 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.4.12 GitCommit: 7b11cfaabd73bb80907dd23182b9347b4245eb5d runc: Version: 1.0.2 GitCommit: v1.0.2-0-g52b36a2 docker-init: Version: 0.19.0 GitCommit: de40ad0
ホスト側のCPU数。
$ grep ^processor /proc/cpuinfo processor : 0 processor : 1 processor : 2 processor : 3 processor : 4 processor : 5 processor : 6 processor : 7
ホスト側のメモリ。
$ head -n 1 /proc/meminfo MemTotal: 16306452 kB
確認してみる
確認してみましょう。Node.js 16.13.1を使い、コンテナには2つのCPUと2Gのメモリを割り当てました。
$ docker container run -it --rm --name node --cpus 2 --memory 2g node:16.13.1-bullseye node WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap. Welcome to Node.js v16.13.1. Type ".help" for more information. > require('os').cpus().length 8 > require('os').totalmem() 16697806848 >
確かに、ホスト側の情報が表示されます。
ヒープサイズについて
ヒープサイズ(--max-old-space-size
)に関していうと、Node.js 12.7.0以降であればコンテナ側の値を
参照してくれるようです。
2019-07-23, Version 12.7.0 (Current), @targos
src: use cgroups to get memory limits by kjin · Pull Request #27508 · nodejs/node · GitHub
libuvの対応を、Node.jsに反映したもの(/proc/meminfo
と/sys/fs/cgroup/memory/memory.limit_in_bytes
を比較して
小さい方を使う)みたいです。
Add uv_get_constrained_memory by kjin · Pull Request #2289 · libuv/libuv · GitHub
https://github.com/libuv/libuv/blob/v1.43.0/src/unix/linux-core.c#L819-L840
Javaだと
ちなみに、現在のJavaだとコンテナに割り当てたCPU数およびメモリサイズを認識します。
$ docker container run -it --rm --name openjdk --cpus 2 --memory 2g eclipse-temurin:17-jdk-focal jshell WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap. Jan 04, 2022 11:47:55 AM java.util.prefs.FileSystemPreferences$1 run INFO: Created user preferences directory. | Welcome to JShell -- Version 17.0.1 | For an introduction type: /help intro jshell> Runtime.getRuntime().availableProcessors() $1 ==> 2 jshell> ((com.sun.management.OperatingSystemMXBean)java.lang.management.ManagementFactory.getOperatingSystemMXBean()).getAvailableProcessors() $2 ==> 2 jshell> ((com.sun.management.OperatingSystemMXBean)java.lang.management.ManagementFactory.getOperatingSystemMXBean()).getTotalMemorySize() $3 ==> 2147483648
というか、コンテナ内の/proc/cpuinfo
や/proc/meminfo
はホスト側のものが表示されるので、ランタイム側が
cgroupへの対応を入れないとJavaのようにはなりません、と…。