Scaling containers
On this page
lws lxc scale changes the resources of existing containers by running
pct set and pct resize on the Proxmox host, so the values land in the
container’s Proxmox configuration like a change made in the web interface.
You decide the values; lxc scale-check can only suggest them.
CPU: three settings in Proxmox
Proxmox gives an LXC container three CPU settings, which work together:
| Setting | What it controls | When unset | Set by LWS |
|---|---|---|---|
cores |
How many of the host’s CPUs the container can use, and the number it sees | Every CPU of the host | lxc scale --cpucores |
cpulimit |
A cap on CPU time, counted in CPUs: 1.5 is the time of one and a half CPUs |
No cap (0) |
lxc scale --cpulimit, and the instance size at creation |
cpuunits |
A relative weight, used only when containers compete for CPU | The Proxmox default | Never |
A container created with lws lxc run --size mid gets cpulimit: 2 and no
cores: it sees every CPU of the host but receives at most the time of two.
Programs that size their worker pools from the number of CPUs they see can
start more workers than that limit serves well. Set --cpucores as well when
that matters:
# Two CPUs visible, and at most the time of two CPUs
lws lxc scale 100 --cpucores 2 --cpulimit 2
--cpucores takes a whole number from 1 to 8192, --cpulimit a decimal
from 0 to 8192, where 0 removes the cap. LWS has no option for
cpuunits; to give one container more weight than its neighbours, run
pct set 100 --cpuunits 200 on the host (or through lws px exec).
Memory
--memory sets the container’s memory limit in MB (at least 16) with
pct set --memory, and Proxmox applies it to a running container straight
away:
lws lxc scale 100 --memory 4096
Warning: lowering the limit below what the container is using makes the
kernel reclaim memory from it, and it may kill processes in the container to
stay under the limit. Check the usage first with lxc status or
lxc resources (see Watching live usage).
LWS does not change swap. Use pct set 100 --swap 1024 on the host for that.
Root disk
--storage-size grows the root disk with pct resize 100 rootfs <size>. Give
an absolute size (64G) or an amount to add (+8G). The units are K, M,
G and T, and a plain number is read as GiB:
lws lxc scale 100 --storage-size 64G
lws lxc scale 100 --storage-size +8G
Disks only grow: Proxmox refuses a size smaller than the current one, and
LWS reports its error. Proxmox also grows the filesystem, so there is nothing
to run inside the container, which can keep running. lxc show-storage shows
the new size from inside. Only rootfs is resized; for a mount point such as
mp0, run pct resize 100 mp0 +10G on the host.
Network rate limit
--net-limit sets the rate option of net0, in megabytes per second (not
megabits): 12.5 is about 100 Mbit/s. 0 removes the limit.
lws lxc scale 100 --net-limit 12.5
pct set replaces the whole net0 definition, so LWS first reads the
current one from pct config, replaces only its rate, and writes it back:
the bridge, address, MAC address and firewall flag stay as they were. Only
net0 is limited. A container without net0 is reported as an error.
Why there are no disk I/O limits
Proxmox has no setting that limits the disk bandwidth of a container; its
per-disk read and write limits exist only for virtual machines. lxc scale
still accepts the hidden options --disk-read-limit and --disk-write-limit,
only to refuse them with that explanation instead of failing with “No such
option”. If a workload needs a disk bandwidth limit, run it in a VM.
Several containers at once
lxc scale takes several container IDs and applies the same values to each,
one after the other:
lws lxc scale 100 101 102 --memory 2048
All of them must be on the host selected with --region and --az. If one
container fails, LWS reports it and goes on with the next; the command then
exits with status 1. For each container, CPU, memory and network changes are
made in one pct set, then the disk is resized. If pct set fails, that
container’s disk is not resized. Passing no option at all is an error.
Instance sizes and existing containers
--size exists only on lxc run: the size’s memory, cpulimit and
storage are passed to pct create, and that is the only time they are
used. LWS does not record which size a container was made with, and editing
instance_sizes in config.yaml does not change existing containers.
To move a container to another size, pass that size’s values, which
Instance sizes lists. From mid (2048 MB, 2 CPUs,
16 GiB) to large (4096 MB, 2 CPUs, 32 GiB):
lws lxc scale 100 --memory 4096 --cpulimit 2 --storage-size 32G
Suggestions with lxc scale-check
lws lxc scale-check 100
scale-check is read-only. It compares what a container is allocated
with what the host has, using the scaling block of config.yaml. It
does not look at what the container is using: an idle container and a busy
one with the same allocation get the same suggestions. It works on stopped
containers too, since it reads only pct config.
- It reads the host’s totals: the number of CPUs from the
CPU(s):line oflscpu(logical CPUs, so threads count), and the total memory fromfree -m. - It reads the container’s allocation from
pct config:cores, orcpulimitrounded up whencoresis unset, or every host CPU when both are unset;memory; and thesizeofrootfsin GB. - For each resource, it compares the allocation with a share of a reference and suggests one step up or down:
| Resource | Reference | Suggest more when below | Suggest less when above | Step up | Step down |
|---|---|---|---|---|---|
| CPU | Host CPUs | min_threshold × CPUs |
max_threshold × CPUs |
step × scale_up_multiplier |
step × scale_down_multiplier |
| Memory | Host memory (MB) | min_threshold × memory |
max_threshold × memory |
step_mb × scale_up_multiplier |
step_mb × scale_down_multiplier |
| Disk | limits.max_storage_gb |
min_threshold × max |
never | step_gb × scale_up_multiplier |
none |
The new value is the current one plus or minus the step, with decimals
dropped, and kept between the limits minimum and maximum. A smaller disk is
never suggested, because Proxmox cannot shrink a container’s disk.
Thresholds are fractions (0.30 is 30%); a value above 1 is read as a
percentage. Keys missing from config.yaml take the values of
config.yaml.example, except that the CPU and memory maximums default to the
host’s own. Configuration lists the
keys.
A worked example
Take a host where lscpu reports 16 CPUs and free -m reports 64000 MB in
total (a 64 GiB host shows a little less than 65536), with the thresholds of
config.yaml.example:
- CPU: more below 16 × 0.30 = 4.8 cores, less above 16 × 0.80 = 12.8; the step is 1 × 1.5 = 1.5 up and 1 × 0.5 = 0.5 down, so one core either way once decimals are dropped.
- Memory: more below 64000 × 0.40 = 25600 MB, less above 64000 × 0.70 = 44800 MB; 256 × 1.25 = 320 MB up, 256 × 0.75 = 192 MB down.
- Disk: more below 1024 × 0.50 = 512 GB; 10 × 1.5 = 15 GB up.
| Container | Allocation | CPU | Memory | Disk |
|---|---|---|---|---|
100 (--size mid) |
cpulimit 2, 2048 MB, 16 GB |
2 < 4.8: 3 | 2048 < 25600: 2368 | 16 < 512: 31 |
| 101 | cores 8, 32768 MB, 600 GB |
none | none | none |
| 102 | no CPU settings, 49152 MB, 900 GB | counted as 16 > 12.8: 15 | 49152 > 44800: 32768 | none |
What the example shows:
- The thresholds express the share of the host one container should hold.
With the example values, nearly every small container on a large host is
told to grow. On a host shared by many small containers, lower the
min_thresholdvalues, for example to0.05. - Each run suggests one step. After you apply it, the next run suggests another step while the value is still below the threshold.
- One step down from 49152 MB would be 48960 MB, still above
max_memory_mb(32768), so the suggestion for 102 is the maximum itself. - Container 102’s disk is above 85% of
max_storage_gb, but no smaller size is suggested: Proxmox cannot shrink it. - The output ends with the
lxc scalecommand that applies the suggestions. Container 100 is limited bycpulimit, so the command changes--cpulimit; for a container withcoresset, it changes--cpucores:
lws lxc scale 100 --cpulimit 3 --memory 2368 --storage-size 31G
Watching live usage
These commands run tools inside the container (top, free, df, ps)
and show what it is using now:
# CPU, memory, disk and process count every 5 seconds, 12 times
lws lxc resources 100 --interval 5 --count 12
# One reading per container: load average, memory, disk and swap
lws lxc status 100 101 102
# Configuration, usage, addresses and top processes, saved as JSON
lws lxc report 100 --output json --file report-100.json
lxc resources needs a running container. It starts by printing the
container’s CPU and memory settings: its cores, its cpulimit, or “all
host CPUs” when it has neither. lxc status counts memory as total minus
free, so the page cache counts as used. For history over days, use the
graphs on the container’s Summary page in the Proxmox web interface.
No autoscaling
LWS has no background process and never changes a container by itself. The
most you can automate is a report: run scale-check from cron and read the
log, then apply what you agree with using lxc scale. Run it from the folder
that holds config.yaml, which LWS reads from the current directory:
# crontab on the machine that runs LWS: every Monday at 07:00
0 7 * * 1 cd /opt/lws && for id in 100 101 102; do python3 lws.py lxc scale-check $id; done >> /var/log/lws-scale-check.log 2>&1
Related pages
- Configuration describes the
scalingkeys. - Instance sizes lists the sizes for
lxc run. - CLI reference lists every option of
lxc scale. - API reference has the same operations over HTTP.