Im ersten Teil der Ansible-Reihe haben Sie Ansible kennengelernt und gelernt, es zu installieren.
In diesem Tutorial erfahren Sie, wie Sie statisches Inventar in Ansible verwalten. Sie werden auch verschiedene Ansible-Konfigurationseinstellungen verstehen.
Darüber hinaus lernen Sie einige Ansible-Module kennen und können Ansible-Ad-Hoc-Befehle ausführen.
Bevor Sie das alles sehen, möchte ich mich bei allen LHB Pro-Mitgliedern bedanken. Diese Ansible-Serie ist mit ihrer Unterstützung möglich. Wenn Sie noch kein Pro-Mitglied sind, ziehen Sie bitte in Betracht, sich für das Abonnement zu entscheiden.
Erstellen eines Ansible-Benutzers
Auch wenn Sie den Root-Benutzer in Ansible verwenden können, um Ad-Hoc-Befehle und Playbooks auszuführen, wird dies definitiv nicht empfohlen und gilt aufgrund der Sicherheitsrisiken, die durch die Gewährung des SSH-Zugriffs für Root-Benutzer entstehen können, definitiv nicht als Best Practice.
Aus diesem Grund wird empfohlen, dass Sie einen dedizierten Ansible-Benutzer mit sudo-Berechtigungen (für alle Befehle) auf allen Hosts (Kontroll- und verwaltete Hosts) erstellen.
Denken Sie daran, dass Ansible SSH und Python verwendet, um die ganze Drecksarbeit hinter den Kulissen zu erledigen. Hier sind also die vier Schritte, die Sie nach der Installation von Ansible befolgen müssten:
- Erstellen Sie einen neuen Benutzer auf allen Hosts.
- Gewähren Sie dem neuen Benutzer sudo-Berechtigungen auf allen Knoten.
- Generieren Sie SSH-Schlüssel für den neuen Benutzer auf dem Kontrollknoten.
- Kopieren Sie den öffentlichen SSH-Schlüssel auf die verwalteten Knoten.
Beginnen wir also ohne weiteres mit dem Erstellen eines neuen Benutzers namens elliot auf allen Hosts:
[[email protected] ~]# useradd -m elliot
[[email protected] ~]# useradd -m elliot
[[email protected] ~]# useradd -m elliot
[[email protected] ~]# useradd -m elliot
[[email protected] ~]# useradd -m elliot
Nach dem Einstellen von elliot's Passwort auf allen Hosts, können Sie mit Schritt 2 fortfahren; Sie können elliot gewähren sudo-Berechtigungen für alle Befehle ohne Passwort, indem Sie den folgenden Eintrag zu /etc/sudoers hinzufügen Datei:
[[email protected] ~]# echo "elliot ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
[[email protected] ~]# echo "elliot ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
[[email protected] ~]# echo "elliot ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
[[email protected] ~]# echo "elliot ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
[[email protected] ~]# echo "elliot ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
Melden Sie sich nun als Benutzer elliot an auf Ihrem Kontrollknoten und generieren Sie ein SSH-Schlüsselpaar:
[[email protected] ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/elliot/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/elliot/.ssh/id_rsa.
Your public key has been saved in /home/elliot/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:Xf5bKx0kkBCsCQ/7rc6Kv6CxCRTH2XJajbNvpzel+Ik [email protected]
The key's randomart image is:
+---[RSA 3072]----+
| .oo . |
| . ooo . o |
| . = *=.o o |
| o =.o+ . o . . |
| . . .. S . . o |
|. .. . . . . |
|.. . oo.o o o|
|. = o oo++. . +.|
| + ..++Eoo. o. |
+----[SHA256]-----+
Schließlich können Sie elliots kopieren öffentlicher SSH-Schlüssel für alle verwalteten Hosts unter Verwendung der ssh-copy-id Befehl wie folgt:
[[email protected] ~]$ ssh-copy-id node1
[[email protected] ~]$ ssh-copy-id node2
[[email protected] ~]$ ssh-copy-id node3
[[email protected] ~]$ ssh-copy-id node4
Sie sollten jetzt in der Lage sein, per SSH auf alle verwalteten Knoten zuzugreifen, ohne zur Eingabe eines Kennworts aufgefordert zu werden. Sie werden nur aufgefordert, eine SSH-Passphrase einzugeben (wenn Sie sie nicht leer gelassen haben, ha-ha).
Aufbau Ihres Ansible-Inventars
Eine Ansible-Inventardatei ist im Grunde eine Datei, die eine Liste von Servern, Servergruppen oder IP-Adressen enthält, die auf die Hosts verweist, die von Ansible verwaltet werden sollen (verwaltete Knoten).
Die /etc/ansible/hosts ist die Standardinventardatei. Ich zeige Ihnen nun, wie Sie Ihre eigenen Inventardateien in Ansible erstellen.
Erstellen eines Projektverzeichnisses
Sie wollen nicht mit /etc/ansible herumspielen Verzeichnis; Sie sollten alles in /etc/ansible aufbewahren intakt und verwenden Sie es im Grunde nur als Referenz, wenn Sie Inventardateien erstellen, Ansible-Projektkonfigurationsdateien bearbeiten usw.
Lassen Sie uns nun ein neues Ansible-Projektverzeichnis mit dem Namen /home/elliot erstellen mit dem Namen Spiele die Sie verwenden werden, um alle Ihre Ansible-bezogenen Dinge (Playbooks, Inventardateien, Rollen usw.) zu speichern, die Sie von diesem Punkt an erstellen werden:
[[email protected] ~]$ mkdir /home/elliot/plays
Beachten Sie, dass sich alles, was Sie von diesem Punkt an erstellen, auf dem Kontrollknoten befinden wird.
Erstellen einer Inventardatei
Wechseln Sie zu /home/elliot/plays Verzeichnis und erstellen Sie eine Bestandsdatei namens myhosts und fügen Sie alle Hostnamen Ihrer verwalteten Knoten hinzu, sodass es am Ende so aussieht:
[[email protected] plays]$ cat myhosts
node1
node2
node3
node4
Sie können jetzt den folgenden Ansible-Befehl ausführen, um alle aufzulisten Ihre Hosts in myhosts Bestandsdatei:
[[email protected] plays]$ ansible all -i myhosts --list-hosts
hosts (4):
node1
node2
node3
node4
Das -i Option wurde verwendet, um myhosts anzugeben Bestandsdatei. Wenn Sie das -i weglassen Option sucht Ansible nach Hosts in /etc/ansible/hosts Inventardatei statt.
Denken Sie daran, dass ich hier Hostnamen verwende und dass sich alle Knoten (VMs), die ich in Azure erstellt habe, im selben Subnetz befinden und ich mich nicht um DNS kümmern muss, da es von Azure gehandhabt wird.
Wenn Sie keinen funktionierenden DNS-Server haben, können Sie die IP-Adresse/Hostnamen-Einträge Ihrer Knoten in /etc/hosts hinzufügen , unten ist ein Beispiel:
Erstellen von Hostgruppen und Untergruppen
Sie können Ihre verwalteten Hosts in Gruppen und Untergruppen organisieren. Beispielsweise können Sie myhosts bearbeiten Datei, um zwei Gruppen test zu erstellen und prod wie folgt:
[[email protected] plays]$ cat myhosts
[test]
node1
node2
[prod]
node3
node4
Sie können die Hosts im prod auflisten gruppieren, indem Sie den folgenden Befehl ausführen:
[[email protected] plays]$ ansible prod -i myhosts --list-hosts
hosts (2):
node3
node4
Es gibt zwei Standardgruppen in Ansible:
- all - enthält alle Hosts im Inventar
- ungrouped - enthält alle Hosts, die kein Mitglied einer Gruppe sind (außer allen).
Lassen Sie uns einen imaginären Host node5 hinzufügen zu den myhosts Inventory-Datei, um die nicht gruppierte zu demonstrieren Gruppe:
[[email protected] plays]$ cat myhosts
node5
[test]
node1
node2
[prod]
node3
node4
Beachten Sie, dass ich node5 hinzugefügt habe ganz am Anfang (und nicht am Ende) von myhosts andernfalls würde sie als Mitglied von prod betrachtet Gruppe.
Jetzt können Sie den folgenden Befehl ausführen, um alle nicht gruppierten aufzulisten Gastgeber:
[[email protected] plays]$ ansible ungrouped -i myhosts --list-hosts
hosts (1):
node5
Sie können auch eine Gruppe (übergeordnet) erstellen, die Untergruppen (untergeordnete Gruppen) enthält. Sehen Sie sich das folgende Beispiel an:
[[email protected] plays]$ cat myhosts
[web_dev]
node1
[web_prod]
node2
[db_dev]
node3
[db_prod]
node4
[development:children]
web_dev
db_dev
[production:children]
web_prod
db_prod
Die Entwicklung Gruppe enthält alle Hosts, die sich in web_dev befinden plus alle Mitglieder, die sich in db_dev befinden . Ebenso die Produktion Gruppe enthält alle Hosts, die sich in web_prod befinden plus alle Mitglieder, die in db_prod. sind
[[email protected] plays]$ ansible development -i myhosts --list-hosts
hosts (2):
node1
node3
[[email protected] plays]$ ansible production -i myhosts --list-hosts
hosts (2):
node2
node4
Ansible konfigurieren
In diesem Abschnitt lernen Sie die wichtigsten Ansible-Konfigurationseinstellungen kennen. Während der gesamten Serie werden Sie bei Bedarf andere Konfigurationseinstellungen besprechen.
Die /etc/ansible/ansible.cfg ist die Standardkonfigurationsdatei. Es wird jedoch auch empfohlen, dass Sie sich nicht mit /etc/ansible/ansible.cfg anlegen und verwenden Sie es einfach als Referenz. Sie sollten Ihre eigene Ansible-Konfigurationsdatei in Ihrem Ansible-Projektverzeichnis erstellen.
Die ansible --Version Der Befehl zeigt Ihnen, welche Konfigurationsdatei Sie gerade verwenden:
[[email protected] plays]$ ansible --version
ansible 2.9.14
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/elliot/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.6.8 (default, Dec 5 2019, 15:45:45) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
Wie Sie der Ausgabe entnehmen können, /etc/ansible/ansible.cfg wird derzeit verwendet, da Sie noch keine eigene ansible.cfg erstellt haben Datei im Projektverzeichnis.
Die /etc/ansible/ansible.cfg enthält eine ganze Reihe verschiedener Ansible-Konfigurationseinstellungen und -abschnitte:
[[email protected] plays]$ wc -l /etc/ansible/ansible.cfg
490 /etc/ansible/ansible.cfg
Die beiden wichtigsten Abschnitte, die Sie in Ihrer Ansible-Konfigurationsdatei definieren müssen, sind:
- [Standard]
- [privilege_escalation]
In den [Standardeinstellungen] Abschnitt finden Sie hier die wichtigsten Einstellungen, die Sie beachten müssen:
- Inventar - gibt den Pfad Ihrer Inventardatei an.
- remote_user - gibt den Benutzer an, der sich mit den verwalteten Hosts verbindet und die Playbooks ausführt.
- Gabeln - gibt die Anzahl der Hosts an, die Ansible parallel verwalten/verarbeiten kann; Standard ist 5.
- host_key_checking - gibt an, ob Sie die Überprüfung des SSH-Schlüsselhosts ein- oder ausschalten möchten; Standard ist True.
In der [privilege_escalation] Abschnitt können Sie die folgenden Einstellungen konfigurieren:
- werden - Geben Sie an, wo die Rechteausweitung zugelassen/nicht zugelassen werden soll; Standard ist False.
- become_method - Geben Sie die Methode zur Rechteausweitung an. Standard ist sudo.
- become_user - Geben Sie den Benutzer an, zu dem Sie durch Rechteausweitung werden; Standard ist root.
- become_ask_pass - Geben Sie an, ob nach dem Passwort für die Rechteerweiterung gefragt werden soll oder nicht; Standard ist False.
Denken Sie daran, dass Sie keine dieser Einstellungen in den Speicher übernehmen müssen. Sie sind alle in /etc/ansible/ansible.cfg dokumentiert .
Erstellen Sie nun Ihre eigene ansible.cfg Konfigurationsdatei in Ihrem Ansible-Projektverzeichnis /home/elliot/plays und legen Sie die folgenden Einstellungen fest:
Führen Sie nun die ansible --version aus Befehl noch einmal; Sie sollten sehen, dass Ihre neue Konfigurationsdatei jetzt wirksam ist:
[[email protected] plays]$ ansible --version
ansible 2.9.14
config file = /home/elliot/plays/ansible.cfg
configured module search path = ['/home/elliot/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.6.8 (default, Dec 5 2019, 15:45:45) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
Ausführen von Ad-hoc-Befehlen in Ansible
Bis zu diesem Punkt haben Sie eigentlich nur Ansible installiert, eingerichtet und konfiguriert. Jetzt beginnt der wahre Spaß!
Ein Ansible-Ad-hoc-Befehl ist ein großartiges Tool, mit dem Sie eine einzelne Aufgabe auf einem oder mehreren verwalteten Knoten ausführen können. Ein typischer Ansible-Ad-hoc-Befehl folgt der allgemeinen Syntax:
ansible host_pattern -m module_name -a "module_options"
Der einfachste Weg, um zu verstehen, wie Ansible Ad-hoc-Befehle funktionieren, besteht darin, einfach einen auszuführen! Fahren Sie also fort und führen Sie den folgenden Ad-hoc-Befehl aus:
[[email protected] plays]$ ansible node1 -m command -a "uptime"
Enter passphrase for key '/home/elliot/.ssh/id_rsa':
node1 | CHANGED | rc=0 >>
18:53:01 up 5 days, 18:03, 1 user, load average: 0.00, 0.01, 0.00
Ich wurde aufgefordert, meine SSH-Schlüssel-Passphrase einzugeben, und dann wurde die Betriebszeit von node1 angezeigt! Sehen Sie sich nun die folgende Abbildung an, um jedes Element des Ad-hoc-Befehls zu verstehen, den Sie gerade ausführen:
Sie hätten es wahrscheinlich schon erraten; Ansible-Module sind wiederverwendbare, eigenständige Skripte, die von der Ansible API verwendet werden können , oder durch das ansible oder ansible - Playbook Programme.
Das Befehlsmodul ist eines der vielen Module, die Ansible zu bieten hat. Sie können ansible-doc -l ausführen Befehl, um alle verfügbaren Ansible-Module aufzulisten:
[[email protected] plays]$ ansible-doc -l | wc -l
3387
Derzeit sind 3387 Ansible-Module verfügbar, und es werden täglich mehr! Sie können jeden Befehl, den Sie ausführen möchten, als Option an das Ansible-Befehlsmodul übergeben.
Wenn Sie keine leere Passphrase für den SSH-Schlüssel haben (genau wie ich); dann müssten Sie ssh-agent ausführen um die unnötigen Kopfschmerzen zu vermeiden, jedes Mal, wenn Ansible versucht, auf Ihre verwalteten Knoten zuzugreifen, zur Eingabe einer Passphrase aufgefordert zu werden:
[[email protected] plays]$ eval `ssh-agent`
Agent pid 218750
[[email protected] plays]$ ssh-add
Enter passphrase for /home/elliot/.ssh/id_rsa:
Identity added: /home/elliot/.ssh/id_rsa ([email protected])
Konnektivität testen
Möglicherweise möchten Sie testen, ob Ansible eine Verbindung zu all Ihren verwalteten Knoten herstellen kann, bevor Sie sich mit den ernsthafteren Aufgaben befassen. Dazu können Sie den Ping verwenden Modul und geben Sie alle Ihre verwalteten Hosts wie folgt an:
[[email protected] plays]$ ansible all -m ping
node4 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
node3 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
node1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
node2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
Wie Sie mit all dem SUCCESS in der Ausgabe sehen können. Beachten Sie, dass Ansible ping Modul benötigt keine Optionen. Einige Ansible-Module erfordern Optionen und andere nicht, genau wie bei Linux-Befehlen.
Dokumentation zu Ansible-Modulen
Wenn mich jemand fragen würde, was Ihnen an Ansible am besten gefällt; Ich würde schnell sagen, es ist die Dokumentation. Ansible ist so sehr gut dokumentiert und das alles bequem von Ihrem eigenen Terminal aus.
Wenn Sie wissen möchten, wie ein bestimmtes Ansible-Modul verwendet wird, können Sie ansible-doc ausführen gefolgt vom Modulnamen.
Beispielsweise können Sie die Beschreibung des Ping anzeigen Modul und wie man es benutzt, indem man es ausführt:
[[email protected] plays]$ ansible-doc ping
Dadurch wird der Ping geöffnet Moduldokumentationsseite:
Achten Sie beim Lesen der Moduldokumentation besonders darauf, ob einer Option das Gleichheitszeichen (=) vorangestellt ist. In diesem Fall ist es eine obligatorische Option, die Sie angeben müssen.
Wenn Sie ganz nach unten scrollen, sehen Sie außerdem einige Beispiele dafür, wie Sie die Ad-hoc-Befehle oder Ansible-Playbooks ausführen (die wir später besprechen werden).
Befehl vs. Shell vs. Raw-Module
Es gibt drei Ansible-Module, die oft miteinander verwechselt werden; diese sind:
- Befehl
- Schale
- roh
Diese drei Module erfüllen denselben Zweck; Sie führen Befehle auf den verwalteten Knoten aus. Aber es gibt wesentliche Unterschiede, die die drei Module trennen.
Mit dem Befehl können Sie weder Piping noch Umleitung verwenden Modul. Beispielsweise führt der folgende Ad-hoc-Befehl zu einem Fehler:
[[email protected] plays]$ ansible node2 -m command -a "lscpu | head -n 5"
node2 | FAILED | rc=1 >>
lscpu: invalid option -- 'n'
Try 'lscpu --help' for more information.non-zero return code
Das liegt daran, dass Befehl Das Modul unterstützt keine Pipes oder Umleitungen. Sie können stattdessen das Shell-Modul verwenden, wenn Sie Pipes oder Redirection verwenden möchten. Führen Sie denselben Befehl erneut aus, aber verwenden Sie diesmal die Shell Modul stattdessen:
[[email protected] plays]$ ansible node2 -m shell -a "lscpu | head -n 5"
node2 | CHANGED | rc=0 >>
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 1
On-line CPU(s) list: 0
Klappt wunderbar! Die ersten fünf Zeilen der lscpu-Befehlsausgabe auf node2 wurden erfolgreich angezeigt.
Ansible verwendet hinter den Kulissen SSH- und Python-Skripte, um die ganze Magie zu erledigen. Jetzt das Rohmaterial -Modul verwendet nur SSH und umgeht das Ansible-Modul-Subsystem. Auf diese Weise würde dieses Rohmodul erfolgreich auf dem verwalteten Knoten funktionieren, selbst wenn Python nicht installiert ist (auf dem verwalteten Knoten).
Ich habe meine Python-Binärdateien auf node4 manipuliert (bitte tun Sie das nicht selbst), damit ich ein Szenario nachahmen kann, was passieren wird, wenn Sie die Shell ausführen oder Befehl Modul auf einem Knoten, auf dem Python nicht installiert ist:
[email protected]:/usr/bin# mkdir hide
[email protected]:/usr/bin# mv python* hide/
Überprüfen Sie nun, was passiert, wenn ich ein Ansible Ad-hoc mit der Shell ausführe oder Befehl Modul, das auf node4 abzielt:
[[email protected] plays]$ ansible node4 -m shell -a "whoami"
node4 | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"module_stderr": "Shared connection to node4 closed.\r\n",
"module_stdout": "/bin/sh: 1: /usr/bin/python: not found\r\n",
}
[[email protected] plays]$ ansible node4 -m command -a "cat /etc/os-release"
node4 | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"module_stderr": "Shared connection to node4 closed.\r\n",
"module_stdout": "/bin/sh: 1: /usr/bin/python: not found\r\n",
"msg": "The module failed to execute correctly, you probably need to set the interpreter.\nSee stdout/stderr for the exact error",
"rc": 127
}
Ich bekomme Fehler! Jetzt werde ich versuchen, dieselbe Aufgabe zu erfüllen; aber dieses Mal werde ich das rohe verwenden Modul:
[[email protected] plays]$ ansible node4 -m raw -a "cat /etc/os-release"
node4 | CHANGED | rc=0 >>
NAME="Ubuntu"
VERSION="18.04.5 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.5 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
Shared connection to node4 closed.
Wie Sie sehen können, war das Rohmodul das einzige Modul von drei Modulen, das die Aufgabe erfolgreich ausgeführt hat. Jetzt gehe ich zurück und behebe das Chaos, das ich auf node4 angerichtet habe:
[email protected]:/usr/bin/hide# mv * ..
Ich habe diese Tabelle unten erstellt, um die verschiedenen Anwendungsfälle für die drei Module zusammenzufassen:
Beschreibung | Befehl | Schale | Roh |
---|---|---|---|
Einfache Befehle ausführen | Ja | Ja | Ja |
Befehle mit Umleitung ausführen | Nein | Ja | Ja |
Befehle ohne Python ausführen | Nein | Nein | Ja |
In Ordnung! Dies bringt uns zum Ende des zweiten Ansible-Tutorials.
Bleiben Sie dran für das nächste Tutorial, da Sie lernen werden, wie Sie Ansible-Playbooks erstellen und ausführen. Vergessen Sie nicht, Mitglied zu werden :)