среда, 1 декабря 2010 г.

Зоны Solaris IV: Ресурсные ограничения

Если создавать зоны так, как описано во всех популярных руководствах - т.е. описывать только абсолютный минимум параметров, например вот так:

root @ blade / # zonecfg -z zone1
zone1: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg:zone1
> create
zonecfg:zone1
> set autoboot=true
zonecfg:zone1
> set zonepath=/export/home2/zone1
zonecfg:zone1
> add net
zonecfg:zone1:net
> set address=192.168.100.10
zonecfg:zone1:net
> set physical=eri0
zonecfg:zone1:net
> end
zonecfg:zone1
> verify
zonecfg:zone1
> commit
zonecfg:zone1
> exit

root @ blade / # zoneadm list -vc
ID NAME STATUS PATH BRAND IP
0 global running / native shared
- zone1 configured /export/home2/zone1 native shared

то созданная зона, не имея фактически никаких ресурсных ограничений, будет конкурировать за ресурсы с глобальной зоной и, соответственно, не исключена ситуация перерасхода ресурсов неглобальной зоной до такой степени, что система может стать полностью неуправляемой.

Это не есть хорошо и правильно, тем более, что существует достаточно возможностей по ограничению ресурсов неглобальных зон.

Первая возможность - использовать ресурсные пулы, для чего активировать соответствующий сервис pools и воспользоваться командами pooladm, poolcfg и poolbind:

root @ blade / # svcs pools
STATE STIME FMRI
disabled 19:03:56 svc:/system/pools:default
root @ blade / # svcadm enable pools
root @ blade / # pooladm

system default
string system.comment
int system.version 1
boolean system.bind-default true
string system.poold.objectives wt-load

pool pool_default
int pool.sys_id 0
boolean pool.active true
boolean pool.default true
int pool.importance 1
string pool.comment
pset pset_default

pset pset_default
int pset.sys_id -1
boolean pset.default true
uint pset.min 1
uint pset.max 65536
string pset.units population
uint pset.load 5
uint pset.size 1
string pset.comment

cpu
int cpu.sys_id 0
string cpu.comment
string cpu.status on-line

root @ blade / # poolcfg
Usage:
poolcfg -h
poolcfg -c command [ -d | [ file ] ]
poolcfg -f command-file [-d | [ file ] ]

root @ blade / # poolbind
Usage: poolbind -p pool_name [-i pid | -i taskid | -i projid | -i zoneid] id ...
poolbind -q pid ...
poolbind -Q pid ...

Данный механизм весьма удобен, очень пригоден для больших и масштабируемых установок и серьеных продуктивных систем с большим количеством ресурсов, настолько большим, что использование ресурсных пулов становится оправданным.

Однако первоначальное планирование ресурсных пулов и их конфигурирование - задача не для начинающего администратора, и, в случае некрупных серверов, в общем, не слишком требуется.

Можно ли получить те же результаты несколько иным путем?

Можно.

По существу, для ограничения потребления ресурсов зоной и сохранения ее отзывчивости (а равно и отзывчивости глобальной зоны) требуется установка и контроль нескольких параметров:

- Класса планировщика задач
- Использования процессоров
- Использования памяти.

Самая основная установка - установка класса планировщика задач для неглобальной зоны. Устанавливается как глобальный параметр зоны:

zonecfg:zone1
> set scheduling-class=FSS

Технически вы можете выбрать любой сконфигурированный класс планировщика из доступных:

root @ blade / # dispadmin -l
CONFIGURED CLASSES
==================

SYS (System Class)
TS (Time Sharing)
SDC (System Duty-Cycle Class)

На практике выгодней использовать FSS (Fair Share Sheduler), так как обычно требуется достаточно высокая отзывчивость неглобальных зон, даже при серьезной перегрузке сервера.

Этого, однако, недостаточно для того, чтобы контролировать потребление зоной ресурсов основной системы.

Для контроля и принуждения зон к использованию процессоров и памяти можно использовать демон rcapd:

root @ blade / # svcs rcap
STATE STIME FMRI
disabled 19:03:56 svc:/system/rcap:default

который имеет интерфейс управления rcapadm:

root @ blade / # rcapadm -E
root @ blade / # svcs rcap
STATE STIME FMRI
online 20:16:26 svc:/system/rcap:default

и позволяет принуждать пользователей проектов (projects) к использованию ресурсных ограничений.

Для того, чтобы в зонах можно было использовать ресурсные ограничения, данный демон должен быть запущен, как показано выше.

Ресурсы можно ограничивать глобальными установками зоны (man zonecfg):

Resources
The following resource types are supported:

capped-cpu

Limits for CPU usage.

capped-memory

Limits for physical, swap, and locked memory.

dataset

ZFS dataset.

dedicated-cpu

Subset of the system's processors dedicated to this zone
while it is running.

а также можно воспользоваться добавлением ресурсных ограничителей в синтаксисе конфигураций ресурсных пулов без использования собственно пулов (директива rctl).

Это не единственные ресурсы, использование которых можно определить в зонах. Можно установить ограничения на процессы LWP и ресурсы IPC:

(global)

max-lwps

(global)

max-msg-ids

(global)

max-sem-ids

(global)

max-shm-ids

(global)

max-shm-memory

Вот как выглядит, например, задание выделенных процессоров для сконфигурированной (и остановленной) зоны:

zonecfg:zone1
> info
zonename: zone1
zonepath: /export/home2/zone1
brand: native
autoboot: true
bootargs:
pool:
limitpriv:
scheduling-class: FSS
ip-type: shared
hostid:
inherit-pkg-dir:
dir: /lib
inherit-pkg-dir:
dir: /platform
inherit-pkg-dir:
dir: /sbin
inherit-pkg-dir:
dir: /usr
net:
address: 192.168.100.10
physical: eri0
defrouter not specified
zonecfg:zone1
> add dedicated-cpu
zonecfg:zone1:dedicated-cpu
> set ncpus=1
zonecfg:zone1:dedicated-cpu
> set importance=1
zonecfg:zone1:dedicated-cpu
> end
zonecfg:zone1
> info
zonename: zone1
zonepath: /export/home2/zone1
brand: native
autoboot: true
bootargs:
pool:
limitpriv:
scheduling-class: FSS
ip-type: shared
hostid:
inherit-pkg-dir:
dir: /lib
inherit-pkg-dir:
dir: /platform
inherit-pkg-dir:
dir: /sbin
inherit-pkg-dir:
dir: /usr
net:
address: 192.168.100.10
physical: eri0
defrouter not specified
dedicated-cpu:
ncpus: 1
importance: 1

При необходимости можно удалить свойство dedicated-cpu, скажем, и перейти к модели cpu-shares:

zonecfg:zone1
> remove dedicated-cpu
zonecfg:zone1
> set cpu-shares=2
zonecfg:zone1
> add capped-cpu
zonecfg:zone1:capped-cpu
> set ncpus=2
zonecfg:zone1:capped-cpu
> end
zonecfg:zone1
> info
zonename: zone1
zonepath: /export/home2/zone1
brand: native
autoboot: true
bootargs:
pool:
limitpriv:
scheduling-class: FSS
ip-type: shared
hostid:
[cpu-shares: 2]
inherit-pkg-dir:
dir: /lib
inherit-pkg-dir:
dir: /platform
inherit-pkg-dir:
dir: /sbin
inherit-pkg-dir:
dir: /usr
net:
address: 192.168.100.10
physical: eri0
defrouter not specified
capped-cpu:
[ncpus: 2.00]
rctl:
name: zone.cpu-shares
value: (priv=privileged,limit=2,action=none)
rctl:
name: zone.cpu-cap
value: (priv=privileged,limit=200,action=deny)

Обратите внимание, что использование cpu-shares и добавление capped-cpu приводит к автоматическому созданию ресурсных ограничителей rctl (так же, как и использование параметра capped-memory).

Параметр capped-cpu задает максимальную величину относительной загрузки разделяемых процессоров в процентах для каждого из совместно использованных процессоров.

Для отключения этих параметров и удаления ресурсных ограничителей зоны выполним следующие команды:

zonecfg:zone1
> clear cpu-shares
zonecfg:zone1
> info
zonename: zone1
zonepath: /export/home2/zone1
brand: native
autoboot: true
bootargs:
pool:
limitpriv:
scheduling-class: FSS
ip-type: shared
hostid:
inherit-pkg-dir:
dir: /lib
inherit-pkg-dir:
dir: /platform
inherit-pkg-dir:
dir: /sbin
inherit-pkg-dir:
dir: /usr
net:
address: 192.168.100.10
physical: eri0
defrouter not specified
capped-cpu:
[ncpus: 2.00]
rctl:
name: zone.cpu-cap
value: (priv=privileged,limit=200,action=deny)
zonecfg:zone1
> remove rctl
zonecfg:zone1
> info
zonename: zone1
zonepath: /export/home2/zone1
brand: native
autoboot: true
bootargs:
pool:
limitpriv:
scheduling-class: FSS
ip-type: shared
hostid:
inherit-pkg-dir:
dir: /lib
inherit-pkg-dir:
dir: /platform
inherit-pkg-dir:
dir: /sbin
inherit-pkg-dir:
dir: /usr
net:
address: 192.168.100.10
physical: eri0
defrouter not specified

Для ограничения использования памяти в зоне используется свойство capped-memory:

zonecfg:zone1
> add capped-memory
zonecfg:zone1:capped-memory
> set physical=256m
zonecfg:zone1:capped-memory
> set swap=256m
zonecfg:zone1:capped-memory
> set locked=128m
zonecfg:zone1:capped-memory
> end
zonecfg:zone1>

При добавлении capped-memory по минимуму достаточно указать только значение physical, swap и locked являются опциональными.

Еще одним важным ресурсом зоны является сетевой интерфейс. По умолчанию сетевой интерфейс используется в режиме shared, для каждой зоны создается логический интерфейс и назначается IP-адрес.

Для высоконагруженной зоны (в плане сетевого трафика) можно установить монопольное использование сетевого интерфейса одной зоной. В этом случае интерфейсу назначается IP-адрес в глобальной зоне (командой ifconfig) и при конфигурировании зоны указывается режим использования физического интерфейса exclusive:

zonecfg:zone1
> set ip-type=exclusive
zonecfg:zone1
> verify
net: address cannot be specified for an exclusive IP type
zone1: Invalid argument

Обратите внимание, что IP-адрес винтерфейса этом случае действительно должен быть определен в глобальной зоне. В нашем случае для реконфигурирования сетевых установок зоны нужно выполнить следующие команды:

zonecfg:zone1
> remove net
zonecfg:zone1
> add net
zonecfg:zone1:net
> set physical=eri0
zonecfg:zone1:net
> end
zonecfg:zone1
> verify

Теперь конфигурация нашей зоны такая, какой мы хотели ее сделать и ее можно установить или запустить:

zonecfg:zone1
> verify
zonecfg:zone1
> info
zonename: zone1
zonepath: /export/home2/zone1
brand: native
autoboot: true
bootargs:
pool:
limitpriv:
scheduling-class: FSS
ip-type: exclusive
hostid:
inherit-pkg-dir:
dir: /lib
inherit-pkg-dir:
dir: /platform
inherit-pkg-dir:
dir: /sbin
inherit-pkg-dir:
dir: /usr
net:
address not specified
physical: eri0
defrouter not specified
capped-memory:
physical: 256M
[swap: 256M]
[locked: 128M]
rctl:
name: zone.max-swap
value: (priv=privileged,limit=268435456,action=deny)
rctl:
name: zone.max-locked-memory
value: (priv=privileged,limit=134217728,action=deny)


Как видно из приведенных примеров, ресурсные ограничители rctl добавляются в конфигурацию зоны без использования ресурсных пулов. Очевидно, что можно добавлять ресурсные ограничители и непосредственно, командой zonecfg add rctl.