Ansible je jedním z nejznámějších a nejrozšířenějších nástrojů pro automatizaci IT, pomáhá nám při automatizaci provozních úloh IT, jako jsou...
- Zavedení hostitele (VM nebo holého počítače) od začátku
- Konfigurace hostitelů a služeb
- Správa nasazení a upgradů softwaru
- Ansible má také podporu pro orchestraci cloudové infrastruktury, jako je vytvoření spousty instancí EC2 a RDS pro vaše aplikace ve veřejných cloudech (AWS, GCP, Azure). Více o poskytování cloudu naleznete zde
Vzhledem k tomu, že tento blog je převážně o správě PostgreSQL pomocí Ansible, nebudeme zabíhat do podrobností o použití Ansible, ale projdeme si některé základy Ansible. Pokud se o něm chcete dozvědět více, doporučuji projít odkaz na dokument Ansible.
Základy Ansible
Ansible je open-source projekt napsaný v pythonu, jehož zdrojový kód je dostupný na GitHubu. Protože se jedná o balíček python, můžeme Ansible snadno nainstalovat pomocí pip.
Ansible musí být nainstalován pouze na jednom hostiteli, ze kterého budeme organizovat naše provozní úkoly pomocí příkazů Ansible (Ansible, Ansible-playbook). Tomuto hostiteli orchestrace říkáme řídicí uzel.
Příkazy Ansible používají knihovny OpenSSH k přihlášení k cílovým hostitelům za účelem provádění provozních úloh, těmto cílovým hostitelům říkáme Managed Node. Název hostitele nebo IP adresa spravovaného uzlu jsou uvedeny v souboru, který se nazývá Inventory, tento název souboru inventáře je pak určen jako vstup pro příkazy Ansible.
V souboru inventáře můžeme uvést více hostitelů pod jednu skupinu, čímž se vyhneme opakování stejných úloh vícekrát pro různé hostitele. Další podrobnosti o použití souboru inventáře naleznete zde.
Vzhledem k tomu, že příkaz Ansible používá k přihlášení SSH, není třeba instalovat Ansible na všechny hostitele, stačí jej nainstalovat na řídicí uzel. Všechny řídicí uzel a spravovaný uzel by však měly mít nainstalovaný python a všechny potřebné knihovny pythonu. Více o instalaci Ansible naleznete zde.
Pro demo budu používat notebook jako řídicí uzel a hostující CentOS-7 VM jako spravovaný uzel. Virtuální počítač CentOS-7 byl zřízen pomocí Vagrant na poskytovateli VirtualBox.
Instalace Ansible na řídicí uzel
Nainstalujeme Ansible pomocí pip, jak je uvedeno na stránce dokumentu Ansible. Následující příkazy byly provedeny jako uživatel „Ansible“.
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python get-pip.py --user
Pomocí volby --user se příkazy pip a Ansible nainstalují do adresáře HOME a my potřebujeme přidat cestu bin do naší proměnné prostředí PATH.
$ echo 'export PATH=$HOME/Library/Python/2.7/bin:$PATH' >> ~/.bash_profile
$ source ~/.bash_profile
Následující příkaz pip nainstaloval Ansible verzi 2.8.0 (což je nejnovější stabilní verze v době psaní tohoto blogu.)
$ pip install --user ansible
$ which ansible
/Users/Ansible/Library/Python/2.7/bin/Ansible
$ ansible --version
Ansible 2.8.0
...
...
Předběžné kontroly řídicího uzlu a spravovaného uzlu
Ujistěte se, že máte správné síťové připojení mezi řídicím uzlem a spravovaným uzlem.
Zkontrolujte bránu firewall, zda neobsahuje pravidla, která mohou blokovat příchozí a odchozí připojení na portu SSH, pokud ano, otevřete port SSH, abyste poskytli přístup jak řídicím, tak spravovaným uzlům.
Nejprve se zkuste připojit přes SSH ke spravovanému uzlu. Měli byste být schopni se přihlásit ke spravovanému uzlu z řídicího uzlu.
Můžete nastavit přístup SSH bez hesla ke spravovaným uzlům podle zásad zabezpečení vaší organizace. Pro tuto ukázku jsem nakonfiguroval SSH bez hesla pro můj spravovaný uzel „pg01“ (CentOS-7) pro uživatele „vagrant“. Díky tomu má spravovaný uzel sílu sudo, většina úloh instalace a konfigurace hostitele bude prováděna jako „tulák“ uživatel pomocí „sudo“.
Na řídicím uzlu máme konfigurační soubor ansible.cfg, který budou používat příkazy Ansible. Níže jsou uvedeny některé možnosti konfigurace, které jsou definovány v konfiguračním souboru. Chcete-li se dozvědět více o dalších dostupných možnostech konfigurace, podívejte se na ukázkový konfigurační soubor.
- vzdálený_port – Pokud server SSH na spravovaném uzlu běží na jiném portu, než je výchozí port 22, můžeme jej změnit
- remote_user – přihlašovací uživatelské jméno, které bude Ansible používat k připojení spravovaného uzlu pro spouštění úloh
- private_key_file – soukromý klíč SSH, který bude použit pro přihlášení Ansible
Protože výše uvedená konfigurace platí globálně pro všechny spravované uzly, pokud chceme mít jinou konfiguraci pro konkrétního hostitele nebo skupinu hostitelů, můžeme je specifikovat v souboru inventáře. Příklad toho můžete vidět níže v inventárním souboru „development.yaml“.
Provedení Ansible Dry Run
Vytvořte soubor inventáře „development.yaml“, jak je znázorněno níže.
$ 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"
V inventárním souboru výše je hostitel pg01 jedním z členů hostitelské skupiny postgres_clusters. Proměnné ansible_port, ansible_user a ansible_private_key_file platí pouze pro hostitele ve skupině postgres_clusters.
Nyní zkontrolujeme, zda Ansible může spouštět úlohy na spravovaném uzlu. V níže uvedeném příkladu příkaz ansible provede modul ping na spravovaném uzlu pg01, pokud Ansible dokázal spustit modul ping, měli byste jako odpověď vidět ÚSPĚCH.
$ ansible -i development.yaml -m ping pg01
pg01 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
Když Ansible spustíte na spravovaném uzlu jako první úlohu, shromažďuje informace, jako je název hostitele, IP adresa, paměť spravovaného uzlu. Abychom to ověřili, můžeme zavolat nastavení modulu, které by vrátilo velký JSON. Můžeme použít kterékoli z nich v naší příručce 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 role
Ansible Role je způsob, jak sloučit určitou sadu souvisejících úloh a konfiguračních nastavení do jediné jednotky pouhým přiřazením role konkrétnímu hostiteli nebo skupině hostitelů. Ansible použije všechny související konfigurace a úkoly. Tím se zabrání opakování úkolů vícekrát pro každého jiného hostitele nebo skupinu hostitelů.
Každá role je reprezentována jako adresář a v adresáři role budou podadresáře jako výchozí soubory, obslužné rutiny, meta, úlohy, šablony, testy, vars. Účel těchto adresářů naleznete zde.
Příkazy Ansible ve výchozím nastavení prohledávají adresář role pod cestami uvedenými v 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.
Galaxie Ansible
Ansible Galaxy je portál, kde lidé z komunity sdílejí úložiště GitHub svých rolí Ansible. Můžeme procházet portálem galaxie a hledat požadované role Ansible. Pomocí příkazu ansible-galaxy jsme mohli stáhnout a znovu použít roli. Před použitím role si podrobně projděte všechny soubory Ansible YAML v adresářích defaults, vars, tasks, templates, handlers a uvědomte si, jak role funguje.
Pro naše nasazení PostgreSQL použijeme roli „postgresql“ vyvinutou autorem ANXS a GitHub repo.
Instalace role 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
Výše uvedený příkaz nainstaluje adresář role „anxs.postgresql“ do adresáře „/Users/ansible/.Ansible/roles“, toto je jeden z adresářů v DEFAULT_ROLES_PATH a příkaz ansible v tomto adresáři vyhledá všechny role.
Příručka Ansible
Ansible Playbook je soubor YAML, ve kterém vypíšeme úkoly nebo role, které je třeba provést na konkrétním hostiteli nebo skupině hostitelů. Zde si můžete přečíst více o vývoji příruček a také se dozvědět o definici značek, jako jsou hostitelé, úkoly, role, proměnná.
Ve výchozím nastavení jsou všechny úlohy prováděny jako oprávněný uživatel, který se přihlásil. Pro provádění konkrétních úloh s jiným uživatelem (nebo s oprávněním „root“) můžeme využít příkazu. Jak tento příkaz použít, najdete zde.
V playbooku níže (postgres-play.yaml) jsem uvedl roli „anxs.postgresql“ pod hostitelskou skupinou „postgres_clusters“, takže všechny úkoly v roli anxs.postgresql budou provedeny pro všechny hostitele ve skupině. „postgres_clusters“.
$ cat postgres-play.yaml
---
- hosts: postgres_clusters
become: yes
roles:
- role: anxs.postgresql
stát:ano v YAML definuje, že tato role bude vykonávána s vyšším oprávněním pomocí 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.
Tuto příručku spustíme jako uživatel „tulák“ a uživateli již byla poskytnuta funkce sudo.
[[email protected] ~]$ sudo cat /etc/sudoers.d/vagrant
%vagrant ALL=(ALL) NOPASSWD: ALL
Několik nines DevOps Průvodce správou databázíZjistěte, co potřebujete vědět k automatizaci a správě vašich databází s otevřeným zdrojovým kódemStáhněte si zdarma Nasazení PostgreSQL pomocí Ansible
Nyní spustíme playbook ‚postgres-play.yaml‘, který nainstaluje všechny balíčky související s PostgreSQL a nakonfiguruje jej pomocí výchozího nastavení.
Pro tento příklad Ansible nainstaluje PostgreSQL 9.6 na port 5432 s postgres max_connections nastaveným na 100. Všechna výchozí nastavení lze nalézt v souboru /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
Spuštění příručky
$ 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
Jakmile Ansible provede všechny úkoly, v části PLAY RECAP se zobrazí souhrn provedených úkolů.
- ok=21, 21 úloh provedených beze změn.
- changed=14, 14 úkolů provedlo změny na hostiteli, jako je instalace postgresu, vytvoření adresářů, souborů, spuštění postgresu.
- přeskočeno=32, 32 úkolů bylo přeskočeno, může to být způsobeno tím, že některá funkce nebyla povolena. Protože instalujeme na entOS, úlohy související s Ubuntu byly přeskočeny.
Zkontrolujte stav a konfiguraci služby 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)
Nyní jsme nainstalovali PostgreSQL na spravovaném hostiteli „pg01“ pomocí výchozí konfigurace.
Změna konfigurace PostgreSQL
Nyní znovu nakonfigurujeme instanci PostgreSQL pomocí našich vlastních nastavení.
Vytvořil jsem soubor custom.yaml (jak je uvedeno níže), který obsahuje seznam proměnných definovaných pro úpravu nastavení PostgreSQL, jako jsou 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
Nyní změníme náš playbook postgres-play.yaml tak, aby používal tento custom.yaml.
$ cat postgres-play.yaml
---
- hosts: postgres_clusters
become: yes
vars_files:
- ./custom.yaml
roles:
- role: anxs.postgresql
Pomocí značek vars_files jsem zadal vlastní konfigurační soubor custom.yaml, který přepíše výchozí konfiguraci zadanou v roli anxs.postgresql. Další podrobnosti o proměnné prioritě naleznete zde.
Nyní bychom mohli znovu spustit stejný příkaz ansible-playbook, který jsme provedli dříve, ale to provede všechny úkoly, jako je instalace PostgreSQL, konfigurace, vytváření uživatelů a databází. Za tímto účelem bychom měli omezit Ansible pouze na provádění úloh souvisejících s konfigurací PostgreSQL pomocí volby --tags
Abychom znali seznam podporovaných značek, mohli bychom spustit příkaz s --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]
Z výše uvedených značek určíme pouze značku postgresql-configure pro úpravu nastavení 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
Jak vidíte v PLAY RECAP, do spravovaného uzlu pg01 se rozšířily pouze 2 změny. První je aktualizace konfigurace a druhá znovu načítání konfigurací.
Ověřte, že se změny konfigurace projevily na spravovaném uzlu.
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)
Jak můžete vidět, některé změny konfigurací jako listen_addresses, max_connections, wal_level, hot_standby se ještě neprojevily. Tyto změny konfigurace vyžadují restart PostgreSQL a role anxs.postgresql pouze znovu načetla samotnou službu.
Aby se předešlo náhlému restartu PostgreSQL během provozní doby, původní autor možná nepřidal do role úlohu restartu. Během plánovaného výpadku můžeme ručně restartovat službu 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)
Vytváření uživatelů a databází PostgreSQL
Nyní vytvoříme uživatele „app1“ a „app2“ a databáze „app1_db“ a „app2_db“ vlastněné uživateli „app1“ a „app2“.
Přidal jsem dvě nové proměnné, postgresql_users a postgresql_database do custom.yaml, který obsahuje seznam uživatelů a databází, které je třeba vytvořit. Role anxs.postgresql používá modul Ansible postgresql_users a postgresql_db pro vytvoření uživatele a databáze. Chcete-li přidat proměnné, můžete se obrátit na tyto dokumenty.
$ 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
Nyní spustíme pouze úlohy spojené se značkami postgresql-users a 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
Ověřte, že uživatelé a databáze jsou vytvořeny na spravovaném hostiteli.
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)
Povolení připojení externích hostitelů k serveru PostgreSQL
Nyní umožníme externím hostitelům připojit se ke službě PostgreSQL přidáním proměnné postgresql_pg_hba_custom do custom.yaml
$ cat custom.yaml
...
...
postgresql_pg_hba_custom:
- {type: "host", database: "all", user: "all", address: "0.0.0.0/0", method: "md5" }
Spuštěním úloh označených postgresql-configure pro použití konfigurace.
$ ansible-playbook -i development.yaml postgres-play.yaml --tags postgresql-configure
Ověřuji, zda se mohu připojit k serveru PostgreSQL z mého řídicího uzlu.
$ PGPASSWORD=password psql -h pg01 -U app1 -d app1_db -c 'Select true'
bool
------
(1 row)
Závěr
Tento blog by vám měl poskytnout základy, které potřebujete vědět, abyste mohli používat Ansible pro nasazení a správu PostgreSQL. Pokryli jsme však pouze několik úloh správy PostgreSQL. V závislosti na infrastruktuře vaší organizace možná budete muset přepsat několik výchozích konfigurací a přidat do role Ansible ještě více úloh.