Railshot
AI deployment & operations platform
Udrul en lokalt bygget webapp i forberedte cloud- og on-premises-miljøer, og driv den derefter.
En AI-platform til udrulning og drift, der bringer en lokalt bygget webapp til forberedte cloud- eller on-premises-miljøer og holder den kørende.
Drifts- og kundeappklynger er adskilt, og den offentlige sti holdes adskilt fra udrulningsstyringen.
I drifts-K3s placeres dashboard, produkt-API og build controller på noder med platform-rolle og runner-Jobs på en node med build-rolle, mens Argo CD står for udrulningen. Kundeapps kører i et udpeget namespace i en separat K3s + Cilium-klynge med én node for hvert registreret mål.
Build → publicér image
Produkt-API'et anmoder om en GitHub Actions-kørsel, og runneren på build-noden tager jobbet og kontrollerer det. Kun en bundle, der bestod de samme kontroller, publiceres til GHCR af et GitHub-hostet release-job.
produkt-API · cd.js → bridge.py
railshot-systemkøre · anvende: workflow_dispatchloop job · self-hosted runnerrailshot-deploy.ymlProdukt-API'et anmoder om en GitHub Actions-kørsel med tenant, app, source commit og target. API'et kalder aldrig et runner-Job direkte.
build controller · CronJob
railshot-systemkøre · anvende: genopfyld runner-Jobrunner Job · hostNetwork · Docker socketrailshot-buildBuild controllerens CronJob (hvert minut, på en platform-node) opretter runner-Jobs i namespacet railshot-build. Dens Role tillader kun get, list og create på Jobs samt get, update og patch på det ene Secret til runner-registrering; den kan ikke oprette namespaces eller andre Secrets.
runner Job · hostNetwork · Docker socket
railshot-buildkøre · anvende: modtag jobloop job · self-hosted runnerrailshot-deploy.ymlRunneren på noden med build-rolle (præcist hostname, NoSchedule-toleration) tager loop-jobbet ud fra dets self-hosted-labels og kører det. Kundens kilde kører i de eksisterende begrænsede Docker-containere til build og kontrol.
runner Job · hostNetwork · Docker socket
railshot-builddata: testet bundlerelease job · GitHub-hostedrailshot-deploy.ymlLoop-jobbet efterlader den bundle, der bestod de samme kontroller, og release-jobbet tager kun den bundle.
release job · GitHub-hosted
railshot-deploy.ymldata: publicér via digestGHCREt GitHub-hostet release-job (ubuntu-24.04) publicerer den testede bundles image til GHCR uden at bygge det igen. Publicering af images sker aldrig inde i kundeappklyngen.
Config-Git → Argo → kundens namespace
Config-Git bærer de ønskede ressourcer og GHCR image-bytes. Argo CD anvender kun på det registrerede kunde-namespace.
produkt-API · cd.js → bridge.py
railshot-systemdata: workload commit · pushconfig-Git-repositorycd.js kører bridge.py, der kun committer og pusher workload.json, når publiceringsloggen og det registrerede mål stemmer overens, og derefter læser den eksterne revision tilbage. Git bærer de ønskede ressourcer; GHCR bærer image-bytes.
config-Git-repositorydata: revisionArgo CD · Application
argocdApplication læser kun sit begrænsede config-repository, sin sti og sin revision.
produkt-API · cd.js → bridge.py
railshot-systemkøre · anvende: Application syncArgo CD · ApplicationargocdDen navngivne Application sættes med server-side apply, og der anmodes om en sync af én præcis revision uden prune. Produkt-API'ets ServiceAccount railshot-product har både den registrerings-bootstrap, operatøren har installeret (create på Secrets, AppProjects og Applications i argocd; get, update og escalate på navngivne Roles), og get- og patch-rettigheder, der tilføjes med præcist navn for hvert valideret mål. Kubernetes' create kan ikke begrænses efter navn, så produktets inputvalidering holder også navnene inden for omfanget.
Argo CD · Application
argocdkøre · anvende: anvend på namespace<app namespace>Argo CD anvender på det udpegede namespace i kundeklyngen med legitimationen fra det registrerede cluster-Secret. AppProject tillader kun namespace-afgrænsede kinds og ingen ressourcer på klyngeniveau.
Deployment · Pod · digest-image
<app namespace>data: pull via digestGHCRDet publicerede digest-image hentes med et pull-Secret, der refereres ved navn i samme namespace. Secret-værdier kommer aldrig ind i artefaktet eller config-Git.
Offentlig forespørgselssti
Appforespørgsler går udbyderens L7-indgang → nodens NodePort → Service → appens Pod. Ciliums håndhævelse af policy er en separat kontrol, ikke et led, der bærer forespørgslen. Vejen ind til driftsdashboardet er en separat sti.
Appbrugerdata: HTTPS 443Udbyderens L7-indgang
Appbrugere når udbyderens L7-indgang via det registrerede hostname. Hver udbyder implementerer sin egen indgang.
Udbyderens L7-indgangdata: NodePortNodePort Service · Local
<app namespace>Indgangen videresender til nodens private adresse og NodePort. NodePort er den, der blev tildelt ved registrering af målet.
NodePort Service · Local
<app namespace>data: til PodDeployment · Pod · digest-image<app namespace>Service sender forespørgslen til appens Pod (Deployment) på samme node. Med externalTrafficPolicy Local når kildeadressen uændret frem til NetworkPolicy'ens kontrol af registrerede CIDR'er.
Cilium · Helm · VXLAN
kube-systemkøre · anvende: håndhæv policyNetworkPolicy · kun angivne CIDR'er<app namespace>Cilium håndhæver NetworkPolicy: ingress kun fra de registrerede CIDR'er til appens port; ingen egress som standard, bortset fra en godkendt databaseadresse. Cloud-firewalls og værtsregler har stadig betydning.
Railshot-brugerdata: dashboard · APIdashboard · nginx
railshot-systemBrugere kommer gennem driftsindgangen til nginx-dashboardet, og nginx står foran produkt-API'et. Dashboardets Service er kun en NodePort, når en godkendt nodeport angives; API'et forbliver ClusterIP.
Verificér · observér
Udrulningsdommen hviler kun på Argo-status og kontrollen af den offentlige URL. Pod-diagnostik, aktuelle logs og driftsmetrikker er separate signaler, der aldrig ændrer den.
produkt-API · cd.js → bridge.py
railshot-systemobservere: revision · health · imagesArgo CD · ApplicationargocdDeployed kræver Applicationens sync-revision, Synced og Healthy, operation Succeeded og at image-referencerne i Argo Applicationens status er lig med den gennemgåede Deployments digest-images. Det er ikke en direkte gate på Pod'ens imageID, og en grøn Argo-status alene fastslår ikke overensstemmelsen.
produkt-API · cd.js → bridge.py
railshot-systemobservere: offentlig HTTPS-kontrolUdbyderens L7-indgangDen registrerede offentlige URL kontrolleres uden omdirigeringer. Succeeded registreres kun med både Argo-dommen og denne kontrol.
produkt-API · cd.js → bridge.py
railshot-systemobservere: Pod-diagnostik · ikke dommenDeployment · Pod · digest-image<app namespace>Efter Argo-dommen og den offentlige kontrol læses Deployment, ReplicaSets og Pods separat med den registrerede legitimation, og imageID og parathed tilføjes som en diagnose: ready, progressing eller unavailable. En fejlet eller afvigende diagnose ændrer aldrig dommen deployed eller succeeded.
produkt-API · cd.js → bridge.py
railshot-systemobservere: log-tail · 100 linjer pr. PodDeployment · Pod · digest-image<app namespace>Kun for den aktuelt udrullede operation, med den betroede config og den registrerede legitimation. For hver aktuel Pod (højst tre) skal den kørende image-digest være lig med den forventede digest; derefter læses op til 100 maskerede linjer pr. Pod inden for en bytegrænse. Et ældre forsøg svarer superseded; uden konfiguration not_configured. Det er ikke logaggregering.
Observations-VMobservere: scrape · NodePortsrailshot-observability
Prometheus på observations-VM'en scraper node-exporter og kube-state-metrics gennem to NodePorts, der er begrænset af en firewall. Manglende eller forældede værdier er ukendte, ikke nul.
Observations-VMobservere: Blackbox probeUdbyderens L7-indgang
probe_success=1 betyder en 2xx på det sted, proben kører fra. Det beviser hverken alle brugeres adgang eller den udrullede version, og det ophøjer aldrig published til deployed.
Operatørinstallation · registrering
Klyngeinstallation, registrerings-bootstrap og input til mål, Secrets og opsætningen til fornyelse af legitimation er operatørinput, aldrig en del af tenant-appens payload.
Operatør-bootstrapkøre · anvende: generér platform · Secretrailshot-system
Operatøren genererer platform-deklarationen med render-platform.py og leverer den private driftskonfiguration og Secrets. Den eksterne MCP medtages kun, når dens image leveres, og den personlige gateway (WireGuard) kun med --personal.
Operatør-bootstrapkøre · anvende: registrerings-bootstrapAppProject · cluster Secret
argocdOperatøren installerer en Role til registrerings-bootstrap og en tom Role til registreringer i argocd og forbereder input til målene. Registreringshjælperne, som produkt-API'et kører (environment.py, applications.py), skriver derefter Secret'et railshot-<target> med en afgrænset legitimation (clusterResources false, tilladte namespaces angivet) og føjer de validerede præcise navne til Role'en for registreringer. Registrering pr. app binder et namespace app-<id> til et AppProject med samme navn.
Operatør-bootstrapkøre · anvende: installér K3s · CiliumCilium · Helm · VXLAN
kube-systeminstall-k3s.sh installerer en K3s-server med én node (flannel, network policy, traefik og servicelb slået fra; kube-proxy bevaret), og Cilium installeres som en Helm-release (kubeProxyReplacement false, VXLAN, Hubble slået fra).
fornyelses-CronJob · hver 2. time
argocdkøre · anvende: TokenRequest · 6 hrailshot-argocd SA · udstedelse af token<app namespace>CronJob'en railshot-credentials anmoder hver anden time om et nyt token på seks timer til kundens SA. Role'en på kundesiden tillader kun token create for dens egen SA. Seks timer er ét tokens TTL, ikke tidspunktet, hvor operatørens adgang ophører.
Alle forbindelser med samme tykkelse. Vælg et flow for kun at fremhæve dets vej med nummererede trin.
- Fuldt optrukket · den retning, forespørgsler, bundles, images og deklarationer flyder
- Stiplet · kørselsanmodninger, anvend, installér, legitimation
- Lang streg-prik · læsning af status, logs, prober, metrikker; adskilt fra dommen
- Kraftig sort linje · det valgte flow; tal angiver rækkefølgen
- Boks · et namespace med navnet i overskriften (ikke en node)
- Indre chip · en komponent i det namespace
- Stiplet boks · uden for klyngerne
- railshot-system · produkt
- argocd · udrulningsbeføjelse
- railshot-build · rettigheder til værtens Docker
- GitHub · kundeklynge
Placeringsbeslutningen fra 2. oktober i docs/architecture (to rollenoder) og diagrammet i den offentlige README er historik; dette kort følger deklarationerne og koden ved 645e28a. Pilene viser årsag og retning, ikke bevis for, at alle provider-stier er aktive nu.
- Namespaces og noder
- Et namespace er et navneområde: hverken hardware eller i sig selv en sikkerhedsgrænse. Rollerne platform og build er planlægningsplacering via nodeSelector og taint; dette kort fastlægger ikke antallet af noder i driftsklyngen. Argo CD's placering på noder er også en separat kontrol.
- Build-nodens rettigheder
- Runner-Jobs kører med hostNetwork, værtens Docker-socket, NET_ADMIN og root. Et namespace, en taint eller RBAC fjerner ikke rettighederne til værtens Docker, så det er hverken isolation på VM-administratorniveau eller en sandkasse til vilkårlig kode.
- Kundens namespace
- Hvert registreret mål bruger et namespace og et AppProject, der ikke er standard (for eksempel tenant-demo eller app-<id> pr. app). Der oprettes kun én tjenestes Deployment (automount af ServiceAccount-token slået fra), NodePort-Service og NetworkPolicy samt eventuelt en PVC eller et migration-Job; Secrets refereres kun ved navn (pull-Secret'et og en godkendt DATABASE_URL) og oprettes aldrig.
- AWS-indgang
- Route 53 Alias → delt ALB HTTPS 443 → kundenodens private adresse og NodePort. Mange apps genbruger én node, hver med sit eget namespace, sin Application og sin NodePort.
- GCP-indgang
- Global EXTERNAL_MANAGED HTTPS LB → zonal GCE_VM_IP_PORT NEG → den eksisterende VM's private NodePort. Certifikater kommer fra Certificate Manager med DNS-autorisation. Modulet ejer hverken VM'en eller VPC'en, og én VM forbliver et enkelt fejlpunkt.
- OpenStack-indgang
- Amphora TLS-listener 443 med L7-policyer for Host og sti → HTTP NodePort. Standardadressen er en privat VIP; Octavia, K3s, databasen og DNS ligger uden for modulet. Offentlig tilgængelighed og Amphora-parathed på stedet kræver separat accept, og der er endnu ikke verificeret nogen anvendelse på stedet med dette modul.
- På tværs af udbydere
- De tre indgange er separate implementeringer uden automatisk failover eller replikering mellem udbydere. Kundeappklyngen er et eksempel på et registreret mål, ikke en påstand om, at den samme udrulning kører på alle clouds på én gang.
- Operatørvalg
- Den personlige gateway (WireGuard) indgår kun i platformen, når operatøren slår --personal til; den er ikke en påkrævet sti for kundeclouds. I den understøttede direct-tilstand kan observations-VM'en dele driftens kontrol-VM.