OpenStack Ατομικό ακαδημαϊκό έργο 2026
Ένα ιδιωτικό cloud μέσα σε ένα VM του Google Cloud
Το OpenStack σε ένα μόνο VM στο Google Cloud, και η δικτύωση Linux που επέτρεψε στα instances του να βγουν προς τα έξω και να αντέχουν μια επανεκκίνηση
- Περίοδος
- Ιούνιος 2026
- Πλατφόρμα
- DevStack σε Ubuntu 24.04, Google Cloud n2-standard-4
- Πλαίσιο
- Χαροκόπειο Πανεπιστήμιο: Διαχείριση Υπολογιστικού Νέφους
Ένα VM, δύο επίπεδα εικονικοποίησης
Η εργασία ζητούσε να στηθεί OpenStack και να διαχειριστώ έναν tenant από την αρχή ως το τέλος: project και χρήστη, quotas, δίκτυο και instances, και στο τέλος μια εφαρμογή πάνω τους. Έτρεξα το DevStack σε ένα μόνο VM στο Google Cloud.
Έτσι, στην ίδια στοίβα υπάρχουν δύο hypervisors. Το VM είναι το πρώτο επίπεδο και τα instances που ξεκινά το Nova είναι εικονικές μηχανές μέσα σε αυτό. Το δημιούργησα με ενεργό nested virtualisation.
Ένας tenant, όπως θα τον παρέδιδε ένας διαχειριστής
Το DevStack εγκατέστησε το OpenStack σε αυτόν τον έναν host, με τις υπηρεσίες του να τρέχουν ως 24 systemd units. Μέσα του έστησα έναν tenant:
- Keystone
- ένα project, έναν χρήστη με τον ρόλο member και ένα αρχείο openrc για αυτόν τον χρήστη
- Glance
- ένα image Ubuntu 22.04 Minimal και για τα δύο instances
- Nova
- δικά μου flavors και quotas για το project
- Neutron
- ιδιωτικό δίκτυο και subnet, router προς το δημόσιο δίκτυο, ένα security group και floating IPs
Ο διαχωρισμός του tenant από τον admin έφερε τα περισσότερα προβλήματα. Από τα 18 που κατέγραψα, τα 8 προήλθαν από πόρους που δημιουργήθηκαν ή αναζητήθηκαν με τα credentials του admin: ένα security group που «δεν βρέθηκε», ένα key pair «μη έγκυρο», ένα instance χωρίς ιδιωτική διεύθυνση. Κάθε πόρος ανήκει στο project που τον δημιούργησε, άρα τα credentials που χρησιμοποιούνται καθορίζουν τι υπάρχει.
Δύο δίκτυα που δεν γνώριζαν το ένα το άλλο
Η κίνηση ενός instance περνά από δύο δίκτυα. Μέσα στο OpenStack, ο router του Neutron της δίνει μια διεύθυνση από το floating range και τη στέλνει έξω από το br-ex, το Open vSwitch bridge του host για το εξωτερικό δίκτυο. Έξω, το Google Cloud γνωρίζει μία μόνο διεύθυνση για όλο το μηχάνημα: την εσωτερική διεύθυνση του VM στο ens4, τη μοναδική του κάρτα δικτύου.
Τίποτα δεν ένωνε τα δύο. Οι οδηγίες των εργαστηρίων είχαν γραφτεί για VirtualBox και δεν το κάλυπταν, οπότε ο host έπρεπε να δρομολογεί και να μεταφράζει μόνος του την κίνηση.
Η σύνδεση του ens4 στο br-ex δεν ήταν επιλογή. Είχα τρέξει αυτή την εντολή ovs-vsctl μία φορά, σε ένα από τα πρώτα εργαστήρια: η μοναδική κάρτα δικτύου του VM βγήκε από τη στοίβα δικτύου του host, το SSH κόπηκε, η serial console δεν μπόρεσε να το επαναφέρει και έστησα το VM από την αρχή. Από τότε, το ens4 έμεινε στον host και η κίνηση δρομολογείται προς αυτό, δεν γεφυρώνεται.
Δίκτυο του Google Cloud
Προωθεί κίνηση από το VM μόνο όταν η πηγή της είναι η διεύθυνση του ίδιου του VM
VM στο Google Cloud
Nested virtualisation με KVM
ens4
Η μοναδική του κάρτα δικτύου
Προστέθηκε στον host: iptables
MASQUERADE στο ens4, FORWARD μεταξύ br-ex και ens4, αποθηκευμένα με iptables-persistent
br-ex
Open vSwitch bridge για το εξωτερικό δίκτυο του OpenStack
Προστέθηκε στον host: brex-setup.service
Oneshot unit που επαναφέρει τη διεύθυνση του bridge και το route του floating range σε κάθε εκκίνηση
OpenStack, εγκατεστημένο με DevStack
Router του Neutron
Gateway στο δημόσιο δίκτυο, ένα floating IP ανά instance
Ιδιωτικό δίκτυο του tenant
Ένα security group: TCP 22, 80 και 5432, και ICMP
vm-app
NGINX στη θύρα 80, Gunicorn, Flask
vm-db
PostgreSQL 14 στη θύρα 5432
vm-appvm-dbμε ιδιωτική διεύθυνση
Έξοδος
- Instance
- Router του Neutron
- br-ex
- ens4
- Google Cloud
Έλεγχος
SSH tunnel μέσω του host προς το vm-app, θύρα 80
Ακολουθώντας ένα πακέτο ως εκεί που χανόταν
- Σύμπτωμα
- Στο πρώτο instance, το ping δεν έπαιρνε απάντηση και το
apt updateκολλούσε στο «Connecting to archive.ubuntu.com». Κανένα μήνυμα λάθους, πουθενά. - Εντοπισμός
tcpdumpσε κάθε interface κατά μήκος της διαδρομής: τα πακέτα εμφανίζονταν στο tap interface του instance και στοbr-ex, ποτέ στοens4.- Αιτία
- Ο host δεν προωθούσε πακέτα μεταξύ
br-exκαιens4, και ό,τι προωθούσε θα έφευγε με διεύθυνση πηγής από το floating range, την οποία το Google Cloud απορρίπτει χωρίς απάντηση. - Λύση
- Ενεργό IP forwarding, κανόνες FORWARD από το
br-exπρος τα έξω και πίσω μόνο για εγκατεστημένες συνδέσεις, MASQUERADE στοens4, όλα αποθηκευμένα με iptables-persistent.
Αυτό άντεξε ώσπου το VM σταμάτησε και ξεκίνησε ξανά. Οι κανόνες iptables επανήλθαν, αλλά το br-ex ξεκίνησε χωρίς τη διεύθυνση και το route του, και τα floating IPs έγιναν ξανά απρόσιτα. Στην αρχή κρατούσα μια λίστα εντολών για να τις ξανατρέχω. Μετά την αντικατέστησα με το brex-setup.service, ένα oneshot systemd unit που τρέχει μετά το δίκτυο και το DevStack και επαναφέρει το bridge σε κάθε εκκίνηση.
Τι κράτησα: το πρόβλημα βρίσκεται ένα βήμα μετά το τελευταίο interface όπου το πακέτο φαίνεται ακόμα, και μια διόρθωση που χάνεται με μια επανεκκίνηση δεν έχει τελειώσει μέχρι να γίνει μέρος της εκκίνησης.
Ένα API και η βάση του στο δίκτυο του tenant
Για να ελέγξω τον tenant από άκρη σε άκρη, έστησα μια μικρή εφαρμογή δύο επιπέδων. Τα εργαστήρια έβαζαν PostgreSQL και Flask στο ίδιο VM. Εγώ τα χώρισα σε δύο instances, ώστε το API να φτάνει στη βάση του μέσα από το ιδιωτικό δίκτυο του OpenStack.
Το vm-db τρέχει PostgreSQL 14, ρυθμισμένη να δέχεται απομακρυσμένες συνδέσεις. Το vm-app τρέχει ένα Flask API με Gunicorn ως systemd service, πίσω από NGINX στη θύρα 80, και συνδέεται στο vm-db με την ιδιωτική του διεύθυνση. Ο τελικός έλεγχος έγινε μέσω SSH tunnel από τον host: το /api/products επέστρεψε τέσσερα προϊόντα σε JSON, διαβασμένα από το άλλο instance.
Τι θα άλλαζα
Λειτούργησε, αλλά ήταν στημένο για εργαστήριο. Τα δύο instances μοιράζονται ένα security group, οπότε η θύρα της PostgreSQL είναι ανοιχτή και στο VM της εφαρμογής και η θύρα 80 στη βάση. Θα έδινα σε κάθε επίπεδο δικό του group, με τη 5432 ανοιχτή μόνο για το vm-app. Ο κωδικός της βάσης βρίσκεται μέσα στον κώδικα της εφαρμογής και η PostgreSQL ακούει σε όλα τα interfaces. Και η δικτύωση του host ανήκει στον τρόπο που στήνεται το VM, όχι σε διορθώσεις που προστέθηκαν στην πορεία.