0. Įvadas į Ansible playbook
Pamokoje Darbo su Ansible pradžia paaiškinome darbo su Ansible pagrindus: kaip sukurti Ansible inventory, nuotoliniu būdu prisijungti prie kitų serverių ir vykdyti juose komandas.
Pavyzdžiui, šią komandą galite paleisti norėdami patikrinti disko užimtumą konkrečiuose serveriuose:
ansible all -i inventory.ini -a "df -h"
Pavienėms komandoms tai puikiai tinka, bet sudėtingesnėms užduotims jau nelabai. Tarkime, reikia atnaujinti galimų paketų sąrašą, įdiegti Nginx, jį paleisti ir įjungti automatinį paleidimą:
sudo apt update
sudo apt install nginx
sudo systemctl start nginx
sudo systemctl enable nginx
Kartoti šias komandas rankiniu būdu keliuose serveriuose vėl ir vėl yra nepatogu ir užima daug laiko, ypač kai serverių daug. Būtent tokiems atvejams ir sukurti Ansible playbook.
Playbook yra scenarijus, tiksliai nurodantis, ką Ansible turi daryti: įdiegti paketus, sukurti naudotojus, nukopijuoti failus ar paleisti tarnybą iš naujo. Iš esmės tai paprastas užduočių sąrašas, todėl playbook greitai perskaitomas ir lengvai redaguojamas.
Keli užduočių, kurias su playbook galima vykdyti keliuose serveriuose vienu metu, pavyzdžiai:
programinės įrangos diegimas;
failų ir katalogų kūrimas;
tarnybų konfigūravimas;
sistemos naudotojų valdymas.
0.1 Kaip veikia Ansible playbook
Playbook yra failas, parašytas YAML formatu. YAML yra tekstinis formatas, naudojamas konfigūracijos failams kurti.
Playbook paprastai sudaro trys pagrindiniai elementai:
Hostai (hosts): serveriai, kuriuose bus vykdomos užduotys.
Užduotys (tasks): veiksmai, kuriuos reikia atlikti valdomuose hostuose.
Moduliai (modules): kodas arba vykdomieji failai, kuriuos Ansible naudoja konkretiems veiksmams valdomuose hostuose atlikti, pavyzdžiui, paketams diegti ar failams kopijuoti.
Daugiau informacijos apie Ansible sąvokas rasite čia.
Ansible užduotis vykdo tokia tvarka, kokia jos išvardytos playbook. Tą patį playbook galite paleisti kelis kartus. Ansible automatiškai patikrina, ar prašomi pakeitimai jau pritaikyti, ir pakartotinai nevykdo užduočių, kurios jau atliktos.
0.2 Reikalavimai
Prieš tęsdami ir pradėdami kurti pirmąjį playbook, įsitikinkite, kad atlikote ankstesnę pamoką:
Jau turėtumėte turėti:
valdymo serverį su įdiegtu Ansible;
vieną ar kelis valdomus VPS;
SSH prieigą prie valdomų serverių;
ankstesnėje pamokoje sukurtą inventory failą;
naudotoją su sudo teisėmis valdomuose serveriuose.
Toliau naudosime tą patį pavyzdį kaip ankstesnėje pamokoje:
Serveris | IP adresas | SSH naudotojas |
Ubuntu | 192.0.2.10 | adminuser |
AlmaLinux | 192.0.2.20 | adminuser |
Mūsų pavyzdyje inventory failas inventory.ini atrodo taip:
[ubuntu]
ubuntu1 ansible_host=192.0.2.10 ansible_user=adminuser
[alma]
alma1 ansible_host=192.0.2.20 ansible_user=adminuser
[linux:children]
ubuntu
alma
IP adresus ir naudotojo vardą (mūsų pavyzdyje adminuser) pakeiskite savo VPS duomenimis.
1. Ansible katalogo paruošimas
Pirmiausia prisijunkite per SSH prie valdymo serverio (serverio su Ansible).
Pereikite į katalogą ansible-lab (sukurtą ankstesnėje pamokoje):
cd ~/ansible-lab
Patikrinkite katalogo failus:
ls -l
Turėtumėte matyti inventory failą:
inventory.ini
Taip pat patikrinkite, ar Ansible gali prisijungti prie valdomų serverių:
ansible all -i inventory.ini -m ping
Abu serveriai turi grąžinti:
"ping": "pong"
Jei viskas teisingai, galite kurti pirmąjį playbook.
2. Pirmojo Ansible playbook sukūrimas
Sukursime playbook, kuris atliks šias užduotis:
Įdiegs
nginxpaketą valdomuose serveriuose.Paleis Nginx tarnybą ir įjungs jos automatinį paleidimą po serverio perkrovimo.
Sukurs tekstinį failą su pasirinktu pranešimu.
Sukurkite naują playbook failą:
nano first-playbook.yml
Įklijuokite šį turinį:
---
- name: Install and configure Nginx
hosts: linux
become: true
tasks:
- name: Update APT cache and install Nginx (Ubuntu/Debian)
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
cache_valid_time: 3600
when: ansible_facts['os_family'] == "Debian"
- name: Update DNF cache and install Nginx (AlmaLinux/Rocky)
ansible.builtin.dnf:
name: nginx
state: present
update_cache: true
when: ansible_facts['os_family'] == "RedHat"
- name: Start and enable Nginx
ansible.builtin.service:
name: nginx
state: started
enabled: true
Išsaugokite pakeitimus ir išeikite.
Svarbu. YAML jautrus atitraukimams (indentation), todėl įsitikinkite, kad visi jūsų playbook atitraukimai tiksliai atitinka mūsų pavyzdį. Visada naudokite tarpus, o ne tabuliavimo simbolius.
3. Playbook struktūros paaiškinimas
3.1 Playbook pavadinimas
- name: Prepare Linux servers
name veikia kaip veiksmų rinkinio antraštė. Jis padeda suprasti, ką tiksliai daro Ansible. Pavadinimą galite pasirinkti bet kokį.
3.2 Tiksliniai serveriai
hosts: linux
hosts nurodo serverius, kuriuose turi būti vykdomos užduotys. Mūsų pavyzdyje tai grupė linux, kurią sudaro ir Ubuntu, ir Alma serveriai. Vadinasi, žemiau nurodytos užduotys bus vykdomos šios grupės serveriuose.
Galite nurodyti ir kitas grupes, pavyzdžiui, ubuntu:
hosts: ubuntu
Tokiu atveju playbook užduotys bus vykdomos tik Ubuntu serveriuose.
Jei užduotis norite vykdyti tik Alma serveriuose:
hosts: alma
Taip pat galite nurodyti visus inventory faile esančius serverius:
hosts: all
3.3 Root teisės
become: true
Kartais konkrečioms operacijoms atlikti reikalingos root teisės. become: true leidžia operacijas vykdyti su sudo.
Playbook become atitinka parametrą -b, kurį naudojome ankstesnės pamokos komandose.
3.4 Užduotys
tasks:
tasks sekcijoje surašyti veiksmai, kuriuos Ansible turi atlikti valdomuose hostuose. Kiekviena užduotis turi ją apibūdinantį pavadinimą (name).
Mūsų pavyzdyje yra trys užduotys.
Pirma užduotis: Update APT cache and install Nginx (Ubuntu/Debian)
- name: Update APT cache and install Nginx (Ubuntu/Debian)
ansible.builtin.apt:
name: nginx
state: present
update_cache: true
cache_valid_time: 3600
when: ansible_facts['os_family'] == "Debian"
Ši užduotis atnaujina APT paketų sąrašą ir įdiegia Nginx Ubuntu bei Debian serveriuose.
ansible.builtin.package leidžia pasirinkti tinkamą paketų tvarkyklę pagal operacinę sistemą. Mūsų atveju naudojame ansible.builtin.apt – modulį, skirtą programinei įrangai valdyti Debian ir Ubuntu sistemose. Su juo galima atnaujinti paketus, įdiegti ar pašalinti programas arba patikrinti jų būseną.
name: nginxnurodo paketą, su kuriuo dirbama. Mūsų atveju tai Nginx. Paprastai tariant, dirbsime su Nginx.state: presentpatikrina Nginx būseną valdomuose serveriuose. Jei Nginx jau įdiegtas, playbook jo pakartotinai diegti nebandys.update_cache: trueatnaujina galimų apt paketų sąrašą.cache_valid_time: 3600atnaujina galimų apt paketų sąrašą, jei jis senesnis nei 3600 sekundžių (1 valanda).whenyra sąlyga, nurodanti, kada užduotis turi būti vykdoma. Šiuo atveju sąlyga yraansible_facts['os_family'] == "Debian". Tai reiškia, kad užduotis bus vykdoma tik Debian pagrindu veikiančiose sistemose (įskaitant Ubuntu).
Antra užduotis: Update DNF cache and install Nginx (AlmaLinux/Rocky)
- name: Update DNF cache and install Nginx (AlmaLinux/Rocky)
ansible.builtin.dnf:
name: nginx
state: present
update_cache: true
when: ansible_facts['os_family'] == "RedHat"
Ši užduotis įdiegs Nginx AlmaLinux ir Rocky Linux sistemose. Principas panašus kaip ankstesnės užduoties.
ansible.builtin.dnf nurodo, kad naudosime DNF paketų tvarkyklę.
Visi kiti parametrai tokie patys. Skirtumas tas, kad čia nėra cache_valid_time: 3600. Tikrinti, ar paketų sąrašas pasenęs, nereikia, nes DNF tai patikrina pats.
when: sąlyga yra ansible_facts['os_family'] == "RedHat", nes ši užduotis bus vykdoma tik RedHat pagrindu veikiančiose sistemose (mūsų atveju AlmaLinux ir Rocky Linux).
Trečia užduotis: Start and enable Nginx
- name: Start and enable Nginx
ansible.builtin.service:
name: nginx
state: started
enabled: true
Ši užduotis paleis Nginx ir nustatys, kad jis automatiškai pasileistų po kiekvieno perkrovimo (enable).
ansible.builtin.service:modulis nurodo, kad dirbsime su tarnybomis.name:vėl yranginx.state: startedpatikrina, ar Nginx tarnyba jau paleista.enabled: truenustato, kad Nginx automatiškai pasileistų po serverio perkrovimo.
Jei Nginx jau veikia ir yra įjungtas automatinis paleidimas po kiekvieno perkrovimo, užduotis jo nekeičia.
Ši užduotis bus vykdoma ir Debian, ir RedHat pagrindu veikiančiose sistemose, todėl sąlygos when čia nėra.
4. Playbook patikra prieš paleidžiant
Visada verta prieš paleidžiant playbook patikrinti jo sintaksę.
Vykdykite šią komandą:
ansible-playbook -i inventory.ini first-playbook.yml --syntax-check
Jei sintaksė teisinga, pamatysite:
playbook: first-playbook.yml
Taip pat galite paleisti šią komandą ir pamatyti, kuriuos serverius playbook paveiks:
ansible-playbook -i inventory.ini first-playbook.yml --list-hosts
Turėtumėte pamatyti:
playbook: first-playbook.yml
play #1 (linux): Install and configure Nginx
pattern: ['linux']
hosts (2):
ubuntu1
alma1
Tai dar nieko nepakeis jūsų serveriuose.
5. Pirmojo playbook paleidimas
Dabar galime paleisti savo playbook.
Įveskite šią komandą (-K nereikia, jei jūsų naudotojui sudo slaptažodis nenustatytas):
ansible-playbook -i inventory.ini first-playbook.yml -K
Ansible vykdys užduotis visuose valdomuose serveriuose.
Turėtumėte pamatyti panašią išvestį:
PLAY [Install and configure Nginx] *****************************
TASK [Gathering Facts] ******************************************
ok: [ubuntu1]
ok: [alma1]
TASK [Update APT cache and install Nginx (Ubuntu/Debian)] *******
changed: [ubuntu1]
skipping: [alma1]
TASK [Update DNF cache and install Nginx (AlmaLinux/Rocky)] *****
skipping: [ubuntu1]
changed: [alma1]
TASK [Start and enable Nginx] **********************************
changed: [ubuntu1]
changed: [alma1]
PLAY RECAP *****************************************************
ubuntu1 : ok=3 changed=2 unreachable=0 failed=0 skipped=1
alma1 : ok=3 changed=2 unreachable=0 failed=0 skipped=1
okreiškia, kad užduotis įvykdyta sėkmingai. Skaičius 3 reiškia, kad visos trys užduotys buvo įvykdytos be problemų.changedreiškia, kad užduotis valdomame serveryje iš tikrųjų atliko pakeitimus. Mūsų atveju skaičius 2 reiškia, kad kiekviename serveryje pakeitimus atliko dvi užduotys.unreachablereiškia, kad serveris buvo nepasiekiamas. Mūsų atveju visi serveriai veikia ir yra pasiekiami, todėl skaičius 0.failedreiškia, kad užduotis susidūrė su klaida. Mūsų atveju visos užduotys įvykdytos sėkmingai, todėl skaičius taip pat 0.skippedyra praleistų užduočių skaičius. Ansible praleidžia užduotį, jei ji netinka konkrečiam serveriui. Mūsų atveju Ansible praleidžia APT užduotį RedHat serveriuose ir DNF užduotį Debian bei Ubuntu serveriuose.
6. Patikrinkite, ar playbook suveikė
Iš valdymo serverio vykdykite šią komandą:
ansible linux -i inventory.ini -a "systemctl is-active nginx"
Turėtumėte pamatyti:
ubuntu1 | CHANGED | rc=0 >>
active
alma1 | CHANGED | rc=0 >>
active
Abu valdomi serveriai turi pateikti tą patį rezultatą: active.
Patikrinkite, ar Nginx įjungtas automatiniam paleidimui po kiekvieno perkrovimo:
ansible linux -i inventory.ini -a "systemctl is-enabled nginx"
Abu serveriai turėtų grąžinti:
enabled
7. Playbook paleidimas dar kartą
Kaip minėjome anksčiau, jei reikiami nustatymai jau pritaikyti, Ansible jokių pakeitimų nedaro. Šis principas vadinamas idempotentiškumu (idempotency).
Dar kartą paleiskite tą patį playbook:
ansible-playbook -i inventory.ini first-playbook.yml -K
Šį kartą, jei valdomuose serveriuose nieko nepasikeitė, išvestis turėtų atrodyti taip:
TASK [Update APT cache and install Nginx (Ubuntu/Debian)] *******
ok: [ubuntu1]
skipping: [alma1]
TASK [Update DNF cache and install Nginx (AlmaLinux/Rocky)] *****
skipping: [ubuntu1]
ok: [alma1]
TASK [Start and enable Nginx] **********************************
ok: [ubuntu1]
ok: [alma1]
PLAY RECAP *****************************************************
ubuntu1 : ok=3 changed=0 unreachable=0 failed=0 skipped=1
alma1 : ok=3 changed=0 unreachable=0 failed=0 skipped=1
Šį kartą changed reikšmė bus:
changed=0
Tai reiškia, kad Ansible patikrino serverio konfigūraciją ir nenustatė, kad Nginx reikėtų iš naujo diegti, paleisti ar įjungti.
8. Playbook keitimas
Dabar atliksime nedidelį pakeitimą, kad pamatytume, kaip Ansible aptinka konfigūracijos skirtumus.
Šiame pavyzdyje pakeisime enabled parametrą.
Atidarykite playbook:
nano first-playbook.yml
Suraskite šią užduotį:
- name: Start and enable Nginx
ansible.builtin.service:
name: nginx
state: started
enabled: true
Pakeiskite ją šiuo turiniu:
- name: Start Nginx without enabling it at boot
ansible.builtin.service:
name: nginx
state: started
enabled: false
Išsaugokite failą.
Dar kartą paleiskite playbook:
ansible-playbook -i inventory.ini first-playbook.yml -K
Dabar Ansible pastebės neatitikimą tarp Nginx paleidimo konfigūracijos serveryje ir tos, kuri nurodyta playbook.
Turėtumėte pamatyti:
TASK [Start Nginx without enabling it at boot]
changed: [ubuntu1]
changed: [alma1]
Taigi Ansible atnaujino tarnybos konfigūraciją abiejuose serveriuose. Nustatymas enabled: false sustabdo automatinį Nginx paleidimą po perkrovimo.
Tačiau vis dar turime:
state: started
Todėl Nginx toliau veikia.
Norėdami grąžinti pradinę konfigūraciją, vėl atidarykite playbook:
nano first-playbook.yml
Turinį pakeiskite atgal į:
- name: Start and enable Nginx
ansible.builtin.service:
name: nginx
state: started
enabled: true
Išsaugokite failą ir dar kartą paleiskite playbook:
ansible-playbook -i inventory.ini first-playbook.yml -K
Ansible vėl aptiks skirtumą ir įjungs automatinį Nginx paleidimą po kiekvieno perkrovimo.
Patikrinkite rezultatą:
ansible linux -i inventory.ini -a "systemctl is-enabled nginx"
Turėtumėte pamatyti:
enabled
Tai vienas pagrindinių Ansible playbook privalumų. Pakeičiate vieną failą, paleidžiate jį iš naujo, ir atnaujinami visi serveriai.
9. Playbook paleidimas konkrečiuose serveriuose
Jei užduotis reikia vykdyti tik konkrečiuose serveriuose, galite naudoti parametrą --limit. Jis apriboja užduočių vykdymą tik jūsų pasirinktais hostais.
Pavyzdžiui, playbook galite paleisti tik Ubuntu serveriuose:
ansible-playbook -i inventory.ini first-playbook.yml --limit ubuntu -K
Arba tik AlmaLinux serveriuose:
ansible-playbook -i inventory.ini first-playbook.yml --limit alma -K
Taip pat galite nurodyti atskirą serverį:
ansible-playbook -i inventory.ini first-playbook.yml --limit ubuntu1 -K
Šiuo atveju Ansible playbook vykdys tik serveryje ubuntu1.
ubuntu1 atitinka pavadinimą, kurį inventory faile nurodėte konkrečiam valdomam serveriui.
Tai patogu, kai konfigūracijos pakeitimus norite išbandyti viename serveryje, prieš pritaikydami juos kitiems savo infrastruktūros serveriams.
10. Trikčių šalinimas
10.1 YAML sintaksės klaidos
Jei gaunate šį klaidos pranešimą:
ERROR! We were unable to read either as JSON nor YAML
Tai reiškia, kad Ansible negalėjo nuskaityti playbook dėl YAML formato klaidos: neteisingų atitraukimų, trūkstamų dvitaškių ar kitų YAML formatavimo problemų. Patikrinkite playbook failą ir įsitikinkite, kad viskas teisinga.
10.2 UNREACHABLE
Jei matote:
fatal: [ubuntu1]: UNREACHABLE!
Tai reiškia, kad Ansible negali prisijungti prie valdomo serverio.
Tokiu atveju rankiniu būdu patikrinkite SSH ryšį:
Jei vykdant šią komandą prisijungti nepavyksta, patikrinkite SSH naudotojo vardą, serverio IP adresą, SSH prievadą, ugniasienės nustatymus ir autentifikacijos metodą.
Ryšį taip pat galite patikrinti paleisdami šią komandą:
ansible all -i inventory.ini -m ping
10.3 Nepavyksta gauti sudo slaptažodžio
Jei gaunate su sudo slaptažodžiu susijusią klaidą, įsitikinkite, kad turite sudo teises.
Pabandykite paleisti playbook su šia komanda:
ansible-playbook -i inventory.ini first-playbook.yml -K
Ansible paprašys įvesti sudo slaptažodį.
Jei vis tiek neveikia, prisijunkite prie valdomo serverio ir patikrinkite sudo ten:
sudo whoami
Jei viskas gerai, komanda turėtų grąžinti:
root
Priešingu atveju jūsų naudotojas neturi sudo teisių.
10.4 No hosts matched
Kita klaida:
[WARNING]: Could not match supplied host pattern
Dažniausiai tai reiškia, kad inventory faile nerastas konkretus serveris ar grupė.
Pavyzdžiui, jei jūsų playbook yra:
hosts: linux
Įsitikinkite, kad grupė linux taip pat yra inventory.ini faile.
Visus inventory failo hostus galite parodyti šia komanda:
ansible all -i inventory.ini --list-hosts
Įsitikinkite, kad komandą vykdote kataloge, kuriame yra inventory failas.
10.5 Nepavyksta įdiegti paketo
Jei Ansible gali prisijungti prie valdomo serverio, bet nepavyksta įdiegti programų, patikrinkite, ar paketas egzistuoja jūsų valdomo serverio sistemoje.
Vykdykite šias komandas:
Ubuntu:
sudo apt update
sudo apt install nginx -y
AlmaLinux:
sudo dnf install nginx -y
11. Naudingos Ansible playbook komandos
Dirbdami su Ansible playbook dažnai naudosite šias komandas:
Komanda | Aprašymas |
| Paleisti playbook |
| Paleisti playbook ir paprašyti sudo slaptažodžio |
| Patikrinti playbook sintaksę |
| Imituoti playbook užduotis nepritaikant pakeitimų |
| Parodyti tikslinius serverius |
| Parodyti playbook užduotis |
| Vykdyti tik konkrečioje grupėje (šiame pavyzdyje Ubuntu grupėje) |
| Rodyti išsamesnę vykdymo informaciją |
12. Išvada
Šioje pamokoje išmokome tinkamai kurti Ansible playbook, tikrinti jų sintaksę, vykdyti užduotis keliuose valdomuose serveriuose, šalinti triktis ir keisti esamus playbook. Šiame pavyzdyje diegėme Nginx, tačiau lygiai taip pat galite automatizuoti Apache, MariaDB, Docker, PHP, ugniasienės ir daugelio kitų paslaugų diegimą bei konfigūravimą.
Daugiau informacijos rasite oficialioje Ansible Playbooks dokumentacijoje.
