Railshot
AI deployment & operations platform
Ανάπτυξη μιας τοπικά φτιαγμένης web εφαρμογής σε έτοιμα περιβάλλοντα cloud και on-premises, και έπειτα λειτουργία της.
Πλατφόρμα ανάπτυξης και λειτουργίας με AI που μεταφέρει μια τοπικά φτιαγμένη web εφαρμογή σε έτοιμα περιβάλλοντα cloud ή on-premises και συνεχίζει να τη λειτουργεί.
Η συστοιχία λειτουργίας και οι συστοιχίες εφαρμογών πελατών είναι χωριστές, και η δημόσια διαδρομή κρατιέται χωριστά από τον έλεγχο ανάπτυξης.
Στο K3s λειτουργίας, το dashboard, το API του προϊόντος και ο build controller τοποθετούνται σε κόμβους ρόλου platform και τα Jobs του runner σε κόμβο ρόλου build, ενώ την ανάπτυξη χειρίζεται το Argo CD. Οι εφαρμογές πελατών τρέχουν σε ορισμένο namespace μιας χωριστής συστοιχίας K3s + Cilium ενός κόμβου για κάθε καταχωρισμένο στόχο.
Build → δημοσίευση image
Το API του προϊόντος ζητά εκτέλεση GitHub Actions, και ο runner στον κόμβο build παίρνει και ελέγχει το job. Μόνο ένα bundle που πέρασε τους ίδιους ελέγχους δημοσιεύεται στο GHCR από ένα release job που φιλοξενείται στο GitHub.
API προϊόντος · cd.js → bridge.py
railshot-systemεκτέλεση · εφαρμογή: workflow_dispatchloop job · self-hosted runnerrailshot-deploy.ymlΤο API του προϊόντος ζητά εκτέλεση GitHub Actions με tenant, app, source commit και target. Το API δεν καλεί ποτέ απευθείας ένα runner Job.
build controller · CronJob
railshot-systemεκτέλεση · εφαρμογή: αναπλήρωση runner Jobrunner Job · hostNetwork · Docker socketrailshot-buildΤο CronJob του build controller (κάθε λεπτό, σε κόμβο platform) δημιουργεί runner Jobs στο namespace railshot-build. Το Role του επιτρέπει μόνο get, list και create σε Job και get, update και patch στο ένα Secret καταχώρισης runner, και δεν μπορεί να δημιουργήσει namespaces ή άλλα Secrets.
runner Job · hostNetwork · Docker socket
railshot-buildεκτέλεση · εφαρμογή: παραλαβή του jobloop job · self-hosted runnerrailshot-deploy.ymlΟ runner στον κόμβο ρόλου build (ακριβές hostname, toleration NoSchedule) παίρνει το loop job με βάση τις ετικέτες self-hosted και το εκτελεί. Ο πηγαίος κώδικας του πελάτη τρέχει στα υπάρχοντα περιορισμένα κοντέινερ build και ελέγχου του Docker.
runner Job · hostNetwork · Docker socket
railshot-buildδεδομένα: ελεγμένο bundlerelease job · GitHub-hostedrailshot-deploy.ymlΤο loop job αφήνει το bundle που πέρασε τους ίδιους ελέγχους, και το release job παίρνει μόνο αυτό το bundle.
release job · GitHub-hosted
railshot-deploy.ymlδεδομένα: δημοσίευση ανά digestGHCRΈνα release job που φιλοξενείται στο GitHub (ubuntu-24.04) δημοσιεύει το image του ελεγμένου bundle στο GHCR χωρίς νέο build. Η δημοσίευση images δεν γίνεται ποτέ μέσα στη συστοιχία εφαρμογών του πελάτη.
Config Git → Argo → namespace πελάτη
Το config Git μεταφέρει τους επιθυμητούς πόρους και το GHCR τα bytes του image. Το Argo CD εφαρμόζει μόνο στο καταχωρισμένο namespace του πελάτη.
API προϊόντος · cd.js → bridge.py
railshot-systemδεδομένα: workload commit · pushΑποθετήριο config GitΤο cd.js εκτελεί το bridge.py, που κάνει commit και push το workload.json μόνο όταν συμφωνούν η καταγραφή δημοσίευσης και ο καταχωρισμένος στόχος, και έπειτα ξαναδιαβάζει το απομακρυσμένο revision. Το Git μεταφέρει τους επιθυμητούς πόρους, το GHCR τα bytes του image.
Αποθετήριο config Gitδεδομένα: revisionArgo CD · Application
argocdΤο Application διαβάζει μόνο το περιορισμένο αποθετήριο config, τη διαδρομή και το revision του.
API προϊόντος · cd.js → bridge.py
railshot-systemεκτέλεση · εφαρμογή: Application syncArgo CD · ApplicationargocdΤο ονομασμένο Application ορίζεται με server-side apply, και ζητείται sync ενός ακριβούς revision χωρίς prune. Το ServiceAccount railshot-product του API του προϊόντος έχει τόσο το registration bootstrap που εγκατέστησε ο χειριστής (create για Secrets, AppProjects και Applications στο argocd, get, update και escalate σε ονομασμένα Roles) όσο και δικαιώματα get και patch που προστίθενται με ακριβές όνομα για κάθε επικυρωμένο στόχο. Το create του Kubernetes δεν περιορίζεται ανά όνομα, γι' αυτό η επικύρωση εισόδου του προϊόντος κρατά επίσης τα ονόματα εντός εύρους.
Argo CD · Application
argocdεκτέλεση · εφαρμογή: εφαρμογή σε namespace<app namespace>Το Argo CD εφαρμόζει στο ορισμένο namespace της συστοιχίας του πελάτη με το διαπιστευτήριο του καταχωρισμένου cluster Secret. Το AppProject επιτρέπει μόνο kinds εντός namespace και κανέναν πόρο σε επίπεδο συστοιχίας.
Deployment · Pod · image digest
<app namespace>δεδομένα: pull ανά digestGHCRΤο δημοσιευμένο image digest τραβιέται με ένα pull Secret που αναφέρεται με το όνομά του στο ίδιο namespace. Οι τιμές των Secrets δεν μπαίνουν ποτέ στο τεχνούργημα ή στο config Git.
Δημόσια διαδρομή αιτημάτων
Τα αιτήματα της εφαρμογής ακολουθούν: σημείο εισόδου L7 παρόχου → NodePort κόμβου → Service → Pod εφαρμογής. Η επιβολή πολιτικής του Cilium είναι χωριστός έλεγχος, όχι βήμα που μεταφέρει το αίτημα. Η είσοδος στο dashboard λειτουργίας είναι χωριστή διαδρομή.
Χρήστης εφαρμογήςδεδομένα: HTTPS 443Σημείο εισόδου L7 παρόχου
Οι χρήστες της εφαρμογής φτάνουν στο σημείο εισόδου L7 του παρόχου μέσω του καταχωρισμένου hostname. Κάθε πάροχος υλοποιεί το δικό του σημείο εισόδου.
Σημείο εισόδου L7 παρόχουδεδομένα: NodePortNodePort Service · Local
<app namespace>Το σημείο εισόδου προωθεί στην ιδιωτική διεύθυνση και στο NodePort του κόμβου. Το NodePort είναι αυτό που κατανεμήθηκε κατά την καταχώριση του στόχου.
NodePort Service · Local
<app namespace>δεδομένα: προς το PodDeployment · Pod · image digest<app namespace>Το Service στέλνει το αίτημα στο Pod της εφαρμογής (Deployment) στον ίδιο κόμβο. Με externalTrafficPolicy Local, η διεύθυνση προέλευσης φτάνει αμετάβλητη στον έλεγχο καταχωρισμένων CIDR του NetworkPolicy.
Cilium · Helm · VXLAN
kube-systemεκτέλεση · εφαρμογή: επιβολή πολιτικήςNetworkPolicy · καταχωρισμένα CIDR<app namespace>Το Cilium επιβάλλει το NetworkPolicy: εισερχόμενη κίνηση μόνο από τα καταχωρισμένα CIDR προς τη θύρα της εφαρμογής, και καμία εξερχόμενη από προεπιλογή, εκτός από μια εγκεκριμένη διεύθυνση βάσης δεδομένων. Τα firewall του cloud και οι κανόνες του host εξακολουθούν να μετρούν.
Χρήστης Railshotδεδομένα: dashboard · APIdashboard · nginx
railshot-systemΟι χρήστες έρχονται από το σημείο εισόδου λειτουργίας στο dashboard nginx, και το nginx στέκεται μπροστά από το API του προϊόντος. Το Service του dashboard είναι NodePort μόνο όταν δίνεται εγκεκριμένο node port, και το API μένει ClusterIP.
Επαλήθευση · παρατήρηση
Η ετυμηγορία ανάπτυξης στηρίζεται μόνο στην κατάσταση του Argo και στον έλεγχο του δημόσιου URL. Τα διαγνωστικά των Pods, τα τρέχοντα αρχεία καταγραφής και οι μετρικές λειτουργίας είναι χωριστά σήματα που δεν την αλλάζουν ποτέ.
API προϊόντος · cd.js → bridge.py
railshot-systemπαρατήρηση: revision · health · imagesArgo CD · ApplicationargocdΤο deployed απαιτεί το sync revision του Application, Synced και Healthy, operation Succeeded, και οι αναφορές image που καταγράφονται στην κατάσταση του Argo Application να ισούνται με τα images digest του αναθεωρημένου Deployment. Δεν είναι άμεση πύλη στο imageID του Pod, και μια πράσινη κατάσταση Argo από μόνη της δεν τεκμηριώνει την ταύτιση.
API προϊόντος · cd.js → bridge.py
railshot-systemπαρατήρηση: δημόσιος έλεγχος HTTPSΣημείο εισόδου L7 παρόχουΤο καταχωρισμένο δημόσιο URL ελέγχεται χωρίς ανακατευθύνσεις. Το succeeded καταγράφεται μόνο με την ετυμηγορία του Argo και αυτόν τον έλεγχο μαζί.
API προϊόντος · cd.js → bridge.py
railshot-systemπαρατήρηση: Διάγνωση Pod · όχι ετυμηγορίαDeployment · Pod · image digest<app namespace>Μετά την ετυμηγορία του Argo και τον δημόσιο έλεγχο, τα Deployment, ReplicaSets και Pods διαβάζονται χωριστά με το καταχωρισμένο διαπιστευτήριο, και το imageID και η ετοιμότητα προστίθενται ως διάγνωση ready, progressing ή unavailable. Μια αποτυχημένη ή διαφορετική διάγνωση δεν αλλάζει ποτέ την ετυμηγορία deployed ή succeeded.
API προϊόντος · cd.js → bridge.py
railshot-systemπαρατήρηση: τέλος αρχείου καταγραφής · 100 γραμμές ανά PodDeployment · Pod · image digest<app namespace>Μόνο για την τρέχουσα αναπτυγμένη operation, με το έμπιστο config και το καταχωρισμένο διαπιστευτήριο. Για κάθε τρέχον Pod (το πολύ τρία), το digest του image που τρέχει πρέπει να ισούται με το αναμενόμενο digest, και έπειτα διαβάζονται έως 100 γραμμές με απαλείψεις ανά Pod μέσα σε όριο bytes. Μια παλαιότερη προσπάθεια απαντά superseded, και χωρίς ρύθμιση not_configured. Δεν πρόκειται για συγκέντρωση αρχείων καταγραφής.
VM παρατήρησηςπαρατήρηση: scrape · θύρες NodePortrailshot-observability
Το Prometheus στο VM παρατήρησης κάνει scrape στο node-exporter και στο kube-state-metrics μέσω δύο NodePorts περιορισμένων από firewall. Τιμές που λείπουν ή είναι παλιές είναι άγνωστες, όχι μηδέν.
VM παρατήρησηςπαρατήρηση: Blackbox probeΣημείο εισόδου L7 παρόχου
Το probe_success=1 σημαίνει 2xx σε εκείνη τη θέση probe. Δεν αποδεικνύει ούτε την πρόσβαση κάθε χρήστη ούτε την αναπτυγμένη έκδοση, και δεν προάγει ποτέ το published σε deployed.
Εγκατάσταση χειριστή · καταχώριση
Η εγκατάσταση της συστοιχίας, το bootstrap καταχώρισης και οι είσοδοι στόχου, τα Secrets και η ρύθμιση ανανέωσης διαπιστευτηρίων είναι είσοδοι του χειριστή, ποτέ μέρος του payload της εφαρμογής του tenant.
Bootstrap χειριστήεκτέλεση · εφαρμογή: render platform · Secretrailshot-system
Ο χειριστής παράγει τη δήλωση platform με το render-platform.py και παρέχει το ιδιωτικό config λειτουργίας και τα Secrets. Το απομακρυσμένο MCP περιλαμβάνεται μόνο όταν δίνεται το image του, και το προσωπικό gateway (WireGuard) μόνο με --personal.
Bootstrap χειριστήεκτέλεση · εφαρμογή: bootstrap καταχώρισηςAppProject · cluster Secret
argocdΟ χειριστής εγκαθιστά στο argocd το Role του bootstrap καταχώρισης και ένα κενό Role καταχωρίσεων και προετοιμάζει τις εισόδους στόχου. Έπειτα οι βοηθητικές ρουτίνες καταχώρισης που εκτελεί το API του προϊόντος (environment.py, applications.py) γράφουν το Secret railshot-<target> με διαπιστευτήριο ορισμένου εύρους (clusterResources false, με λίστα επιτρεπόμενων namespaces) και προσθέτουν τα επικυρωμένα ακριβή ονόματα στο Role καταχωρίσεων. Η καταχώριση ανά εφαρμογή δένει ένα namespace app-<id> σε ένα AppProject με το ίδιο όνομα.
Bootstrap χειριστήεκτέλεση · εφαρμογή: εγκατάσταση K3s · CiliumCilium · Helm · VXLAN
kube-systemΤο install-k3s.sh εγκαθιστά έναν K3s server ενός κόμβου (flannel, network policy, traefik και servicelb ανενεργά, kube-proxy διατηρείται), και το Cilium εγκαθίσταται ως Helm release (kubeProxyReplacement false, VXLAN, Hubble ανενεργό).
CronJob ανανέωσης · κάθε 2 h
argocdεκτέλεση · εφαρμογή: TokenRequest · 6 hrailshot-argocd SA · token<app namespace>Το CronJob railshot-credentials ζητά κάθε δύο ώρες νέο token έξι ωρών για το SA του πελάτη. Το Role στην πλευρά του πελάτη επιτρέπει μόνο token create για το δικό του SA. Οι έξι ώρες είναι το TTL ενός token, όχι το πότε λήγει η πρόσβαση του χειριστή.
Κάθε σύνδεση με το ίδιο πάχος. Επιλέξτε μια ροή για να επισημανθεί μόνο η διαδρομή της, με αριθμημένα βήματα.
- Συνεχής · η κατεύθυνση ροής αιτημάτων, bundles, images και δηλώσεων
- Διακεκομμένη · αιτήματα εκτέλεσης, εφαρμογή, εγκατάσταση, διαπιστευτήρια
- Μακριά παύλα-τελεία · ανάγνωση κατάστασης, αρχείων καταγραφής, probes και μετρικών, χωριστά από την ετυμηγορία
- Παχιά μαύρη γραμμή · η επιλεγμένη ροή, οι αριθμοί δίνουν τη σειρά
- Κουτί · ένα namespace, με το όνομά του στην κεφαλίδα (όχι κόμβος)
- Εσωτερικό τσιπ · στοιχείο σε αυτό το namespace
- Διακεκομμένο κουτί · εκτός των συστοιχιών
- railshot-system · προϊόν
- argocd · εξουσία ανάπτυξης
- railshot-build · εξουσία Docker στον host
- GitHub · συστοιχία πελάτη
Η απόφαση τοποθέτησης της October 2 στο docs/architecture (δύο κόμβοι ρόλων) και το διάγραμμα του δημόσιου README είναι ιστορικό, και αυτός ο χάρτης ακολουθεί τις δηλώσεις και τον κώδικα στο 645e28a. Τα βέλη δείχνουν αιτία και κατεύθυνση, όχι απόδειξη ότι κάθε διαδρομή παρόχου είναι ενεργή τώρα.
- Namespaces και κόμβοι
- Ένα namespace είναι εύρος ονοματοδοσίας: ούτε υλικό ούτε, από μόνο του, όριο ασφαλείας. Οι ρόλοι platform και build είναι τοποθέτηση χρονοπρογραμματισμού με nodeSelector και taint, και αυτός ο χάρτης δεν ορίζει το πλήθος των κόμβων της συστοιχίας λειτουργίας. Η τοποθέτηση του Argo CD σε κόμβους είναι επίσης χωριστός έλεγχος.
- Εξουσία κόμβου build
- Τα runner Jobs τρέχουν με hostNetwork, το socket Docker του host, NET_ADMIN και root. Ένα namespace, ένα taint ή το RBAC δεν αφαιρούν την εξουσία Docker του host, οπότε δεν πρόκειται ούτε για απομόνωση από τον διαχειριστή του VM ούτε για sandbox για αυθαίρετο κώδικα.
- Namespace πελάτη
- Κάθε καταχωρισμένος στόχος χρησιμοποιεί μη προεπιλεγμένο namespace και AppProject (για παράδειγμα tenant-demo, ή app-<id> ανά εφαρμογή). Δημιουργούνται μόνο το Deployment μίας υπηρεσίας (με ανενεργή την αυτόματη προσάρτηση του token ServiceAccount), ένα NodePort Service και ένα NetworkPolicy, καθώς και ένα προαιρετικό PVC ή migration Job. Τα Secrets αναφέρονται μόνο με όνομα (το pull Secret και ένα εγκεκριμένο DATABASE_URL) και δεν δημιουργούνται ποτέ.
- Είσοδος AWS
- Route 53 Alias → κοινόχρηστο ALB HTTPS 443 → ιδιωτική διεύθυνση και NodePort του κόμβου του πελάτη. Πολλές εφαρμογές επαναχρησιμοποιούν έναν κόμβο, η καθεμία με δικό της namespace, Application και NodePort.
- Είσοδος GCP
- Καθολικό EXTERNAL_MANAGED HTTPS LB → ζωνικό GCE_VM_IP_PORT NEG → το ιδιωτικό NodePort του υπάρχοντος VM. Τα πιστοποιητικά προέρχονται από το Certificate Manager με εξουσιοδότηση DNS. Το module δεν κατέχει ούτε το VM ούτε το VPC, και ένα VM παραμένει μοναδικό σημείο αποτυχίας.
- Είσοδος OpenStack
- Amphora TLS listener 443 με πολιτικές L7 κατά Host και διαδρομή → HTTP NodePort. Η προεπιλεγμένη διεύθυνση είναι ιδιωτικό VIP, και τα Octavia, K3s, η βάση δεδομένων και το DNS βρίσκονται εκτός του module. Η δημόσια προσβασιμότητα και η ετοιμότητα του Amphora επί τόπου χρειάζονται χωριστή παραλαβή, και καμία επιτόπια εφαρμογή δεν έχει ακόμη επαληθευτεί με αυτό το module.
- Μεταξύ παρόχων
- Τα τρία σημεία εισόδου είναι χωριστές υλοποιήσεις, χωρίς αυτόματο failover ή αναπαραγωγή δεδομένων μεταξύ παρόχων. Η συστοιχία εφαρμογών πελάτη είναι παράδειγμα καταχωρισμένου στόχου, όχι ισχυρισμός ότι η ίδια ανάπτυξη τρέχει σε κάθε cloud ταυτόχρονα.
- Επιλογές χειριστή
- Το προσωπικό gateway (WireGuard) εντάσσεται στην πλατφόρμα μόνο όταν ο χειριστής ενεργοποιήσει το --personal και δεν είναι απαιτούμενη διαδρομή για τα cloud των πελατών. Στην υποστηριζόμενη λειτουργία direct, το VM παρατήρησης μπορεί να μοιράζεται το VM ελέγχου λειτουργίας.