пятница, 8 августа 2014 г.

Postgresql 9.2.4 для 1С в контейнере Docker и решение с shmmax

Новые технологии, новые задачи.


Давно хотел погонять технологию docker в работе, но, случая не предоставлялось. А тут возникла необходимость переместить кучу файловых баз 1С от Зарплаты и Управление персоналом в базу данных.

Ну и соответственно, звезды сложились. Проблема в том, что ЗУП 3.0 работает с Postrgesql 9.2, а предыдущие не работают, точнее, им нужен postgress собранный с другой опцией, либо версией ниже. Плодить кучу серверов БД не хотелось, Хотелось красиво все завернуть в виртуалки с минимальных оверхедом. И тут я вспомнил про docker. Попробовал, получилось, были и проблемы, но они решены. Этими решениями и хотел поделиться.

Приступим и посмотрим, что получится:

1. Свежеустановленная Ubuntu 14.04.


Качаем, ставим, ничего сверхестественного.

2. Подготовка


docker можно взять из репо убунты, но я взял из репо самого проекта. Инструкция здесь:

Кратко:

Добавляем ключ:

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9

Добавляем репозитарий
$ sudo sh -c "echo deb https://get.docker.io/ubuntu docker main\ > /etc/apt/sources.list.d/docker.list"

$ sudo apt-get update

$ sudo apt-get install lxc-docker

3. Установка


Чистый образ:

sudo docker run -i -t ubuntu:precise /bin/bash

В контейнере:

apt-get update apt-get install nano wget bzip2 exit

Зафиксируем образ:

sudo docker commit CONTAINER_ID stormbp/precise-clean

CONTAINER_ID легко брать из командной строки когда работаете внутри контейнера:

он выглядит так:

root@af40b772abbf:/data/main#

Хеш после root@ и есть ID контейнера.

Имя контейнера (stormbp/precise-clean) поставьте свое, главное обойтись без заглавных букв, будет ошибка.


Запустим новый экземпляр из шаблона:
sudo docker run -i -t stormbp/precise-clean /bin/bash
Внутри контейнера:
cd /root
Качаем дистрибутив postgres с сайта 1с.
wget http://downloads.v8.1c.ru/get/Info/AddCompPostgre/9_2_4_1_1S/postgresql_9_2_4_1_1C_amd64_deb_tar.bz2
Предварительно зайдите туда со своими учетными данными, чтоб авторизоваться. Это можно сделать с любого компьютера в локальной сети.
Распаковываем
tar jxf postgresql_9_2_4_1_1C_amd64_deb_tar.bz2
rm postgresql_9_2_4_1_1C_amd64_deb_tar.bz2
ставим:
dpkg -i *.deb
apt-get -f install
не обращайте внимание, что сервер не инициализировался, сейчас будет творить магию.
exit
Коммитим контейнер
sudo docker commit CONTAINER_ID stormbp/precise-postgress-9.2.4-1c
Создаем в домашней директории хранилище для самой базы:
mkdir -p $HOME/postgresdata
и запускаем экземпляр
sudo docker run -v="$HOME/postgresdata":"/data" -i -t -p 5432 stormbp/precise-postgress-9.2.4-1c /bin/bash

4. Магия, как она есть

А теперь еще немного магии:
Posgresql не запустится, так как по умолчанию, параметр ядра shmmax установлен меньше необходимого. А внутри контейнера поменять его просто так невозможно, /proc/sys смонтирована только на чтение и перемонтировать ее просто так нельзя.
Надо залезть из хостовой системы в контейнер и переписать значение переменной ядра. Для этого есть такой замечательный инструмент nsenter. Но вот разработчики ubuntu усложняют жизнь тем, что не включают его в поставку и в репах его нет.
Будем компилять? - спросите вы.
Зачем? - спрошу я. Ведь у нас есть докер, пусть сам себе накомпиляет в контейнере и удалится, оставив нам только бинарник nsenter на память.
Все просто, в соседнем терминале, на хост системе (не в контейнере с postgress) запускаем:
sudo docker run --rm -v /usr/local/bin:/target jpetazzo/nsenter
docker отработает минут за 5 и удалит все следы оставив нам бинарник nsenter в /usr/local/bin
Теперь снова черная магия:
На хосте отключаем apparmor (на всякий, у некоторых не получается с ним)
/etc/init.d/apparmor stop
узнаем pid запущенного контейнера с postgres
PID=$(docker inspect --format '{{ .State.Pid }}' ID)
ID - подставить из соседнего терминала.
Далее лезем в пространство имен контейнера:
nsenter --target $PID --mount --uts --ipc --net --pid bash
mount -o remount rw /proc/sys
echo 1073741824 > /proc/sys/kernel/shmmax
mount -o remount ro /proc/sys
все, можно инициализировать базу
mkdir -p /data/main chown postgres /data/* chgrp postgres /data/* chmod 700 /data/main
su postgres --command "/usr/lib/postgresql/9.2/bin/initdb -D /data/main --locale=ru_RU.UTF-8"

5. Результат

Получите и распишитесь: база лежит в /data контейнера, или в домашней папке $HOME/postgresdata, доступна локально по сети. Правьте hba как и раньше.
Выходим из контейнера и коммитим образ для множественного развертывания баз данных
sudo docker commit CONTAINER_ID stormbp/1с-9.2.4
Кто работал с постгрессом далее разберется, если не разберетесь, спрашивайте.
На очереди контейнерная виртуализация сервера предприятия для 1с, чтобы жить было совсем весело, а потом статья о том, как же всем этим управлять-то.

2 комментария:

  1. Оформить бы аккуратно. А то запись в одну строку нескольких команд bash разделяя их лишь пробелом даёт читаемость «хуже не придумаешь».

    ОтветитьУдалить
  2. Ещё вопрос (видимо от незнания работы постгри) - движок субд что, используется только при создании бд и не используется при взаимодействии 1с и бд в ходе работы? Или как обеспечивается в данном случае одновременная работа 1с на хосте с базами развернутыми на разнымх версиях постгри?

    ОтветитьУдалить