PostgreSQL в Azure. Часть 1
Этой статьей мы начинаем цикл заметок об использовании PostgreSQL в Microsoft Azure.
Первая статья будет об установке и настройке кластера PostgreSQL:
- Знакомство с ресурсами Azure
- Управление через azure cli
- Выбор подходящего хранилища
- Сборка классической связки ведущий-ведомый в одной группе доступности
Задача этой части — реализовать схему, включающую следующие компоненты, ресурсы Azure:
Делать мы будем это при помощи azure cli. Вы можете не устанавливать azure-cli и сделать все через веб-интерфейс portal.azure.com, но управление и создание через cli мне показалось более наглядным.
Утилита azure cli кроссплатформенная и работает везде, где можно работает nodejs. Установить ее под linux можно так:
# dnf install npm || apt-get install npm
NPM_CONFIG_PREFIX=~/.npm-global npm install -g 'git://github.com/Azure/azure-xplat-cli.git#v0.9.20-April2016'
echo 'NPM_PACKAGES="$HOME/.npm-global"' >> ~/.bash_profile
echo 'export PATH="$PATH:$NPM_PACKAGES/bin"' >> ~/.bash_profile
Ознакомиться с основными командами azure cli можно здесь. Все последующие команды azure cli запускаются с вашего рабочего компьютера. Начнем с того, что нам необходимо представиться системе и получить токен:
azure login
Подробнее про способы авторизации можно прочитать здесь.
Создаем группу ресурсов (контейнер ресурсов) в Северной Европе:
azure group create --name pg-resource-group --location northeurope
Создаем виртуальную локальную сеть 10.0.0.0/8 и подсеть 10.0.0.0/24:
azure network vnet create -g pg-resource-group -l northeurope --address-prefixes 10.0.0.0/8 --name pg-vnet
azure network vnet subnet create -g pg-resource-group --vnet-name pg-vnet --address-prefix 10.0.0.0/24 --name pg-vnet-subnet
Так как управлять мы собираемся через ssh по внешнему ip-адресу, создаем правила сетевого экрана и разрешаем подключения извне только к 22 порту:
azure network nsg create -g pg-resource-group -l northeurope --name pg-nsg
azure network nsg rule create -g pg-resource-group --nsg-name pg-nsg --name AllowSSH --protocol Tcp --access Allow --destination-port-range 22 --priority 200 --direction Inbound
Настраиваем внешний ip-адрес (public-ip), сетевой адаптер с приватной сетью и подсеть для ведущего:
azure network public-ip create -g pg-resource-group -l northeurope --allocation-method Static --name pg-public-1
azure network nic create -g pg-resource-group -l northeurope --subnet-name pg-vnet-subnet --subnet-vnet-name pg-vnet --private-ip-address 10.0.0.101 --network-security-group-name pg-nsg --name pg-nic-1
Создаем группу доступности. Вкратце это кластер машин, разделенный на группы (домены), которые не могут быть недоступны одновременно:
azure availset create -g pg-resource-group -l northeurope --name pg-availability-set
Подробнее про группы доступности можно прочитать здесь.
Настало время настройки виртуальной машины. Доступные типы виртуальных машин и их ограничения можно узнать через команду:
azure vm sizes -l northeurope
В списке будет более 50 типов машин, с ценами можно ознакомиться здесь. К более дешевым можно подключить меньшее количество дисков (общее количество дисков может быть от 1 до 40). Для тестирования мастера выбран Standard_DS4_v2: 8 CPU, 28GB RAM, к которому можно подключить до 16 дисков premium storage.
Команда создания виртуальной машины, которая подразумевает пользователя pg с sudo-правами и разрешеным входом по ssh с применением ssh-ключа:
azure vm create -g pg-resource-group -l northeurope --nic-name pg-nic-1 --os-type Linux --image-urn OpenLogic:CentOS:7.2:latest --admin-username pg --ssh-publickey-file ~/.ssh/id_rsa.pub --vm-size Standard_DS4_v2 --public-ip-name pg-public-1 --availset-name pg-availability-set --name pg-1
Посмотреть параметры созданной машины, а также внешние ip, можно через команду:
azure vm show -g pg-resource-group --name pg-1
Теперь мы имеем виртуальную машину с установленной CentOS 7.2, запущенной в приватной виртуальной сети pg-vnet с ip-адресом 10.0.0.101 и публичным pg-public-1, по которому мы можем попасть на ssh извне. Необходимо создать диск, на котором будут расположены данные нашего PostgreSQL. Про различные типы хранилищ можно почитать тут. Для начала представим результаты нашего тестирования хранилища:
Создадим аккаунт хранилища Premium LRS с именем pgplrs (оно должно быть уникальным в пределах azure):
azure storage account create -g pg-resource-group -l northeurope --type PLRS pgplrs
Создадим диск и подключим его к виртуальной машине:
azure vm disk attach-new -g pg-resource-group -l northeurope --vm-name pg-1 --lun 1 --size-in-gb 512 --vhd-name pgdata-1 --host-caching ReadOnly --storage-account-name pgplrs
Создадим и запустим виртуальную машину pg-2:
azure network public-ip create -g pg-resource-group -l northeurope --allocation-method Static --name pg-public-2
azure network nic create -g pg-resource-group -l northeurope --subnet-name pg-vnet-subnet --subnet-vnet-name pg-vnet --private-ip-address 10.0.0.102 --network-security-group-name pg-nsg --name pg-nic-2
azure vm create -g pg-resource-group -l northeurope --nic-name pg-nic-2 --os-type Linux --image-urn OpenLogic:CentOS:7.2:latest --admin-username pg --ssh-publickey-file ~/.ssh/id_rsa.pub --vm-size Standard_DS4_v2 --public-ip-name pg-public-1 --availset-name pg-availability-set --name pg-2
azure vm disk attach-new -g pg-resource-group -l northeurope --vm-name pg-2 --lun 1 --size-in-gb 512 --vhd-name pgdata-2 --host-caching ReadOnly --storage-account-name pgplrs
azure vm start -g pg-resource-group pg-2
Теперь мы можем подключиться по ssh к pg-1 под пользователем pg:
ssh pg-public-1 -l pg -i ~/.ssh/id_rsa
Все дальнейшие действия мы будем выполнять на машине pg-1. Сразу после подключения диска нужно его сопоставить с физическим блочным устройством, доступным на виртуальной машине. Для этого запускаем команду:
[root@pg-1 ~] $ dmesg | tail -n 10
[ 488.417024] Adjusting hyperv_clocksource more than 11% (1945964553 vs 1862270976)
[ 525.969741] scsi 5:0:0:0: Direct-Access Msft Virtual Disk 1.0 PQ: 0 ANSI: 4
[ 526.001471] sd 5:0:0:0: Attached scsi generic sg3 type 0
[ 526.018792] sd 5:0:0:0: [sdc] 1073741824 512-byte logical blocks: (549 GB/512 GiB)
[ 526.039690] sd 5:0:0:0: [sdc] 4096-byte physical blocks
[ 526.053643] sd 5:0:0:0: [sdc] Write Protect is off
[ 526.065818] sd 5:0:0:0: [sdc] Mode Sense: 0f 00 10 00
[ 526.065985] sd 5:0:0:0: [sdc] Write cache: enabled, read cache: enabled, supports DPO and FUA
[ 526.091754] sdc: unknown partition table
[ 526.105263] sd 5:0:0:0: [sdc] Attached SCSI disk
Из этих сообщений можно понять, что имя блочного устройства, назначенного подключенному диску: /dev/sdc. Создаем на нем файловую систему:
[root@pg-1 ~] $ mkfs.ext4 /dev/sdc
mke2fs 1.42.9 (28-Dec-2013)
/dev/sdc is entire device, not just one partition!
Proceed anyway? (y,n) y
Теперь мы должны создать запись в fstab. Получаем UUID устройства:
[root@pg-1 ~] $ blkid /dev/sdc
/dev/sdc: UUID="8cb25a32-175b-4c78-b557-8153327d48ba" TYPE="ext4"
И монтируем диск, предварительно создав точку монтирования и добавив запись в fstab:
[root@pg-1 ~] $ mkdir -p /var/lib/pgsql
[root@pg-1 ~] $ echo 'UUID=8cb25a32-175b-4c78-b557-8153327d48ba /var/lib/pgsql ext4 defaults 0 0' >> /etc/fstab
[root@pg-1 ~] $ mount -a
Пришло время установки софта, подключаем репозиторий:
[root@pg-1 ~] $ rpm -ivh http://repo.postgrespro.ru/pgpro-9.5/keys/postgrespro-9.5.centos95.noarch.rpm
Устанавливаем софт:
[root@pg-1 ~] $ yum install postgrespro95-server postgrespro95-contrib
Включаем сервис и инициализируем экземпляр СУБД:
[root@pg-1 ~] $ chkconfig postgresql-9.5 on
[root@pg-1 ~] $ service postgresql-9.5 initdb
[root@pg-1 ~] $ service postgresql-9.5 start
Дальнейшие команды мы будем выполнять под пользователем postgres:
[root@pg-1 ~] $ su -l postgres
Разрешаем подключение к серверу в pg_hba с ip 10.0.0.101–102 для репликации:
[postgres@pg-1 ~] $ echo 'host replication replication 10.0.0.101/30 md5' >> /var/lib/pgsql/9.5/data/pg_hba.conf
Создаем пользователя для репликации:
[postgres@pg-1 ~] $ /usr/pgsql-9.5/bin/psql -U postgres postgres
postgres=$ CREATE ROLE replication WITH REPLICATION PASSWORD 'password' LOGIN;
CREATE ROLE
Выставляем параметры, позволяющие использовать эту машинку как ведущий сервер для репликации:
[postgres@pg-1 ~] $ /usr/pgsql-9.5/bin/psql -U postgres postgres
postgres=$ alter system set listen_addresses to '*';
ALTER SYSTEM
postgres=$ alter system set wal_level to hot_standby;
ALTER SYSTEM
postgres=$ alter system set max_wal_senders to 3;
ALTER SYSTEM
postgres=$ alter system set wal_keep_segments to 128;
ALTER SYSTEM
Проверяем, применены ли параметры:
postgres=$ select * from pg_file_settings where not applied;
sourcefile | sourceline | seqno | name | setting | applied
----------------------------------------------+------------+-------+------------------+-------------+---------
/var/lib/pgsql/9.5/data/postgresql.auto.conf | 3 | 20 | wal_level | hot_standby | f
/var/lib/pgsql/9.5/data/postgresql.auto.conf | 4 | 21 | max_wal_senders | 3 | f
/var/lib/pgsql/9.5/data/postgresql.auto.conf | 6 | 23 | listen_addresses | * | f
(3 rows)
Перезапускаем службу:
[postgres@pg-1 ~] $ /usr/pgsql-9.5/bin/pg_ctl restart -D /var/lib/pgsql/9.5/data -w
Теперь мы можем подключиться по ssh к pg-2 под пользователем pg:
ssh pg-public-2 -l pg -i ~/.ssh/id_rsa
Все дальнейшие команды мы выполняем на машине pg-2. Пришло время заняться репликой: аналогично подключаем диск и устанавливаем postgrespro. И выполняем вход на pg-2 под пользователем postgres:
[root@pg-2 ~] $ su -l postgres
После этого подготавливаем реплику одной командой:
[postgres@pg-2 ~] $ /usr/pgsql-9.5/bin/pg_basebackup -U replication -D /var/lib/pgsql/9.5/data -R -x -P -c spread -h 10.0.0.101 -W
Password:
38895/38895 kB (100%), 1/1 tablespace
Теперь у нас есть полная копия в /var/lib/pgsql/9.5/data
и прописанный файл recovery.conf
, в который рекомендую добавить информацию о файле-триггере, при создании которого этот экземпляр СУБД из ведомого превратится в полноценный ведущий сервер. Таким образом, содержимое файла будет такое:
[postgres@pg-2 ~] $ cat /var/lib/pgsql/9.5/data/recovery.conf
standby_mode = 'on'
primary_conninfo = 'user=replication password=password host=10.0.0.101 port=5432 sslmode=prefer sslcompression=1 krbsrvname=postgres'
trigger_file = '/var/lib/pgsql/stop_replication_trigger'
Запускаем экземпляр с репликой:
[postgres@pg-2 ~] $ /usr/pgsql-9.5/bin/pg_ctl start -w -D /var/lib/pgsql/9.5/data
И проверяем, запущен ли приёмник WAL (процесс wal receiver):
[postgres@pg-2 ~] $ ps axufwwww
postgres 29423 0.1 0.2 372920 16564 ? S 09:07 0:00 /usr/pgsql-9.5/bin/postmaster -D /var/lib/pgsql/9.5/data
postgres 29425 0.0 0.0 225568 1608 ? Ss 09:07 0:00 \_ postgres: logger process
postgres 29426 0.1 0.0 372960 2464 ? Ss 09:07 0:00 \_ postgres: startup process recovering 0000010000000000000003
postgres 29427 0.0 0.0 372920 1964 ? Ss 09:07 0:00 \_ postgres: checkpointer process
postgres 29428 0.0 0.0 372920 1976 ? Ss 09:07 0:00 \_ postgres: writer process
postgres 29429 0.2 0.0 379640 3360 ? Ss 09:07 0:00 \_ postgres: wal receiver process streaming 0/3000060
Итого мы имеем две виртуальные машины, между которыми настроена потоковая асинхронная репликация, работающая в одной группе доступности. В следующей части статьи мы обсудим резервные копии и балансировку клиентов.
Ждите продолжения!