Skip to content

THREESCALE-15465 refactor: use new cpu.requests formula from Kubernetes#1595

Open
tkan145 wants to merge 1 commit into
3scale:masterfrom
tkan145:update-cpus-share-formula
Open

THREESCALE-15465 refactor: use new cpu.requests formula from Kubernetes#1595
tkan145 wants to merge 1 commit into
3scale:masterfrom
tkan145:update-cpus-share-formula

Conversation

@tkan145

@tkan145 tkan145 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

What

https://redhat.atlassian.net/browse/THREESCALE-15465

Recently reported by support team that APIcast run with a wrong number of workers. From this blog New Conversion from cgroup v1 CPU Shares to v2 CPU Weight the formula to calculate cpu.weight has been changed in the recent version of runc/crun

  • Old formula: cpu.weight = (1 + ((cpu.shares - 2) * 9999) / 262142)
  • New formula: cpu.weight = 10 ^ (L^2 / 612 + 125 * L / 612 − 7 / 34), where: L=log2⁡(cpu.shares)

Required Code Change

The implementation in cpu_shares should be updated to use the new conversion formula. This change is required to ensure that requested CPU values are computed correctly when running on cgroup v2.

Impact

You can use this playground to play with different values.
https://go.dev/play/p/EIFB4_Ia4ae

2.16

CPU shares cpu.weight (old formula) cpu.weight (new formula) APIcast workers count (with old container runtime) APIcast workers count (with new container runtime)
100mil 4 17 1 1
500mil 19 58 1 2
1 39 99 1 3
2 77 170 2 5
4 153 297 4 8
8 306 522 8 14
16 611 924 16 24

master

CPU shares cpu.weight (old formula) cpu.weight (new formula) APIcast workers count (with old container runtime) APIcast workers count (with new container runtime)
100mil 4 17 1 1
500mil 19 58 1 1
1 39 99 1 1
2 77 170 1 2
4 153 297 2 4
8 306 522 5 8
16 611 924 10 16

With this change, the APIcast will run with less workers on older cluster with older version of container runtime. However, when I check, the container runtime does not seems to tied to a specific version major of OCP and make it hard to adjust these value during runtime.
For example:

  • OCP 4.18.45 -> crun (1.26)
  • OCP 4.20.14 -> crun (1.23.1)

In my opinion, the best is to apply this change to the master branch, then flag it in the release log to mark it as a breaking change.

Verification steps

You will need a cluster with new version of runc/crun, I tried with Docker but it just does not handle cpu.weight the way that I wanted. I'm using 4.20.27 in this case

  • Check runc/crun version
 ▲ ~ oc get nodes -o wide
NAME                                         STATUS   ROLES                  AGE
ip-10-0-122-131.us-west-1.compute.internal   Ready    worker                 5
...

 △ ~ oc debug node/ip-10-0-122-131.us-west-1.compute.internal -- chroot /host crun --version
Temporary namespace openshift-debug-bwvqd is created for debugging node...
Starting pod/ip-10-0-122-131us-west-1computeinternal-debug-sb8zg ...
To use host binaries, run `chroot /host`
crun version 1.27
commit: a718a92cc9a94955a5a550b6fdec1378c247ec50
rundir: /run/crun
spec: 1.0.0
+SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +CRIU +YAJL
  • Setup APIcast
export NAMESPACE=apicast-test
oc new-project $NAMESPACE

cat << EOF | oc create -f -
apiVersion: v1
kind: Secret
metadata:
  name: apicast-config-secret
  namespace: $NAMESPACE
type: Opaque
stringData:
  config.json: |
    {
      "services": [
        {
          "proxy": {
            "policy_chain": [
              { "name": "apicast.policy.upstream",
                "configuration": {
                  "rules": [{
                    "regex": "/",
                    "url": "http://echo-api.3scale.net"
                  }]
                }
              }
            ]
          }
        }
      ]
    }
EOF
  • Install APIcast operator from the catalog
  • Create APIcast CR
cat << EOF | oc create -f -
apiVersion: apps.3scale.net/v1alpha1
kind: APIcast
metadata:
  name: example-apicast
  namespace: $NAMESPACE
spec:
  embeddedConfigurationSecretRef:
    name: apicast-config-secret
EOF
  • One the pod is ready, jump inside and run the following
sh-4.4$ curl localhost:9421/metrics
...
# TYPE worker_process counter
worker_process{} 2

sh-4.4$ cat /sys/fs/cgroup/cpu.weight
59

By default, APIcast is setup with the following

- resources:
        limits:
          cpu: '1'
          memory: 128Mi
        requests:
          cpu: 500m
          memory: 64Mi

Cross check with the table above, we can see 2 workers here for 500m of cpu shares.

  • Update APIcast CR with new image
spec:
  embeddedConfigurationSecretRef:
    name: apicast-config-secret
  image: 'quay.io/an_tran/apicast:cpus-share'
  • Wait for the pod to ready
  • Run the command again, you should see 1 worker this time
sh-5.1$ curl localhost:9421/metrics
...
# TYPE worker_process counter
worker_process{} 1

@tkan145 tkan145 requested a review from a team as a code owner July 8, 2026 03:36
@tkan145 tkan145 changed the title refactor: use new cpu.requests formula from Kubernetes THREESCALE-15465 refactor: use new cpu.requests formula from Kubernetes Jul 8, 2026
@tkan145 tkan145 force-pushed the update-cpus-share-formula branch from 9d4dd07 to 7de3852 Compare July 9, 2026 01:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant