PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Разгръщане и поддръжка на PostgreSQL с Ansible

Ansible е един от най-известните и широко използвани инструменти за ИТ автоматизация, той ни помага при автоматизирането на оперативни ИТ задачи като...

  • Зареждане на хоста (VM или машина с гол метал) от нулата
  • Конфигуриране на хостове и услуги
  • Управление на внедряването и надстройките на софтуера
  • Ansible също има поддръжка за оркестриране на облачната инфраструктура, като създаване на куп EC2 и RDS екземпляр за вашите приложения в публични облаци (AWS, GCP, Azure). Повече за предоставянето на облак можете да намерите тук

Тъй като този блог е предимно за управление на PostgreSQL с помощта на Ansible, ние няма да навлизаме в подробности за употребите на Ansible, но ще преминем през някои основи на Ansible. Препоръчвам да преминете през връзката към документа Ansible, ако искате да научите повече за него.

Основи на Ansible

Ansible е проект с отворен код, написан на python, чийто изходен код е достъпен в GitHub. Тъй като това е пакет на python, можем лесно да инсталираме Ansible с помощта на pip.

Ansible трябва да бъде инсталиран само на един хост, от който ще организираме нашите оперативни задачи с помощта на команди Ansible (Ansible, Ansible-playbook). Наричаме този хост за оркестрация Контролен възел.

Командите Ansible използват OpenSSH библиотеки за влизане в целевите хостове за изпълнение на оперативни задачи, ние наричаме тези целеви хостове Managed Node. Името на хоста или IP адреса на управлявания възел се споменават във файл, който се нарича Inventory, това име на инвентарния файл след това се посочва като вход към командите Ansible.

Във файла с инвентара можем да изброим няколко хоста в една група, това ще избегне повтарянето на едни и същи задачи няколко пъти за различен хост. Повече подробности за използването на файла за инвентаризация можете да намерите тук.

Тъй като командата Ansible използва SSH за влизане, няма нужда да инсталирате Ansible на всички хостове, тя трябва да бъде инсталирана само на контролния възел. Въпреки това, всички контролни възли и управлявани възли трябва да имат инсталирани python и всички необходими библиотеки на python. Повече за инсталацията на Ansible можете да намерите тук.

За демонстрацията ще използвам лаптоп като контролен възел и гост CentOS-7 VM като управляван възел. Виртуалната машина CentOS-7 беше предоставена с помощта на Vagrant на доставчика VirtualBox.

Инсталиране на Ansible на контролния възел

Ще инсталираме Ansible с помощта на pip, както е посочено в страницата на документа на Ansible. Следните команди бяха изпълнени като „Ansible“ потребител.

$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python get-pip.py --user

Използването на опцията --user прави командите pip и Ansible да бъдат инсталирани в директорията HOME и трябва да добавим пътя на bin към нашата променлива на средата PATH.

$ echo 'export PATH=$HOME/Library/Python/2.7/bin:$PATH' >> ~/.bash_profile
$ source ~/.bash_profile

Следната команда pip е инсталирала Ansible версия 2.8.0 (която е най-новата стабилна версия към момента на писане на този блог.)

$ pip install --user ansible 
$ which ansible
/Users/Ansible/Library/Python/2.7/bin/Ansible
$ ansible --version
Ansible 2.8.0
...
... 

Предварителни проверки на контролен възел и управляван възел

Уверете се, че имате правилна мрежова връзка между контролния и управлявания възел.

Проверете защитната си стена за всякакви правила, които могат да блокират входящи и изходящи връзки на SSH порта, ако е така, отворете SSH порта, за да осигурите достъп както на контролните, така и на управляваните възли.

Първо, опитайте да се свържете чрез SSH към управлявания възел. Трябва да можете да влезете в управлявания възел от контролния възел.

Можете да настроите SSH достъп без парола до управляваните възли в съответствие с политиките за сигурност на вашата организация. За тази демонстрация съм конфигурирал без парола за SSH към моя управляван възел „pg01“ (CentOS-7) за потребителя „vagrant“. Това прави управляваният възел да има силата на sudo, повечето от задачите за инсталиране и конфигурация на хост ще се изпълняват като „скитник“ потребител с „sudo“.

На контролния възел имаме конфигурационния файл ansible.cfg, който ще се използва от командите на Ansible. По-долу са дадени някои опции за конфигурация, които са дефинирани в конфигурационния файл. За да научите повече за другите налични опции за конфигурация, вижте примерния конфигурационен файл.

  • remote_port – Ако SSH сървърът на управлявания възел работи на различен порт, различен от порта по подразбиране 22, можем да го променим
  • remote_user – Потребителското име за вход, което ще се използва от Ansible за свързване на управлявания възел за изпълнение на задачите
  • private_key_file - SSH частен ключ, който ще се използва за Ansible за влизане

Тъй като гореспоменатата конфигурация се прилага глобално за всички управлявани възли, ако искаме да имаме различна конфигурация за конкретен хост или група хостове, можем да ги посочим във файла с инвентара. Можете да видите пример за това по-долу в инвентарния файл „development.yaml“.

Извършване на Ansible Dry Run

Създайте инвентарен файл „development.yaml“, както е показано по-долу.

$ pwd
/Users/Ansible/postgres-setup

$ cat development.yaml 
all:
  hosts:
  children:
    postgres_clusters:
      hosts:
        pg01:
      vars: 
        ansible_port: 22
        ansible_user: "vagrant"
        ansible_private_key_file: "/Users/Ansible/postgres-setup/private_key"

Във файла с инвентара по-горе хост pg01 е един от членовете на хост групата postgres_clusters. Променливите ansible_port, ansible_user и ansible_private_key_file се прилагат само за хостовете в групата postgres_clusters.

Сега ще проверим дали Ansible може да изпълнява задачите на управлявания възел. В примера по-долу командата ansible изпълнява модулен ping на управлявания възел pg01, ако Ansible е успял да изпълни модулния ping, тогава трябва да видите УСПЕХ като отговор.

$ ansible -i development.yaml -m ping pg01
pg01 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}

Когато изпълнява Ansible на управлявания възел като първа задача, той събира информация като име на хост, IP адрес, паметта на управлявания възел. За да проверим това, можем да извикаме настройката на модула, която ще върне голям JSON. Можем да използваме някое от тях в нашата книга с игри на Ansible.

$ ansible -i development.yaml -m setup pg01 
pg01 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.100.4", 
            "10.0.2.15"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::a00:27ff:fe29:ac89", 
            "fe80::5054:ff:fe26:1060"
        ],

Ansible Роля

Ansible Role е начин за обединяване на определен набор от свързани задачи и конфигурационни настройки в една единица само чрез присвояване на роля на конкретен хост или група хостове. Ansible ще приложи цялата свързана конфигурация и задачи. Това избягва повтарянето на задачите многократно за всеки различен хост или хост група.

Всяка роля е представена като директория и в директорията на ролите ще има поддиректории като файлове по подразбиране, манипулатори, мета, задачи, шаблони, тестове, vars. Целта на тези директории може да бъде намерена тук.

Командите Ansible по подразбиране търсят в директорията на ролите по пътищата, посочени в DEFAULT_ROLES_PATH.

$ ansible-config list | grep -A2 '^DEFAULT_ROLES_PATH'
DEFAULT_ROLES_PATH:
  default: ~/.Ansible/roles:/usr/share/Ansible/roles:/etc/Ansible/roles
  description: Colon separated paths in which Ansible will search for Roles.

Галактика Ansible

Ansible Galaxy е портал, където хората от общността споделят хранилището на GitHub на своите роли в Ansible. Можем да прегледаме портала на галактиката за необходимите роли на Ansible. Използвайки командата ansible-galaxy, бихме могли да изтеглим и използваме отново ролята. Преди да използвате роля, прегледайте подробно всички Ansible YAML файлове в директориите по подразбиране, vars, задачи, шаблони, манипулатори и бъдете наясно как работи ролята.

За нашето внедряване на PostgreSQL ще използваме ролята „postgresql“, разработена от автора ANXS и GitHub repo.

Инсталиране на ролята на Ansible “anxs.postgresql”

$ ansible-galaxy  install anxs.postgresql
- downloading role 'postgresql', owned by anxs
- downloading role from https://github.com/ANXS/postgresql/archive/v1.10.1.tar.gz
- extracting anxs.postgresql to /Users/ansible/.Ansible/roles/anxs.postgresql
- anxs.postgresql (v1.10.1) was installed successfully

Горната команда инсталира директорията на ролите „anxs.postgresql“ в директорията „/Users/ansible/.Ansible/roles“, това е една от директориите в DEFAULT_ROLES_PATH и командата ansible ще търси в тази директория всякакви роли.

Ansible Playbook

Ansible Playbook е YAML файл, в който ще изброим задачите или ролите, които трябва да бъдат изпълнени на конкретен хост или групата хостове. Можете да прочетете повече за разработването на учебници, както и да научите дефиницията на тагове като хостове, задачи, роли, vars тук.

По подразбиране всички задачи се изпълняват като ansible потребител, който е влязъл. За да изпълняваме определени задачи с различен потребител (или с привилегия „root“), можем да използваме станови. Как да използвате тази команда можете да намерите тук.

В учебника по-долу (postgres-play.yaml) посочих ролята „anxs.postgresql“ под групата хостове „postgres_clusters“, така че всички задачи в ролята anxs.postgresql ще бъдат изпълнени за всички хостове в групата „postgres_clusters“.

$ cat postgres-play.yaml 
---
- hosts: postgres_clusters
  become: yes
  roles: 
    - role: anxs.postgresql

стане:yes в YAML дефинира, че тази роля ще се изпълнява с по-високи привилегии с помощта на DEFAULT_BECOME_METHOD „sudo“

$ ansible-config list | grep -A2 '^DEFAULT_BECOME_METHOD'
DEFAULT_BECOME_METHOD:
  default: sudo
  description: Privilege escalation method to use when `become` is enabled.

Ще стартираме тази книга с игри като потребител „скитник“ и потребителят вече е снабден с sudo power.

[[email protected] ~]$ sudo cat /etc/sudoers.d/vagrant
%vagrant ALL=(ALL) NOPASSWD: ALL
Severalnines DevOps Ръководство за управление на бази данни Научете какво трябва да знаете, за да автоматизирате и управлявате своите бази данни с отворен код Изтеглете безплатно

Разгръщане на PostgreSQL с помощта на Ansible

Сега ще стартираме плейбета „postgres-play.yaml“, който ще инсталира всички свързани с PostgreSQL пакети и ще го конфигурира с помощта на настройките по подразбиране.

За този пример Ansible ще инсталира PostgreSQL 9.6 на порт 5432, като postgres max_connections е настроен на 100. Всички настройки по подразбиране могат да бъдат намерени във файла /Users/ansible/.Ansible/roles/anxs.postgresql/defaults/main.yml .

$ grep -E '^postgresql_(version|port|max_connections):' ~/.Ansible/roles/anxs.postgresql/defaults/main.yml 
postgresql_version: 9.6
postgresql_port: 5432
postgresql_max_connections: 100

Изпълнение на учебника

$ ansible-playbook -i development.yaml postgres-play.yaml
PLAY [postgres_clusters] ***************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************
ok: [pg01]
...
...


PLAY RECAP *****************************************************************************************************************************************************************************************************
pg01                       : ok=21   changed=14   unreachable=0    failed=0    skipped=32   rescued=0    ignored=0 

След като Ansible изпълни всички задачи, обобщение на изпълнението на задачите ще се покаже под PLAY RECAP.

  • ok=21, 21 задачи са изпълнени без промени.
  • changed=14, 14 задачи направиха промени в хоста, като инсталиране на postgres, създаване на директории, файлове, стартиране на postgres.
  • skipped=32, 32 задачи са пропуснати, може да се дължи на това, че някои функции не са били активирани. Тъй като инсталираме на entOS, свързаните с Ubuntu задачи бяха пропуснати.

Проверете състоянието и конфигурацията на услугата PostgreSQL.

