Feeds: mp3
All episodes: Archive
Powered by Mikrowelle OS
Viele Server zentral und automatisiert zu verwalten; Dafür gibt es mittlerweile rund zwei Dutzend Systeme. Alle paar Jahre schaue ich mir diese Systeme an und stelle fest, daß sie mir nicht gefallen.
Viele der bisher getesteten Systeme basieren auf einer Client/Server Struktur und/oder nutzen zentrale Datenbanken zur Verwaltung der Clients. Dies ist mir zu unflexibel.
Ansible ist anders: Voraussetzung auf dem Client sind SSH Zugriff und ein installiertes Python. Das finde ich sogar auf Vyos-, Ubiquiti- und Junos Routern vor :-)
etckeeper versioniert
/etc
eigenständig als git Repository und pusht auf Wunsch auch periodisch die Änderungen auf einen GitLab Server. Und per Ansible wird das ganze mit möglichst wenig manuellem Aufwand auf die vorhandenen Linuxserver ausgerollt.Hier eine Schritt für Schritt Anleitung, wie man dieses Setup erhält.
(Viele Beispiele sind von http://docs.ansible.com übernommen)
root
sudo
Sobald Ansible installiert ist (pip install ansible
), legen wir eine hosts
Datei an:
192.0.2.50
aserver.example.org
bserver.example.org
Diese kann auch in Kategorien unterteilt werden:
[lokal]
192.0.2.50
[Webserver]
aserver.example.org
bserver.example.org
Die
hosts
Datei wird von Ansible in/etc/ansible/hosts
erwartet. Da ich dies auf meinem Desktop als unpraktisch empfinde, erstellte ich mir einen Ordneransible
in meinem per Seafile gesyncten Ordner und linkte diesen persudo ln -s /etc/ansbile ~/Seafile/DevOps/ansible
nach/etc/ansible
.
Es ist zwar lustig anzusehen, aber äußerst unpraktisch im Tagesgeschäft, daß Ansible per default (und sofern installiert) cowsay
für die Tasknamen nutzt. Möchte man dies nicht, schaltet man es im Environment oder per .profile
hiermit ab: export ANSIBLE_NOCOWS=1
.
Hier ein paar demonstrative Aufrufe aus der offiziellen Doku:
# as bruce
ansible all -m ping -u bruce
# as bruce, sudoing to root
ansible all -m ping -u bruce --sudo
# as bruce, sudoing to batman
ansible all -m ping -u bruce --sudo --sudo-user batman
# With latest version of ansible `sudo` is deprecated so use become
# as bruce, sudoing to root
ansible all -m ping -u bruce -b
# as bruce, sudoing to batman
ansible all -m ping -u bruce -b --become-user batman
ansible all -a "/bin/echo hello"
Ein Eintrag wie dieser:
jumper ansible_port=5555 ansible_host=192.0.2.50 ansible_user=root
definiert, daß man einen Host unter dem Namen jumper
auf Port 5555
der IP 192.168.0.2.50
mit dem Benutzernamen root
anspricht.
Um die Automatisierung so nennen zu dürfen, definiert man in Playbooks Ketten von Abläufen, die dann ausgeführt werden.
Um später auf den Maschinen manierlich schaffen zu können, schiebe ich hier erstmal ein Playbook ein, das einem auf den Targethosts zsh installiert, zur Default Shell macht und sie sinnvoll konfiguriert per oh-my-zsh.
Das Playbook liegt bei mir in einem Unterordner roles
und sieht folgendermaßen aus:
---
# - hosts: Webserver
- hosts: '{{ target }}'
tasks:
- name: Check if vim is installed
stat: path=/usr/bin/vim.basic
register: vim_bin
- name: Installiere vim
apt: pkg=vim state=installed update_cache=true
when: not vim_bin.stat.exists
- name: Setze vim als default editor
shell: update-alternatives --set editor /usr/bin/vim.basic
- name: Check if zsh is installed
stat: path=/usr/bin/zsh
register: zsh_bin
- name: Install zsh
apt: pkg=zsh state=installed update_cache=true
when: not zsh_bin.stat.exists
- name: Check if zsh is installed
stat: path=/usr/bin/zsh
register: zsh_bin
- name: Set zsh as default Shell for User
shell: chsh -s $(which zsh)
when: zsh_bin.stat.exists
- name: Check if git is installed
stat: path=/usr/bin/git
register: git_bin
- name: Install git
apt: pkg=git state=installed update_cache=true
when: not git_bin.stat.exists
- name: Check if curl is installed
stat: path=/usr/bin/curl
register: curl_bin
- name: Install curl
apt: pkg=curl state=installed update_cache=true
when: not curl_bin.stat.exists
- name: Install oh-my-zsh
shell: sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
when: zsh_bin.stat.exists
- name: done
debug: msg="done."
Aufgerufen wird das Playbook mit dem Kommando:
ansible-playbook roles/systemtools.yml --extra-vars "target=jumper"
Inhaltlich sollte das Playbook selbsterklärend sein, die hosts
Zeilen definieren (auskommentiert) "Wende dies auf alle Hosts der Gruppe oder des Namens Webserver
an" bzw. Wende dies auf alle Hosts mit dem Namen oder der Gruppe Variable Target
an.
Bei Erfolg sieht das ganze dann so aus:
cm@cmmini > ~/ansible > $ ansible-playbook roles/zsh.yml --extra-vars "target=rtm-pi"
PLAY [rtm-pi] ******************************************************
TASK [setup] *******************************************************
ok: [rtm-pi]
TASK [Check if zsh is installed] ***********************************
ok: [rtm-pi]
TASK [Install zsh] *************************************************
changed: [rtm-pi]
TASK [Check if zsh is installed] ***********************************
ok: [rtm-pi]
TASK [Set zsh as default Shell for User] ***************************
changed: [rtm-pi]
TASK [Check if git is installed] ***********************************
ok: [rtm-pi]
TASK [Install git] *************************************************
skipping: [rtm-pi]
TASK [Check if curl is installed] **********************************
ok: [rtm-pi]
TASK [Install curl] ************************************************
skipping: [rtm-pi]
TASK [Install oh-my-zsh] *******************************************
changed: [rtm-pi]
TASK [done] ********************************************************
ok: [rtm-pi] => {
"msg": "done."
}
PLAY RECAP *********************************************************
rtm-pi : ok=9 changed=3 unreachable=0 failed=0
Morgen wird dieser Beitrag dann um die etckeeper und GitLab Konfiguration erweitert.
... to be continued