Ganz vorne weg: in diesem Artikel werde ich viele der aktuellen buzzwords verwenden.
Wenn man sich die vielen neuen und spannenden technologien anschauen möchte, braucht man eine Menge Ressourcen. Nicht grade leichtgewichtig kommen sie daher. OpenStack bietet hier keine Ausnahme. Es ist das Softwareprodukt das man einsetzen möchte, wenn man sich mit den Prinzipien und funktionsweisen von Cloudumgebungen wie AWS oder GCE auseinandersetzen möchte.
OpenStack setzt sich aus einer ziemlich großen Latte an einzelnenen Services zusammen. Dabei kann man zwischen unbedingt notwendigen Diensten die Keystone und möglichen Diensten wie Zun unterscheiden. Alle diese Services haben gemeinsam, dass sie unabhängig voneinander installiert und in die Umgebung integriert werden können. Das ist bei kleinen Umgebungen wie in den meisten Firmen vermutlich so nicht notwendig. Mit einem Blick auf eine große Cloudumgebung hingegen macht es sinn.
Zum lernen und aufbauen meiner Testumgebungen nutze ich gern Vagrant. Damit kann ich mir diverse Order mit meinen Projekten machen und mir immer eine frische virtuelle Umgebung provisionieren, wenn ich sie brauche. Alles was sich nicht auf diese Art und Weise vorhalten lässt wurde nicht richtig gebaut und ist mist.
Es macht wirklich keinen Spaß OpenStack von Hand zu installieren. Daher sollte man sich eine Lösung wie Kolla-Ansible ansehen. Kolla-Ansible ist ein wirklich interessantes Projekt, das die oben genannten OpenStack-Komponenten in Docker verpackt und ausliefert. So spart man sich enorm viel Einrichtungsaufwand und hat vor allem nochmals eine Abstraktionsebene die im Falle eine Fehlverhaltens oder defekte unkompliziert getauscht und beeinflusst werden kannst.
Zentrale Komponente von Kolla-Ansible ist die Datei /etc/kolla/globals.yml über diese werden die notwendigen und gewünschten Einstellungen definiert und über die kolla-ansible Befehle angewendet.
Sofern eine VM zur Hand ist, gehe ich folgenden Schritte für eine laufenden All-in-One Umgebung.
Wer sich ein wenig tiefer einlesen möchte, dem sei die Dokumentation ans Herz gelegt:
https://docs.openstack.org/kolla-ansible/latest/user/quickstart.html
Nach der Dokumentation sollte eine all-in-one Maschine folgende Ressourcen aufweisen
Jetzt geht es ans eingemachte. Wir fangen an den Server zu installieren
Während meiner Setuporgien habe ich ein paar Fehler gehabt, welche ich durch die Art und Weise der Einrichtung umgehe.
yum install -y epel-release
yum upgrade -y
yum install -y python-devel libffi-devel gcc openssl-devel libselinux-python
pip install -U pip
pip uninstall requests
pip uninstall urllib3
yum remove -y python-urllib3 python-requests
pip freeze | grep requests
yum install -y python-urllib3 python-requests
reboot
Ich gehe den Weg direkt auf der Maschine zu arbeiten ohne weitere Verschachtelungen.
easy_install pip
pip install -U pip
yum install ansible
pip install --upgrade decorate
pip install kolla-ansible
pip install --ignore-installed python-openstackclient
mkdir -p /etc/kolla
chown $USER:$USER /etc/kolla
cp -r /usr/share/kolla-ansible/etc_examples/kolla/* /etc/kolla
cp /usr/share/kolla-ansible/ansible/inventory/* .
Nun sollten wir ein Kolla-Ansible samt Abhängigkeiten und Inventory haben. Ein Inventory wird genutzt um die Umgebung der Server zu pflegen und Aufganen zu verteilen. In unserem Fall landet alles auf einem Server - sollte man aber vor haben OpenStack so richtig zu nutzen und eine größere Installation planen, so sollte man sich unbedingt anschauen was die Datei multinode zu bieten hat.
Bei einem System wie OpenStack kann man sich vorstellen, das an allen Ecken und enden ein Kennwort vergeben wird. Wir können froh sein, dass Kolla-Ansible sich für uns darum kümmert - ansonsten wären wir lange beschäftigt.
kolla-genpwd
Dieser Befelhl sorgt dafür, dass wir die Datei /etc/kolla/passwords.yml mit Leben füllen. Darin enthalten sind alle Kennwörter - also vorsicht.
Die Datei /etc/kolla/globals.yml ist die zentrale Anlaufstelle um die Ausstattung und Konfiguration unseres OpenStack Server vorzunehmen. Hier sollte man sich Zeit lassen und die Möglichkeite studieren. In meinem einfachen Fall enthält die Datei den folgenden Inhalt:
---
---
config_strategy: "COPY_ALWAYS"
kolla_base_distro: "centos"
kolla_install_type: "binary"
openstack_release: "train"
kolla_internal_vip_address: "192.168.124.254"
kolla_external_vip_address: "{{ kolla_internal_vip_address }}"
docker_configure_for_zun: "no"
network_interface: "eth0"
network_address_family: "ipv4"
openstack_region_name: "itemisDemoRegion"
enable_openstack_core: "yes"
enable_aodh: "yes"
enable_heat: "{{ enable_openstack_core | bool }}"
enable_horizon: "{{ enable_openstack_core | bool }}"
enable_horizon_blazar: "{{ enable_blazar | bool }}"
enable_horizon_cloudkitty: "{{ enable_cloudkitty | bool }}"
enable_horizon_congress: "{{ enable_congress | bool }}"
enable_horizon_designate: "{{ enable_designate | bool }}"
enable_horizon_fwaas: "{{ enable_neutron_fwaas | bool }}"
enable_horizon_freezer: "{{ enable_freezer | bool }}"
enable_horizon_heat: "{{ enable_heat | bool }}"
enable_horizon_ironic: "{{ enable_ironic | bool }}"
enable_horizon_karbor: "{{ enable_karbor | bool }}"
enable_horizon_magnum: "{{ enable_magnum | bool }}"
enable_horizon_manila: "{{ enable_manila | bool }}"
enable_horizon_masakari: "{{ enable_masakari | bool }}"
enable_horizon_mistral: "{{ enable_mistral | bool }}"
enable_horizon_murano: "{{ enable_murano | bool }}"
enable_horizon_neutron_vpnaas: "{{ enable_neutron_vpnaas | bool }}"
enable_horizon_octavia: "{{ enable_octavia | bool }}"
enable_horizon_qinling: "{{ enable_qinling | bool }}"
enable_horizon_sahara: "{{ enable_sahara | bool }}"
enable_horizon_searchlight: "{{ enable_searchlight | bool }}"
enable_horizon_senlin: "{{ enable_senlin | bool }}"
enable_horizon_solum: "{{ enable_solum | bool }}"
enable_horizon_tacker: "{{ enable_tacker | bool }}"
enable_horizon_trove: "{{ enable_trove | bool }}"
enable_horizon_vitrage: "{{ enable_vitrage | bool }}"
enable_horizon_watcher: "{{ enable_watcher | bool }}"
enable_horizon_zun: "{{ enable_zun | bool }}"
enable_kuryr: "no"
enable_magnum: "yes"
enable_mistral: "no"
enable_murano: "no"
enable_senlin: "yes"
enable_zun: "no"
nova_compute_virt_type: "qemu"
num_nova_fake_per_node: 5
Jetzt geht es los und wir bauen unser OpenStack auf
kolla-ansible -i ./all-in-one bootstrap-servers
kolla-ansible -i ./all-in-one prechecks
kolla-ansible -i ./all-in-one deploy
Das Passwort für das Web-Ui-Dashboard Dingen erhalten wir aus unserer zentralen Kennwort-Datenbank:
grep -i keystone_admin_password /etc/kolla/passwords.yml
Nun können wir uns schon auf dem Horizon-Web-Ding anmelden. Dazu steuern wir einfach die Host-Adresse - oder noch besser die virtual IP an. In meinem Fall also die 192.168.124.254
Weil das aber voll langweilig ist, setzen wir noch einen nach und installieren gleich ein paar Demo Daten:
kolla-ansible post-deploy
. /etc/kolla/admin-openrc.sh
#deploy the demo stuff
/usr/share/kolla-ansible/init-runonce
# deploy demo instance
openstack server create --image cirros --flavor m1.tiny --key-name mykey --network demo-net demo1
Quellen und Links:
Mir gehen ja hin und wieder gewisse Tatsachen auf den Zeiger. Zum Beispiel unterschiedliche Zeiten auf Serversystemen. Daher hab ich mir folgenden Snippet zurecht gelegt, damit ich einheitlich mal alles richtig einstellen kann. Ausgetauscht werden muss lediglich der NTP-Server - sofern denn einer im Netzwerk bekannt ist. Und natürlich die Zeit selbst.
echo "NTP=0.de.pool.ntp.org 1.de.pool.ntp.org 2.de.pool.ntp.org" >>/etc/systemd/timesyncd.conf
timedatectl set-ntp false
timedatectl set-time 12:45:30
timedatectl set-local-rtc 0
timedatectl set-ntp true
timedatectl
CGI ist nicht tot zu bekommen. Warum auch? Ist es doch eine (für den Admin) coole Lösung um mal fix ein BASH Skript zu schreiben und dieses durch eine URL angetriggert auszuführen.
Leider läuft das ganze nicht out-of-the-Box, daher müssen folgende Dinge auf einem CentOS System passieren, damit es funktioniert:
yum install -y fcgiwrap.x86_64 spawn-fcgi
damit haben wir dann schon die Grundlage geschaffen.
Nun müssen wir noch spawn-fcgi konfigurieren, damit es später mit unserem NGINX zusammenspielt:
cat << EOF > /etc/sysconfig/spawn-fcgi
FCGI_SOCKET=/var/run/fcgiwrap.socket
FCGI_PROGRAM=/usr/sbin/fcgiwrap
FCGI_USER=nginx
FCGI_GROUP=nginx
FCGI_EXTRA_OPTIONS="-M 0777"
OPTIONS="-u $FCGI_USER -g $FCGI_GROUP -s $FCGI_SOCKET -S $FCGI_EXTRA_OPTIONS -F 1 -P /var/run/spawn-fcgi.pid -- $FCGI_PROGRAM"
EOF
damit legen wir nach dem Start einen unix socket für die Kommunikatio unter /var/run/fcgiwrap.socket an und übergeben die Rechte an NGINX.
Nun machen wir uns noch ein Skriptverzeichnis:
mkdir -p -m 770 /var/www/cgi-bin
chown -vR nginx:nginx /var/www/cgi-bin
und natürlich müssen wir unserem NGINX beibringen mit dem Dienst zu reden - dazu nutzen wir eine location directive:
location / {
root /var/www/cgi-bin;
fastcgi_intercept_errors on;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
}
im Anschluss müssen wir unsere Dienste noch aktualisieren:
systemctl enable spawn-fcgi
systemctl start spawn-fcgi
systemctl restart nginx
von nun an sollten wir in der Lage sein Skripte unter /var/www/cgi-bin über den Aufruf innerhalb der URL anzusprechen und zur Ausführung zu bewegen. Ein Skript sollte übrigens in etwa so beginnen:
#!/bin/bash
echo "Content-type: text/html"
echo ""
echo "<html>"
echo "<head>"
echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">"
echo "<title>Bash CGI script</title>"
echo "</head>"
echo "<body>"
echo ""
echo ""
echo ""
echo "</body>"
echo "</html>"