[[email protected] ~]$ systemctl status postgresql-9.6
● postgresql-9.6.service - PostgreSQL 9.6 database server
   Loaded: loaded (/usr/lib/systemd/system/postgresql-9.6.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/postgresql-9.6.service.d
           └─custom.conf
   Active: active (running) since Wed 2019-05-29 07:15:25 UTC; 24min ago
     Docs: https://www.postgresql.org/docs/9.6/static/
  Process: 7559 ExecStartPre=/usr/pgsql-9.6/bin/postgresql96-check-db-dir /var/lib/pgsql/9.6/data (code=exited, status=0/SUCCESS)
 Main PID: 7564 (postmaster)
   CGroup: /system.slice/postgresql-9.6.service
           ├─7564 /usr/pgsql-9.6/bin/postmaster -D /etc/postgresql/9.6/data
           ├─7567 postgres: checkpointer process   
           ├─7568 postgres: writer process   
           ├─7569 postgres: wal writer process   
           ├─7570 postgres: autovacuum launcher process   
           └─7571 postgres: stats collector process   

[[email protected] ~]$ psql -U postgres
psql (9.6.13)
Type "help" for help.

postgres=# show max_connections ;
 max_connections 
-----------------
 100
(1 row)

postgres=# show statement_timeout ;
 statement_timeout 
-------------------
 
(1 row)

postgres=# show log_min_duration_statement ;
 log_min_duration_statement 
----------------------------
 -1
(1 row)

Вече инсталирахме PostgreSQL на управлявания хост „pg01“, използвайки конфигурацията по подразбиране.

Промяна на конфигурацията на PostgreSQL

Сега ще конфигурираме отново екземпляра на PostgreSQL, използвайки нашите персонализирани настройки.

Създадох файл custom.yaml (както е показано по-долу), който има списък с променливи, дефинирани за промяна на настройките на PostgreSQL като listen_addresses, max_connections, wal_level, hot_standby, statement_timeout, log_checkpoint, log_lock_waits, log_destination, log_min_duration_statement.

$ pwd
/Users/ansible/postgres-setup
$ cat custom.yaml 
postgresql_listen_addresses: "*"
postgresql_max_connections: 300
postgresql_wal_level: "hot_standby"
postgresql_hot_standby: "on"
postgresql_statement_timeout: 60000
postgresql_log_lock_waits: "on"
postgresql_log_destination: "csvlog"
postgresql_log_min_duration_statement: 0

Сега ще променим нашата книга с игри postgres-play.yaml, за да използваме този custom.yaml.

$ cat postgres-play.yaml  
---
- hosts: postgres_clusters
  become: yes
  vars_files:
    - ./custom.yaml
  roles: 
    - role: anxs.postgresql

Използвайки vars_files тагове, посочих персонализирания конфигурационен файл custom.yaml, който ще замени конфигурацията по подразбиране, посочена в ролята anxs.postgresql. Повече подробности за приоритета на променливите можете да намерите тук.

Вече можем да изпълним отново същата команда ansible-playbook, която бяхме изпълнили преди, но това ще изпълни всички задачи като инсталиране на PostgreSQL, конфигуриране, създаване на потребители и бази данни. За това трябва да ограничим Ansible да изпълнява само задачите, свързани с конфигурацията на PostgreSQL, като използваме опцията --tags .

За да знаем списъка с поддържани тагове, можем да изпълним командата с --list-tags.

$ ansible-playbook -i development.yaml postgres-play.yaml --list-tags
playbook: postgres-play.yaml
  play #1 (postgres_clusters): postgres_clusters        TAGS: []
      TASK TAGS: [always, postgresql, postgresql-configure, postgresql-databases, postgresql-extensions, postgresql-install, postgresql-monit, postgresql-users]

От горните тагове ще посочим само маркер postgresql-configure за промяна на настройките на postgresql.

$ ansible-playbook  -i development.yaml postgres-play.yaml --tags postgresql-configure

PLAY [postgres_clusters] ***************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************
ok: [pg01]
...
...

TASK [anxs.postgresql : PostgreSQL | Update configuration - pt. 2 (postgresql.conf)] ***************************************************************************************************************************
changed: [pg01]
...
...
TASK [anxs.postgresql : PostgreSQL | Reload all conf files] ****************************************************************************************************************************************************
changed: [pg01]

PLAY RECAP *****************************************************************************************************************************************************************************************************
pg01                       : ok=13   changed=2    unreachable=0    failed=0    skipped=6    rescued=0    ignored=0

Както виждате в PLAY RECAP, само 2 промени са разпространени до управлявания възел pg01. Първият е актуализиране на конфигурацията, а вторият е презареждане на конфигурациите.

Проверете дали промените в конфигурацията са влезли в сила на управлявания възел.

postgres=# show listen_addresses ;
 listen_addresses
------------------
 localhost
(1 row)

postgres=# show max_connections ;
 max_connections 
-----------------
 100
(1 row)

postgres=# show wal_level ;
 wal_level 
-----------
 minimal
(1 row)

postgres=# show hot_standby ;
 hot_standby 
-------------
 off
(1 row)

postgres=# show statement_timeout;
 statement_timeout 
-------------------
 1min
(1 row)

postgres=# show log_lock_waits ;
 log_lock_waits 
----------------
 on
(1 row)

postgres=# show log_destination ;
 log_destination 
-----------------
 csvlog
(1 row)

postgres=# show log_min_duration_statement;
 log_min_duration_statement 
----------------------------
 
(1 row)

Както можете да видите, някои конфигурации се променят като listen_addresses, max_connections, wal_level, hot_standby все още не са влезли в сила. Тези промени в конфигурацията изискват рестартиране на PostgreSQL и ролята anxs.postgresql само презареди самата услуга.

За да се избегне внезапно рестартиране на PostgreSQL по време на производствените часове, първоначалният автор може да не е добавил задачата за рестартиране към ролята. Можем ръчно да рестартираме услугата postgresql по време на планирания престой.

[[email protected] ~]$ sudo systemctl restart postgresql-9.6

[[email protected] ~]$ psql -U postgres
psql (9.6.13)

postgres=# show listen_addresses ;
 listen_addresses 
------------------
 
(1 row)

postgres=# show max_connections ;
 max_connections 
-----------------
 300
(1 row)

postgres=# show wal_level;
 wal_level 
-----------
 replica
(1 row)

postgres=# show hot_standby;
 hot_standby 
-------------
 on
(1 row)

Създаване на PostgreSQL потребители и бази данни

Сега ще създадем потребителите „app1“ и „app2“ и базите данни „app1_db“ и „app2_db“, притежавани съответно от потребителите „app1“ и „app2“.

Добавих две нови променливи, postgresql_users и postgresql_database към custom.yaml, който има списък с потребители и бази данни, които трябва да бъдат създадени. Ролята anxs.postgresql използва модула Ansible postgresql_users и postgresql_db за създаване на потребителя и базата данни. Можете да се обърнете към тези документи, за да добавите променливите.

$ cat custom.yaml 
...
...
postgresql_users:
  - name: app1
    pass: md5bb0592c05941d14c231da96950c71b60
    encrypted: yes
  - name: app2
    pass: md5bbb1e4d09b64ca54a237727af46cba7c
    encrypted: yes

postgresql_databases:
  - name: app1_db
    owner: app1 
  - name: app2_db
    owner: app2 

Сега ще изпълняваме само задачите, свързани с таговете postgresql-users и postgresql-databases.

$ ansible-playbook -i development.yaml postgres-play.yaml --tags postgresql-users,postgresql-databases

PLAY [postgres_clusters] ***************************************************************************************************************************************************************************************
...
...
TASK [anxs.postgresql : PostgreSQL | Make sure the PostgreSQL users are present] *******************************************************************************************************************************
changed: [pg01] => (item=None)
changed: [pg01] => (item=None)
changed: [pg01]
...
...
TASK [anxs.postgresql : PostgreSQL | Make sure the PostgreSQL databases are present] ***************************************************************************************************************************
changed: [pg01] => (item={u'owner': u'app1', u'name': u'app1_db'})
changed: [pg01] => (item={u'owner': u'app2', u'name': u'app2_db'})
...
...
PLAY RECAP *****************************************************************************************************************************************************************************************************
pg01                       : ok=6    changed=2    unreachable=0    failed=0    skipped=9    rescued=0    ignored=0

Проверете дали потребителите и базите данни са създадени на управлявания хост.

postgres=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of 
-----------+------------------------------------------------------------+-----------
 app1      |                                                            | {}
 app2      |                                                            | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

postgres=# \l
                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-----------+----------+----------+-------------+-------------+-----------------------
 app1_db   | app1     | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 app2_db   | app2     | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
(5 rows)

Разрешаване на външни хостове да се свързват към PostgreSQL сървъра

Сега ще позволим на външните хостове да свържат услугата PostgreSQL, като добавим променливата postgresql_pg_hba_custom към custom.yaml

$ cat custom.yaml
...
...
postgresql_pg_hba_custom:
  - {type: "host", database: "all", user: "all", address: "0.0.0.0/0", method: "md5" }

Изпълнение на задачите, маркирани с postgresql-configure, за прилагане на конфигурацията.

$ ansible-playbook -i development.yaml postgres-play.yaml --tags postgresql-configure

Проверявам дали мога да се свържа със сървъра на PostgreSQL от моя контролен възел.

$ PGPASSWORD=password psql -h pg01 -U app1 -d app1_db -c 'Select true'
 bool
------
 
(1 row)

Заключение

Този блог трябва да ви даде основите, които трябва да знаете, за да използвате Ansible за внедряване и управление на PostgreSQL. Ние обаче покрихме само няколко административни задачи на PostgreSQL. В зависимост от инфраструктурата на вашата организация, може да се наложи да замените няколко от конфигурациите по подразбиране и да добавите още повече задачи към ролята Ansible.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. реда на колоните в израза SELECT * - гарантиран?

  2. Съхраняване на дълги двоични (сурови) низове

  3. Ограничете потребителския достъп на PostgreSQL с помощта на схема и изгледи

  4. Какъв е правилният индекс за запитване на структури в масиви в Postgres jsonb?

  5. Сървърът работи ли на хост localhost (::1) и приема ли TCP/IP връзки на порт 5432?