diff --git a/CHANGELOG.md b/CHANGELOG.md index 0822ee9c8..0321171e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Added + +- Detect number of CPU shares when running on Cgroups V2 [PR #1410](https://github.com/3scale/apicast/pull/1410) [THREESCALE-10167](https://issues.redhat.com/browse/THREESCALE-10167) + ## [3.14.0] 2023-07-25 ### Fixed diff --git a/gateway/src/apicast/cli/environment.lua b/gateway/src/apicast/cli/environment.lua index b208ba152..4b201f28a 100644 --- a/gateway/src/apicast/cli/environment.lua +++ b/gateway/src/apicast/cli/environment.lua @@ -43,24 +43,35 @@ local function parse_nameservers() end end -local function detect_kubernetes() - local secrets = open('/run/secrets/kubernetes.io') +-- CPU shares in Cgroups v1 or converted from weight in Cgroups v2 in millicores +local function cpu_shares() + local shares - if secrets then secrets:close() end + -- This check is from https://github.com/kubernetes/kubernetes/blob/release-1.27/test/e2e/node/pod_resize.go#L305-L314 + -- alternatively, this method can be used: https://kubernetes.io/docs/concepts/architecture/cgroups/#check-cgroup-version + -- (`stat -fc %T /sys/fs/cgroup/` returns `cgroup2fs` or `tmpfs`) + if pl_path.exists("/sys/fs/cgroup/cgroup.controllers") then + -- Cgroups v2 + ngx.log(ngx.DEBUG, "detecting cpus in Cgroups v2") + -- Using the formula from https://github.com/kubernetes/kubernetes/blob/release-1.27/pkg/kubelet/cm/cgroup_manager_linux.go#L570-L574 + local file = open('/sys/fs/cgroup/cpu.weight') - return secrets or resty_env.value('KUBERNETES_PORT') -end - -local function cpu_shares() - if not detect_kubernetes() then return end + if file then + local weight = file:read('*n') + file:close() - local shares - local file = open('/sys/fs/cgroup/cpu/cpu.shares') + shares = (((weight - 1) * 262142) / 9999) + 2 + end + else + -- Cgroups v1 + ngx.log(ngx.DEBUG, "detecting cpus in Cgroups v1") + local file = open('/sys/fs/cgroup/cpu/cpu.shares') - if file then - shares = file:read('*n') + if file then + shares = file:read('*n') - file:close() + file:close() + end end return shares @@ -68,11 +79,16 @@ end local function cpus() local shares = cpu_shares() - if shares then return ceil(shares / 1024) end + if shares then + local res = ceil(shares / 1024) + ngx.log(ngx.DEBUG, "cpu_shares = "..res) + return res + end -- TODO: support /sys/fs/cgroup/cpuset/cpuset.cpus -- see https://github.com/sclorg/rhscl-dockerfiles/blob/ff912d8764af9a41096e63064bbc325395afa608/rhel7.sti-base/bin/cgroup-limits#L55-L75 local nproc = util.system('nproc') + ngx.log(ngx.DEBUG, "cpus from nproc = "..nproc) return tonumber(nproc) end