'How many CPUs does my docker container have?

I'm writing a library that operates in parallel. This library is often used within docker containers. I would like to start as many threads as my docker container has allocated cores.

Does docker set the CPUs limit somewhere as an environment variable?

For example if my user sets two CPUs when creating the container:

docker run --cpuset-cpus="2" myapp:latest

(see this question)

How do I get back the number 2 from within the container by inspecting the container's state?



Solution 1:[1]

With --cpuset-cpus="2" you actually use 1 cpu. For example, if you have 4 available: {0,1,2,3} you have to specify 2 of them by separating them with comma or by defining a range. From the docs:

--cpuset-cpus

Limit the specific CPUs or cores a container can use. A comma-separated list or hyphen-separated range of CPUs a container can use, if you have more than one CPU. The first CPU is numbered 0. A valid value might be 0-3 (to use the first, second, third, and fourth CPU) or 1,3 (to use the second and fourth CPU).

Answer:

  • To get the number of processing units available: nproc
  • To get the cpu set: /sys/fs/cgroup/cpuset/cpuset.cpus

small example follows:

  1. host:

    $ nproc
    4
    
  2. container with 1 cpu:

    $ docker run --rm -it --cpuset-cpus="2" ubuntu
    root@73844de506db:/# nproc
    1
    root@73844de506db:/# cat /sys/fs/cgroup/cpuset/cpuset.cpus
    2
    
  3. container with 3 cpus:

    $ docker run --rm -it --cpuset-cpus="0-2" ubuntu
    root@4c3f841e613b:/# nproc
    3
    root@4c3f841e613b:/# cat /sys/fs/cgroup/cpuset/cpuset.cpus
    0-2
    

Solution 2:[2]

Docker containers, by design, are isolated from the underlying host system, so you shouldn't be able to ask Docker "how many CPU cores do I have".

Using /proc/cpuinfo doesn't seem to work for me, it always tells me 1 cpu from within the container.

Looking at this issue on Github describes the journey to figure it out in a roundabout way. Ultimately, this method looks at the cgroup to determine which cores are available, and I think that would work for you:

cat /sys/fs/cgroup/cpuset/cpuset.cpus

Solution 3:[3]

Files such as /proc/cpuinfo, /proc/meminfo, etc. are not namespaced. In containers, the best way would be to check /sys/fs/cgroup/cpuset/cpuset.cpus for the available CPU's

Solution 4:[4]

If you need to get number of processors from .Net application, you can call

Environment.ProcessorCount

From https://blog.markvincze.com/troubleshooting-high-memory-usage-with-asp-net-core-on-kubernetes/ :

On my machine, just doing dotnet run, the value was 4.
On my machine, with Docker, it was 1.
On Google Cloud Kubernetes it was 8.

Solution 5:[5]

within a container you can run the following shell command to parse a simple range (?-?) cpuset :

awk -F "0-" '{print 1+$NF }' /sys/fs/cgroup/cpuset/cpuset.cpus 2>/dev/null || echo 1

Solution 6:[6]

if you're going with nproc, here's a quick one-liner to format the docker syntax while querying the core count :

mawk 'BEGIN { 

    printf("docker run --rm -it --cpuset-cpus=%c0-%.f%c ubuntu%c",
                                       39, 
           system("exit \140nproc\140")-1, 
                                       39, 12) }' 

docker run --rm -it --cpuset-cpus='0-9' ubuntu

This shortcut code works unless you have more than 255 cores in your uber-powerful system.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 bluescores
Solution 3 Ricardo Branco
Solution 4 Michael Freidgeim
Solution 5 Julien Laurenceau
Solution 6 RARE Kpop Manifesto