New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
On Linux, os.count() should read cgroup cpu.shares and cpu.cfs (CPU count inside docker container) #80235
Comments
There appears to be no way to detect the number of CPUs allotted to a Python program within a docker container. With the following script: import os print("os.cpu_count(): " + str(os.cpu_count())) when run in a container (from an Ubuntu 18.04 host) I get: docker run -v "$PWD":/src/ -w /src/ --cpus=1 python:3.7 python detect_cpus.py Recent vesions of Java are able to correctly detect the CPU allocation: docker run -it --cpus 1 openjdk:10-jdk jshell> Runtime.getRuntime().availableProcessors() |
I would like to work on this issue. |
so, I have also tested with the last docker image of golang.
here is the code of golang: package main import "fmt" func main() { Here is the output
When I try with grep on /proc/cpuinfo
I will test with openjdk because it's related to Java and see if I can get the result of 1 |
ok, I didn't see your test with openjdk:10, sorry |
I believe this is related to this ticket: https://bugs.python.org/issue26692 Looking at Java's implementation it seems like they are checking if cgroups are enabled via /proc/self/cgroup and then if it is parsing the cgroup information out of the filesystem. |
I am really sorry but I thought to work on this issue but it's not the case. Feel free to submit a PR. |
I think that I may work on a PR for this issue. Is there anybody has worked on it ? |
Hi Manjusaka, Could you explain your solution, because I have read the code of Also, if you need my help for the review or for the construction of your Have a nice day, Stéphane |
Hi Stéphane Thanks a lot! In my opinion, I would like to make an independent library that name is cgroups. For ease of use and compatibility, I think it's better than combining code with the os module. Thanks for you working! Manjusaka |
Hi Stéphane: I have checked the JVM implantation about container improvements. I confirm that maybe we need a new Libary for container environment. I don't think that combine it into the os module is a good idea. I will make a PR during this week. |
The JVM parses cgroups information from the proc filesystem and evaluates CPU count from the cgroup cpu.shares and cpu.cfs. |
Yes, not only but also support get real memory limit. look at https://blogs.oracle.com/java-platform-group/java-se-support-for-docker-cpu-and-memory-limits |
Yep, but in this case, you have to create an other issue for the memory |
Is this issue still being worked on as a core feature? I needed a solution for this using 2.7.11 to enable some old code to work properly/nicely in a container environment on AWS Batch and was forced to figure out what OpenJDK was doing and came up with a solution. The process in OpenJDK seems to be, find where the cgroups for docker are located in the file system, then depending on the values in different files you can determine the number of CPUs available. The inelegant code below is what worked for me: def query_cpu():
if os.path.isfile('/sys/fs/cgroup/cpu/cpu.cfs_quota_us'):
cpu_quota = int(open('/sys/fs/cgroup/cpu/cpu.cfs_quota_us').read().rstrip())
#print(cpu_quota) # Not useful for AWS Batch based jobs as result is -1, but works on local linux systems
if cpu_quota != -1 and os.path.isfile('/sys/fs/cgroup/cpu/cpu.cfs_period_us'):
cpu_period = int(open('/sys/fs/cgroup/cpu/cpu.cfs_period_us').read().rstrip())
#print(cpu_period)
avail_cpu = int(cpu_quota / cpu_period) # Divide quota by period and you should get num of allotted CPU to the container, rounded down if fractional.
elif os.path.isfile('/sys/fs/cgroup/cpu/cpu.shares'):
cpu_shares = int(open('/sys/fs/cgroup/cpu/cpu.shares').read().rstrip())
#print(cpu_shares) # For AWS, gives correct value * 1024.
avail_cpu = int(cpu_shares / 1024)
return avail_cpu This solution makes several assumptions about the cgroup locations within the container vs dynamically finding where those files are located as OpenJDK does. I also haven't included the more robust method in case cpu.quota and cpu.shares are -1. Hopefully this is a start for getting this implemented. |
Hello Mike, thanks for your code. I think it's a good way I think if cpu.quota and cpu.shares are -1, just return the original value in os.cpu_count() is OK |
I will make a PR in this week |
I'm not sure that it's a good idea to change os.cpucount(). I suggest to add a new function instead. os.cpu_count() iss documented as: By the way, the documentation adds: "This number is not equivalent to the number of CPUs the current process can use. The number of usable CPUs can be obtained with len(os.sched_getaffinity(0))" |
I suggest that your provide a low solution that returns general information from cgroup v1 and unified cgroup v2 rather than a solution that focuses on CPU only. Then you can provide a high level interface that returns effective CPU cores. cgroup v2 (unified hierarchy) has been around for 6 years and slowly gains traction as container platforms start to support them. |
Actually, we already have some third party libs to support cgroup. But most of them get these questions
But if we want to add a new std lib. Should we create a PEP? |
Hello guys, I some ideas about this issue First, maybe we should add a new API named cpu_usable_count(). I think it's more meaningful than the os.sched_getaffinity(0) Second, more and more people use docker to run their app today. So people need an official way to get the environment info, not just cpu, but the memory, the network traffic limit. Because the docker is based on the CGroup in Linux, maybe we can add a cgroup lib as an official supported lib. but I'm not sure about this idea, because there are some problem.
|
Please try to find a more inclusive way to say hello: https://heyguys.cc/ ;-) |
Do we have any news about this? |
There is IBM effort to do this in container level, so that os.cpu_count() will return right result in container https://www.phoronix.com/scan.php?page=news_item&px=Linux-CPU-Namespace |
Good news! |
FYI, this solution was actually implemented in I fixed this for |
keirlawson mannequin commentedFeb 20, 2019
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: