The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Введение в OpenVZ (openvz chroot container linux limit)


<< Предыдущая ИНДЕКС Исправить src / Печать Следующая >>
Ключевые слова: openvz, chroot, container, linux, limit,  (найти похожие документы)
From: sHaggY_caT Date: Mon, 3 Aug 2010 17:02:14 +0000 (UTC) Subject: Введение в OpenVZ Оригинал: http://blog.shaggy-cat.ru/2010/03/openvz_25.html Общая информация Технология OpenVZ не является виртуализацией в общепринятом значении этого термина. OpenVZ предоставляет так называемые контейнеры, и является виртуализацией уровня операционной системы. OpenVZ является базисом для проприетарного, улучшенного решения с профессиональной технической поддержкой: Parallels Virtuozzo Containers (PVC). Parallels является главным спонсором проекта OpenVZ, и ей принадлежат авторские права на код. Утилиты OpenVZ лицензированы, в основном, под GNU GPL v2 (или старше) Если сильно упростить, можно считать, что: * Обычная, невиртуализированная система, имеет один kernel-mode (ring0), и один user-mode, в последнем процессы не имеют прямого доступа к оборудованию, таймеру, и т д, и вынуждены использовать API ядра и другие базовые утилиты/библиотеки user-mode для доступа к оборудованию и пр. привелегированным операциям требующим вмешательства ядра * Полная виртуализация запускает под хостовой ОС, в качестве user-mode процесса, виртуальную машину неподозревающую о своей виртуальности, со своими usermode и ring0 * Паравиртуализация, позволяет запускать модифицированные версии гостевых ОС, не старающихся не замечать, что они работают не на настоящем железе, а виртуализированы, и использующих модифицированные фронт-энды-драйверы для доступа к оборудованию и другим интерфейсам хост-системы, позволяет добиться существенного повышения производительности * Гипервизор представляет из себя тонкую специализированную ОС, занимающуюся прежде всего только выделением ресурсов для гостевых систем * контейнеры в отличае от перечисленных выше технологий, представляют из себя несколько user-mode под одним kernel-mode. Некоторые технологии, такие как OpenVZ/PVC, позволяют так же управлять некоторыми (далеко не всеми) параметрами kernel-mode отдельно для каждого контейнера Главным преимуществом контейнеров является практически нативная(как у невиртуализированной системы "на железе") производительность, отсуствие потерь на виртуализацию из-за отсуствия переключения ядерных контекстов (так как ring0 один, шедуллер CPU, диска тоже один, но модифицированные для работы с контейнерами) Главными недостатками является меньшая изоляция и устойчивость по сравнению с виртульными машинами (невозможно полностью исключить влияние контейнеров друг на друга, хотя в OpenVZ/PVC оно и сведено практически к минимуму), а так же невозможность решения большей части задач, требующих модификации ядра/ особых ядерных параметров. В частности, в OpenVZ контейнере нельзя запустить обычный, ядерный NFS, OpenVPN работает прямо-таки по случайному совпадению, с помощью хака, IPsec не работает, и т д. Основные концепции * Хост-система называется Hardware Node, управление контейнерами и всем сервером производится именно с нее. Так же ее иногда называют CT0, VE0(нулевой контейнер), именно такое обозначение можно встретить в конфигурационных файлах OpenVZ * Контейнеры в технологии OpenVZ, так и называются "контейнерами"(CT, Container), а так же Virtual Enviroment'ами (VE, гостевыми окружениями) * Каждый контейнер имеет доступ к пулу ресурсов, причем может иметь гарантии на ресурсы, и лимиты. * Темплейты - шаблоны контейнеров(с предустановленным ПО), из которых контейнеры и развертываются Существуют группа UBC ресурсов, а так же отдельные от них дисковые квоты, квоты на потребление CPU, и приоритеты i/o Возможности OpenVZ * OpenVZ предоставляет менеджмент ресурсов физического сервера для каждого контейнера. Почти все ресурсы могут быть гарантированными, и негарантированными (лишние имеющиеся в наличии на ноде, и отданные в распоряжение тех контейнеров, которым позволено пользоваться такими ресурсами в рамках своего конфига). Возможны так же жесткие лимиты на большую часть ресурсов. Наличие отдельных ресурсов для каждого контейнера придает устойчивость сервисам, а существование негарантированных ресурсов может дать производительность шаред-хостинга, так как дает возможность использовать всю мощность физического сервера под сервисы, если он простаивает. * Ресурсы "второго уровня": администратору OpenVZ-контейнера можно разрешить использовать собственные дисковые квоты (по-умолчанию отключено), и ставить собственные приоритеты на процессы (renice, включено всегда), номера процессов так же виртуализированы: pid процесса init внутри контейнера всегда равен одному, хотя на HardwareNode у него(как и у остальных процессов контейнера) будет другой номер * OpenVZ предоставляет почти полноценный сетевой стек для каждого контейнера с собственными IP-адресами, таблицами статической маршрутизации, и даже с собственными правилами iptables, которыми можно управлять из контейнера. Количество правил для контейнера является ресурсом, который может быть установлен в конфиге. Есть возможность использовать два вида сетевых интерфейсов: venet, более производительный, и veth, с незначительным оверхедом, но предоставляющий поддержку Ethernet mac-адресов для контейнеров. Большинство технологии контейнерной виртуализации не предоставляют полноценный сетевой стек, и не обеспечивают даже половины возможностей (например, во FreeBSD jails только во FreeBSD 8 появилась поддержка более одного IP на Jail, и какие-то зачатки своего стека для контейнера, тогда как на момент написания статьи, даже FreeBSD7 еще только начинала использоваться в production некоторыми хостерами) * OpenVZ предоставляет возможности так называемого Checkpointing и live-migration. + Live-migration - миграция контейнера с одной HardwareNode на другую без выключения контейнера. Даунтайм составляет, обычно, несколько секунд. На новую HardwareNode восстанавливается дамп памяти контейнера (с запущенными процессами) + Checkpointing - технология, позволяющая заморозить контейнер, и восстановить его состояние из дампа памяти. Удобно, например, для создания бэкапа контейнера, интенсивно работающего с базой данных, транзакции которой не могут быть оборваны некорректно * OpenVZ содержит несколько "хаков", предоставляющих нетипичные, для контейнеров, возможности (близкие к виртуализации): возможность подгружать на ноду ядерные модули, и, иногда, работать с ними из контейнеров. Например, можно "пробросить" железку в контейнер, при этом есть достаточно большая вероятность, что она в ней заработает (если работает в контексте хост-системы). Может использоваться в тех случаях, когда user-mode утилиты, требуемые драйверу, программно не совместимы с другими утилитами, которые могут быть установлены на физической машине, но следует понимать, что такое решение не всегда оправдано на отвественных системах с большим числом контейнеров, так как ядро всего одно, ошибка в ядерном драйвере устройства обрушит всю HardwareNode. Так же занимателен факт реализации работы OpenVPN внутри контейнера (видимо, понадобилось кому-то из разработчиков). Яедрный модуль при этом, понятно, один на всю ноду, а вот user-mode демонов может быть сколько угодно много, на всю ноду, и каждый из них будет считать, что работает на "настоящем" железе UBC, User Beancounters В группе ресурсов UBC находится большая их часть. UBC можно посмотреть из контекста ноды для каждого контейнера в файле /proc/user_beancounters, а так же в /proc/bc/VEID/resources [root@veweb21 /]# cat /proc/user_beancounters Version: 2.5 uid resource held maxheld barrier limit failcnt 5005: kmemsize 7430824 14454677 21055923 21377049 0 lockedpages 0 0 256 256 0 privvmpages 49608 65562 243200 262144 0 shmpages 8336 8336 21504 21504 0 dummy 0 0 0 0 0 numproc 45 94 240 240 0 physpages 33338 40620 0 2147483647 0 vmguarpages 0 0 201216 204800 0 oomguarpages 33338 40620 26112 2147483647 0 numtcpsock 6 14 360 360 0 numflock 1 6 188 206 0 numpty 1 1 16 16 0 numsiginfo 0 2 256 256 0 tcpsndbuf 53760 156800 1720320 2703360 0 tcprcvbuf 98304 324096 1720320 2703360 0 othersockbuf 26880 35840 1126080 2097152 0 dgramrcvbuf 0 8576 262144 262144 0 numothersock 20 25 360 360 0 dcachesize 4248 40356 3409920 3624960 0 numfile 970 1118 9312 9312 0 dummy 0 0 0 0 0 dummy 0 0 0 0 0 dummy 0 0 0 0 0 numiptent 14 14 128 128 0 Описание ресурсов можно прочитать в официальной документации. * fcnt Последняя правая колонка, fcnt, это счетчик отказа в выделении ресурса. Ненулевое значение счетчика обозначает нехватку ресурса, и, как правило, нестабильную работу приложения внутри контейнера. Решением проблемы может быть выделение большего числа ресурсов приложению, либо перенастройка приложения так, что бы оно умерило аппетиты. * Колонка held означает текущее значение утилизации ресурса * Колонка maxheld максимальное значение за все время калькуляции ресурсов для контейнера * Колонка barrier Обозначает максимальное значение потребления ресурса, которое, в ряде случаев, может быть превышено(если на HN есть свободные ресурсы) * Колонка limit Обозначает максимальное значение потребления ресурса, которое никогда не может быть превышено контейнером UBC лимиты так же можно просмотреть, находясь внутри контейнера: cat /proc/user_beancounters OpenVZ позволяет "мухлевать" с выделением памяти: дело в том, что память, ассигнованная приложением, практически никогда в таком объеме ему не требуется: [root@ovz07 ~]# vzmemcheck Output values in % LowMem LowMem RAM MemSwap MemSwap Alloc Alloc Alloc util commit util util commit util commit limit 20.66 195.31 30.89 14.34 126.26 48.51 191.00 341.16 И в разрезе по контейнерам, можно увидеть, что утилизированная память всегда гораздо меньше, чем аллоцированная: [root@ovz07 ~]# vzmemcheck -v Output values in % veid LowMem LowMem RAM MemSwap MemSwap Alloc Alloc Alloc util commit util util commit util commit limit 5018 0.35 5.28 0.24 0.11 1.84 0.64 2.30 4.44 5002 0.33 5.28 0.35 0.16 1.84 0.23 8.12 12.04 9074 0.54 5.28 0.38 0.18 1.84 0.77 2.30 4.44 ... 5001 0.53 5.84 0.35 0.16 1.87 0.47 6.19 12.07 Summary: 20.67 195.31 30.89 14.34 126.26 48.51 191.00 341.16 В выделении памяти OVZ-ядром есть много нюансов, вероятно, главный то, что считается аллоцирования, а не реально используемая процессами в контейнере память. Это, с одной стороны, удобно, и помогает большей изоляции, но с другой минус в том, что контейнеру может быть отказано в аллоцировании памяти тогда, когда контейнер просто хочет зарезервировать для себя много ОЗУ, а реально ее не использует. CPU OpenVZ позволяет ставить приоритеты CPU, и лимиты CPU. Приоритеты ставятся в специальных единицах CPUUNITS, вычисляемые по специальной формуле так, что у процессоров с разной производительностью будет разное число CPUUNITS, что бы контейнер, перевезенный на новую ноду, получал такое же количество ресурсов CPU, что и раньше. То есть, cpuunints так же являются и минимально гарантированными ресурсами CPU * Два контейнера с вдвое отличающимися значениями cpuunits получат, при стопроцентной загрузке процессора ноды, вдвое различающееся количество процессорного времени для своих процессов * Внутри контейнеров можно использовать собственные приоритеты на процессы, OpenVZ использует двухуровневый планировщик CPU * Лимиты CPU ставятся в процентах. Удобно поставить высокое значение CPUUNITS для приложения, требующего высокой интерактивности, но малое значение CPULIMIT, что бы оно не "завалило" HardwareNode, и наоборот, для приложения не требующего высокой интерактивности, например, для контейнера, в котором в фоне компилируются rpm-пакеты, можно поставить очень маленькие CPUUNITS, но оставить высокий лимит на CPULIMIT, что бы, когда CPU ноды не загружен, он использовался для фоновой многочасовой компиляции С ноды проверить потребление CPU можно с помощью команд: [root@ovz07 ~]# vzcpucheck Current CPU utilization: 193130 Power of the node: 280025 Здесь Current CPU utilization - обещанные гарантии времени CPU, вы 88;аженные в CPUUNITS, а Power of the node вычисленное значение CPUUNITS в целом для ноды А вот потребление CPU в разрезе каждого контейнера: [root@ovz07 ~]# vzcpucheck -v VEID CPUUNITS ------------------------- 0 1000 5001 2500 5003 15151 5004 1302 ... 5018 1000 Current CPU utilization: 193130 Power of the node: 280025 Дисковые квоты OpenVZ поддерживает двухуровневые дисковые квоты: во-первых, квота на занимаемое место, и количество дисковых инодов (файлы, директории, сокеты, и т д) на весь контейнер, и во-вторых, квоты устанавливаемые администратором OpenVZ-контейнера для пользователей и групп контейнера. Работа с квотами внутри OpenVZ контейнера аналогична работой с квотами внутри обычной, не виртуализированной Linux-системы Пример просмотра квот для всего контейнера: [root@ovz07 ~]# vzquota show 5005 vzquota : (warning) Quota is running, so data reported from quota file may not reflect current values resource usage softlimit hardlimit grace 1k-blocks 3305824 15048576 15153024 inodes 154840 600000 620000 softlimit - лимит, который может быть превышен, hardlimit, лимит, который не может быть превышен, 1k-blocks - занятое место, в блоках по 1k inodes - количество занятых inodes Очень важно, что бы файлы попадали в контейнер штатным путем, то есть, через сеть (ssh, ftp, http, и т д), иначе квота на контейнер будет считаться неверно. В случае если есть проблемы с квотой, можно заставить OpenVZ пересчитать квоту для контейнера с помощью команды: vzquota drop и перезапустить контейнер. Квота может вычисляться достаточно долго, минуты(даже десятки минут в редких случаях), оказывая существенную нагрузку на диск (особенно в случае большого числа файлов в контейнере) I/O приоритеты OpenVZ использует модифицированный CFQ -планировщик для выделения отдельных "весов", приоритетов по работе с диском для каждого контейнера. К сожалению, в условиях острого дефицита дисковых операций, планировщик не может гарантировать справедливого выделения дисковых ресурсов для всех контейнеров. Если какой-либо контейнер дергает диск во много потоков, минимальный приоритет для его процессов может лишь слегка улучшить катастрофическую ситуацию. Проблема связана с тем, что OpenVZ, by design, использует один общий дисковый кэш на все VPS. В кэш ядро помещает те данные, к которым наиболее часто обращается, соотвественно, даже процессы контейнера с минимальным дисковым приоритетом, в случае большого числа обращений к диску, рано или поздно вытеснят из кэша процессы других контейнеров. Минимальный приоритет поможет другим контейнерам хотя бы получать доступ непосредственно к диску, но общая ситуация, когда данные чаще всего будут браться не из кэша, а непосредственно с диска, будет иметь тенденцию к дальнейшему катастрофическому развитию ситуации. Следует иметь ввиду, что OpenVZ не лучшее решение для виртуализации серверов с серьезной дисковой нагрузкой. Приоритет может иметь значения от 0 до 7. vzctl set 101 --ioprio 0 --save vzctl set 101 --ioprio 7 --save Первая команда установит минимальный приоритет для контейнера, а вторая максимальный. По-умолчанию, любой контейнер имеет приоритет 4, и ядро OpenVZ старается выделить всем контейнерам примерно одинаковое количество дисковых операций, что у него практически всегда прекрасно получается, когда ни один из контейнеров не пытается использовать дисковых ресурсов больше, чем в состоянии выдать дисковая подсистема сама по себе. Конфигурационные файлы Главный конфигурационный файл OpenVZ: /etc/sysconfig/vz В файле описываются общие (без применения к отдельным контейнерам) настройки среды OpenVZ/PVC Конфигурационные файлы контейнеров находятся тут: /etc/sysconfig/vz-scripts/ Например, 5014.conf - параметры контенера 5014, 5011.start - скрипт, выполняющийся после старта контейнера в контексте контейнера 5018.mount - скрипт, выполняющийся при старте контейнера (когда он переходит в состояние mounted) в контексте ноды ve-vps256M.conf-sample - набор типовых параметров для контейнера (тарифный план) Пример конфига контейнера: ONBOOT="yes" # UBC parameters (in form of barrier:limit) KMEMSIZE="21055923:21377049" LOCKEDPAGES="256:256" PRIVVMPAGES="243200:262144" SHMPAGES="21504:21504" NUMPROC="240:240" PHYSPAGES="0:2147483647" VMGUARPAGES="201216:204800" OOMGUARPAGES="26112:2147483647" NUMTCPSOCK="360:360" NUMFLOCK="188:206" NUMPTY="16:16" NUMSIGINFO="256:256" TCPSNDBUF="1720320:2703360" TCPRCVBUF="1720320:2703360" OTHERSOCKBUF="1126080:2097152" DGRAMRCVBUF="262144:262144" NUMOTHERSOCK="360:360" DCACHESIZE="3409920:3624960" NUMFILE="9312:9312" AVNUMPROC="180:180" NUMIPTENT="128:128" # Disk quota parameters (in form of softlimit:hardlimit) DISKSPACE="15048576:15153024" DISKINODES="600000:620000" QUOTATIME="0" # CPU fair sheduler parameter CPUUNITS="15000" CPULIMIT="65" VE_ROOT="/vz/root/$VEID" VE_PRIVATE="/vz/private/$VEID" OSTEMPLATE="centos-5-i386-webserver" ORIGIN_SAMPLE="vps.basic" HOSTNAME="lamp.loc" IP_ADDRESS="10.0.10.5" NAMESERVER="217.10.32.4 10.0.5.51" NETIF="ifname=eth0,mac=00:18:51:1D:90:C3,host_ifname=veth5005.0,host_mac=00:18:51:7D:4D:E0" # Network customization section CONFIG_CUSTOMIZED="yes" VETH_IP_ADDRESS="10.0.5.110/24" BRIDGEDEV="br0" Темплейты и другая, связанная с ними информация. В Virtuozzo так называемые EZtemplates представляют из себя "особую" rpm, в которой хранится список rpm (или deb) пакетов контейнера, что позволяет, во-первых, развертывать контейнер из свежего ПО, а, во-вторых, обновлять ПО внутри контейнера. В OpenVZ (а так же в Virtuozzo в слегка улучшенном виде) так же доступны более "простые" темплейты, которые представляют из себя затаренную корневую систему инсталляции какого-либо дистрибутива, минус некоторые системные файлы. Из данного тарболла, так называемого "private cache", и производится развертывание новых контейнеров. В директории /vz/template/cache/ и находятся template cache разных систем: [root@ovz-test ~]# ls /vz/template/cache/ centos-4-x86.tar.gz centos-5-x86.tar.gz fedora-12-x86.tar.gz ubuntu-9.04-x86.tar.gz centos-5-i386-default.tar.gz debian-5.0-x86.tar.gz suse-11.1-x86.tar.gz Так же, существует набор скриптов, предоставляющих менеджмент сети и других параметров, специфичных для дистрибутива: ls /etc/vz/dists/ altlinux-2.4.conf default owl.conf sles-9.conf altlinux-3.0.conf distribution.conf-template redhat-7.0.conf sles.conf altlinux-4.0.conf fedora-7.conf redhat-7.1.conf suse-7.3.conf altlinux.conf fedora-8.conf redhat-7.2.conf suse-8.0.conf arch-0.7.conf fedora-9.conf redhat-7.3.conf suse-8.1.conf arch-0.8.conf fedora-core-1.conf redhat-8.0.conf suse-8.2.conf arch.conf fedora-core-2.conf redhat-9.conf suse-9.0.conf centos-3.conf fedora-core-3.conf redhat.conf suse-9.1.conf centos-4.conf fedora-core-4.conf rhel-3.conf suse-9.2.conf centos-5-i386-webserver.conf fedora-core-5.conf rhel-4.conf suse-9.3.conf centos.conf fedora-core-6.conf scripts/ suse.conf centoswebserver-5-x86.conf fedora-core-7.conf slackware-10.0.conf ubuntu-5.1.conf debian-3.0.conf fedora-core.conf slackware-10.1.conf ubuntu.conf debian-3.1.conf gentoo.conf slackware-9.0.conf debian-4.0.conf mandrake.conf slackware-9.1.conf debian.conf opensuse.conf slackware.conf OpenVZ узнает о том, что, например, к контейнеру нужно применить набор правил gentoo.conf, если template cache называется gentoo-XXXXXX Для openvz ранее использовались утилиты vzyum и vzrpm для создания и обновления private cache шаблонов из пакетов vztmpl, но их развитие остановилось, и сейчас поддерживаются только очень старые Fedora, CentOS4, и CentOS5 (через vztmpl шаблон от коммюнити) Существует полуофициальный проект vzpkg2 для возрождения данного функционала для современных контейнеров, добавлена поддержка Debian-based систем (Debian, Ubuntu). Статус проекта и его будущее не до конца ясно. Вот ссылка на страницу в официальной вики openvz: http://wiki.openvz.org/Install_vzpkg2_and_pkg-cacher Официально проектом OpenVZ сейчас предоставляются только template cache свежих систем, и "поддерживаются" vztmpl пакеты для давно умерших, по большей части, дистрибутивов, из которых имеет актуальность разве что CentOS4 Так как контейнеры крутятся на хоть и "старом" RHEL-ядре, теоретически возможны какие-либо проблемы с очень свежим софтом и системными утилитами в свежих дистрибутивах, но, благодаря регулярному бэкпортированию фич последних ядер в RHEL-ядра, такая ситуация возникает редко. Менее месяца назад(от момента написания статьи) возникла угроза того, что под OpenVZ не будет работать следующий LTS Ubuntu, и Debian 6 (сломана поддержка udev) В прошлый раз такая проблема возникла с Fedora10, шаблон которой появился только почти одновременно с Fedora11. Можно так же создавать application шаблоны с преднастроенными системами, они должны называться, например, debian-5.0-x86-webserver.tar.gz, fedora-12-x86-plesk.tar.gz, и т д, что бы скрипты openvz правильно конфигурировали контейнер, созданный из темплейта операционной системы. Таким шаблоном может быть просто настроенный и затаренный vps-сервер Другая информация Так называемая "приватная" область контейнера находится в директории /vz/private/. Это корневая файловая система контейнера. Когда контейнер находится в состоянии running и mounted, она монтируется в директорию /vz/root/. В случае, если нужно срочно перекинуть файл с ноды в контейнер, его нужно поместить в директорию /vz/root/VEID/PATH-в-контейнере При этом нужно иметь ввиду, что квота в контейнере теперь будет считаться неверно, и ее необходимо сбросить (см. выше) В PVC в /vz/private/ находятся лишь симлинки на темплейты, установленные на ноде, и файлы темплейтов, которые были изменены в контейнере, а так же созданные в нем самом файлы. После перехода контейнера в состояние running или mounted эти файлы вместе с симлинками монтируются в /vz/root/. Данная технология называется VZFS. и является одним из главных преимуществ Virtuozzo перед OpenVZ, так как позволяет резко сократить потребление ОЗУ и места на диске. Базовые команды * vzctl enter veid - "войти" в контейнер с номером veid * vzctl restart veid - перезапустить контейнер veid * vzlist - получить список запущенных контейнеров * vzlist -a получить список всех контейнеров (во всех состояниях, не только запущенных) * vzlist veid то же самое для одного контейнера * vzctl stop veid --fast экстренно, с максимальной скоростью, остановит контейнер veid. Можно использовать, если контейнер является источником каких-то проблем. Чревато сбоем в подсчете квоты контейнера. * vztl stop veid - то же самое, что и предыдущая команда. * vzps aux -E veid - аналог ps aux, но только для процессов контейнера veid * vzpid pid - узнать, какому контейнеру принадлежит процесс с PID pid Ссылки http://wiki.openvz.org/Main_Page - Wiki OpenVZ, официальная документация http://www.parallels.com/ru/products/pvc45/ - Обзор Parallels Virtuozzo Containers на сайте Parallels http://ru.wikipedia.org/wiki/OpenVZ Статья в русской wikipedia. Я согласна не со всеми выводами и тезисами (как ругательными, так и хвалебными)

<< Предыдущая ИНДЕКС Исправить src / Печать Следующая >>

Обсуждение [ RSS ]
  • 1, daevy (??), 13:10, 11/08/2010 [ответить]  
  • +/
    как думаете будущее у проекта есть?
     
  • 2, Anton (??), 19:43, 12/10/2011 [ответить]  
  • +/
    Конечно есть!
    Вы нас хотите в заблуждение ввести?
     
  • 3, Elena10 (ok), 22:18, 15/11/2011 [ответить]  
  • +/
    Сильный проект
     

     Добавить комментарий
    Имя:
    E-Mail:
    Заголовок:
    Текст:




    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру