Pierwsza udostępniona rola ansible, a wraz z nim poradnik odnośnie ansible.

Chciałbym zacząć cykl od nauki ansible, z racji tego, że uczyć najlepiej się na przykładach, postaram się wam to pokazać na przykładzie roli ansible służącej do instalacji dockera.

Dzisiaj chciałbym pokazać wam moją pierwszą rolą idea, służącą do instalacji dockera:

https://github.com/liske310/ansible-docker/tree/master

Rola ta służy do instalacji dockera na rocky linux (i wszystkich pochodnych RedHata).

Każda rola w ansible składa się z kilku folderów – głównie używane to:

  • tasks -> folder służący do przechowywania plików z taskami (zadaniami)
  • defaults -> folder służący do przechowywania plików z defaultowymi zmiennymi
  • vars -> folder służący do przechowywania plików z zmiennymi, które mogą być różnić się np. poprzez dystrybucje
  • handlers -> folder służący do przechowywania plików z handlerami (po PL obsługiwacze zdarzeń).

W tym przypadku rola ta składa się tylko i wyłącznie z jednego folderu tasks – ponieważ została napisana tylko na RedHata, ponieważ tylko na ten ekosystem była mi ta rola potrzebna, a więc w folderze tasks posiadamy 2 pliki:

  • redhat.yml
  • main.yml

W takim main.yml znajduje się jeden task:

---
- name: "Redhat"
  when: ansible_facts['os_family'] == "RedHat"
  include_tasks: redhat.yml
  tags: [redhat, docker-redhat]

Ten jeden task służy do tego, aby sprawdził, czy rodzina danego systemu operacyjnego to RedHat (działa na CentOS/RockyLinux/Redhat/Fedora i inne). Jeżeli tak to rób taski z pliku podanego w parametrze include_tasks, czyli redhat.yml.

W pliku redhat.yml znajduje się kilka tasków odnośnie instalacji dockera:

---
- name: "add docker repository"
  shell: "dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo"

- name: "install docker-ce"
  shell: "dnf install docker-ce --nobest -y"

- name: "start&enable docker daemon"
  systemd:
    name: docker
    state: started
    enabled: yes

a więc po kolei:

  1. Pierwszy task odpowiada za dodanie repozytorium dockera
  2. Drugi task odpowiada za to, aby był zainstalowany docker-ce – w tym przypadku został użyty –nobest, ponieważ po dodaniu repozytorium, dnf czepiał się nowego certyfikatu po dodaniu repozytorium
  3. Trzeci task odpowiada za uruchomienie i ustawienie enable w systemd usługi docker.

Jak ją uruchamiamy?

Musimy mieć na serwerze dostęp po SSH do serwera, najlepiej po kluczu i wtedy tworzymy następującą strukturę plików:

[root@ansible ansible]# tree
.
├── roles
│   ├── docker
│   │   └── tasks
│   │   ├── main.yml
│   │   └── redhat.yml
└── variables
├── docker.yml
├── hosts

Gdzie plik hosts wygląda następująco:

[all]
naszserver.local

Gdzie naszserver.local jest to nazwa DNS naszego serwera – ja mam lokalny serwer dns dlatego nazwałem go naszserver.local, który znajduje się w grupie [all] .

Nic nie stoi na przeszkodzie, aby plik wyglądał tak:

[all]
naszserver.local

[mailserver]
naszserver.local

albo jeszcze inaczej -> jeden serwer może występować w wielu grupach, nie ma to najmniejszego problemu

A plik docker.yml wygląda następująco:

---
- name: "docker"
  hosts:
    - all
  roles:
    - { role: ../roles/docker }

Służy on do tego, aby wskazać, jakie hosty mogą używać tej roli (w tym przpadku wszystkie z grupy all), oraz jakie role ma uruchomić – może być ich kilka o czym będziemy mówili w przyszłych poradnikach.

Teraz przechodzimy do katalogu variables i wydajemy poniższe polecenie:

variables $ ansible-playbook -i hosts docker.yml -l naszserver.local

PLAY [docker] ******************************************************************

TASK [Gathering Facts] *********************************************************
ok: [naszserver.local]

TASK [../roles/docker : Redhat] ************************************************
included: /opt/ansible/roles/docker/tasks/redhat.yml for naszserver.local

TASK [../roles/docker : add docker repository] *********************************
changed: [naszserver.local]

TASK [../roles/docker : install docker-ce] *************************************
changed: [naszserver.local]

TASK [../roles/docker : start&enable docker daemon] ****************************
ok: [naszserver.local]

PLAY RECAP *********************************************************************
naszserver.local           : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

W tym przypadku widzimy, że na naszserver.local dodał repozytorium dockera i doinstalował.

Weźmy na tapetę sobie jeszcze polecenie:

ansible-playbook -i hosts docker.yml -l naszserver.local

hosts to jest nasz plik hosts z hostami które ma ansible

docker.yml to jest nasz „playbook” czyli plik w którym zapisujemy co ma rola uruchomić, oraz na jakich hostach może

-l naszserver.local to jest ograniczenie, aby działało tylko na naszserwer.local – jeżeli byśmy mieli w pliku hosts:

[all]
naszserver.local
naszserver2.local
naszserver3.local

[mailserver]
naszserver.local
naszserver2.local

[minecraftserver]
naszserver3.local

To służy do tego, aby nie uruchamiać tego playbooka na wszystkich hostach, a tylko na jednym z nich.

Dlaczego to robimy ansiblem a nie ręcznie?
Wyobraź sobie, że masz teraz 1 tysiąc serwerów na których musisz zainstalować dockera… zrobiłbyś to ręcznie z chęcią? Czy wolałbyś puścić jeden automat w którym wskazałbyś tylko grupę tego 1 tysiąca serwerów i robiłoby się to automatycznie?