RAILSHOT.
Tilbake til salen

Railshot

AI deployment & operations platform

Rull ut en lokalt bygget nettapp til forberedte sky- og on-premises-miljøer, og drift den deretter.

En AI-plattform for utrulling og drift som tar en lokalt bygget nettapp til forberedte sky- eller on-premises-miljøer og holder den i gang.

28. september 2026 til 4. oktober 2026 · Avsluttet

Teamprosjekt · min del: planlegging og implementering av CI, CSP-klynger og Ansible-grensesnitt, drift, kodegjennomgang og integrasjon i teamet

SoftBank Hackathon 2026 powered by KOREC & ProgateDeltaker i innledende runde · uttak til finalen kunngjøres 26. oktober 2026 (per 7. oktober 2026)

  • NettImplementert · hackathon
  • MCP-serverImplementert · ekstern · lokal

Drifts- og kundeappklynger er atskilt, og den offentlige stien holdes atskilt fra utrullingsstyringen.

I drifts-K3s plasseres dashbord, 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 utrullingen. Kundeapper kjører i et angitt namespace i en separat K3s + Cilium-klynge med én node for hvert registrerte mål.

Klyngekart · tegnet ut fra deklarasjoner og kode ved offentlig commit 645e28a
Kart over Railshots drifts- og kundeklyngerDrifts-K3s-klyngen og en registrert kundeappklynge. I driftsklyngen plasserer namespacet railshot-system dashbord, produkt-API, ekstern MCP (bare når imaget leveres) og build controller på noder med platform-rolle; runner-Jobs i namespacet railshot-build tar GitHub Actions-jobber på den taintede noden med build-rolle. En GitHub-hostet release-jobb publiserer den testede bundelen til GHCR. Produkt-API-et committer arbeidslasten til config-Git og synkroniserer en Application i namespacet argocd, og Argo CD tar i bruk en Deployment, en NodePort-Service og en NetworkPolicy på namespacet som er registrert i kundeklyngen. Appforespørsler kommer inn gjennom leverandørens L7-inngang til nodens NodePort og Service og deretter appens Pod. Utrullingsdommen hviler bare på Argo-status og kontrollen av den offentlige URL-en; Pod-diagnostikk, logger og metrikker leses som separate signaler. Operatørens installasjons- og registreringsinput holdes atskilt fra tenant-appens payload.Railshot-brukerdashbord · MCPOperatør-bootstrapinstaller · registrer · SecretGHCRdigest-imagesconfig-Git-repositoryworkload.json · revisionLeverandørens L7-inngangALB · GCP LB · AmphoraAppbrukeroffentlig HTTPSObservasjons-VMutenfor kundens K3s · Composerailshot-systemdashboard · nginxekstern MCP · bare med et imagebuild controller · CronJobprodukt-API · cd.js → bridge.pyargocdArgo CD · ApplicationAppProject · cluster Secretfornyelses-CronJob · hver 2. timerailshot-buildrunner Job · hostNetwork · Docker socketrailshot-deploy.ymlloop job · self-hosted runnerrelease job · GitHub-hosted<app namespace>Deployment · Pod · digest-imageNodePort Service · LocalNetworkPolicy · bare angitte CIDR-errailshot-argocd SA · utstedelse av tokenkube-systemCilium · Helm · VXLANrailshot-observabilitynode-exporterkube-state-metricsDriftsklynge · K3sAWS · rollenodernoder med platform-rollenodeSelectornode med build-rolleNoSchedule taintGitHubActions · GHCRKundeappklynge · eksempelén per registrert målÉn K3s-node · serverCilium · kube-proxy beholdt1workflow_dispatch2fyll på runner-Job3motta jobb4testet bundle5 publiser via digest · release job · GitHub-hosted → GHCR51workload commit · push2revision3 Application sync · produkt-API · cd.js → bridge.py → Argo CD · Application34ta i bruk på namespace5pull via digest1HTTPS 4432NodePort3 til Pod · NodePort Service · Local → Deployment · Pod · digest-image34 håndhev policy · Cilium · Helm · VXLAN → NetworkPolicy · bare angitte CIDR-er45 dashbord · API · Railshot-bruker → dashboard · nginx51 revisjon · health · images · produkt-API · cd.js → bridge.py → Argo CD · Application12offentlig HTTPS-kontroll3Pod-diagnostikk · ikke dommen4logg-tail · 100 linjer per Pod5scrape · NodePorts6Blackbox probe1generer platform · Secret2registrerings-bootstrap3installer K3s · Cilium4TokenRequest · 6 h

Bygg → publiser image

Produkt-API-et ber om en GitHub Actions-kjøring, og runneren på build-noden tar jobben og kontrollerer den. Bare en bundle som besto de samme kontrollene, publiseres til GHCR av en GitHub-hostet release-jobb.

  1. produkt-API · cd.js → bridge.pyrailshot-systemkjøre · ta i bruk: workflow_dispatchloop job · self-hosted runnerrailshot-deploy.yml

    Produkt-API-et ber om en GitHub Actions-kjøring med tenant, app, source commit og target. API-et kaller aldri et runner-Job direkte.

  2. build controller · CronJobrailshot-systemkjøre · ta i bruk: fyll på runner-Jobrunner Job · hostNetwork · Docker socketrailshot-build

    CronJob-en til build controller (hvert minutt, på en platform-node) oppretter runner-Jobs i namespacet railshot-build. Dens Role tillater bare get, list og create på Jobs samt get, update og patch på det ene Secret-et for runner-registrering; den kan ikke opprette namespaces eller andre Secrets.

  3. runner Job · hostNetwork · Docker socketrailshot-buildkjøre · ta i bruk: motta jobbloop job · self-hosted runnerrailshot-deploy.yml

    Runneren på noden med build-rolle (eksakt hostname, NoSchedule-toleration) tar loop-jobben ut fra self-hosted-etikettene og kjører den. Kundens kildekode kjører i de eksisterende begrensede Docker-containerne for bygg og kontroll.

  4. runner Job · hostNetwork · Docker socketrailshot-builddata: testet bundlerelease job · GitHub-hostedrailshot-deploy.yml

    Loop-jobben etterlater bundelen som besto de samme kontrollene, og release-jobben tar bare den bundelen.

  5. release job · GitHub-hostedrailshot-deploy.ymldata: publiser via digestGHCR

    En GitHub-hostet release-jobb (ubuntu-24.04) publiserer imaget fra den testede bundelen til GHCR uten å bygge det på nytt. Publisering av images skjer aldri inne i kundeappklyngen.

Config-Git → Argo → kundens namespace

Config-Git bærer de ønskede ressursene og GHCR image-bytene. Argo CD tar bare i bruk på det registrerte kunde-namespacet.

  1. produkt-API · cd.js → bridge.pyrailshot-systemdata: workload commit · pushconfig-Git-repository

    cd.js kjører bridge.py, som bare committer og pusher workload.json når publiseringsloggen og det registrerte målet stemmer overens, og deretter leser den eksterne revisjonen tilbake. Git bærer de ønskede ressursene; GHCR bærer image-bytene.

  2. config-Git-repositorydata: revisionArgo CD · Applicationargocd

    Application leser bare sitt begrensede config-repository, sin sti og sin revisjon.

  3. produkt-API · cd.js → bridge.pyrailshot-systemkjøre · ta i bruk: Application syncArgo CD · Applicationargocd

    Den navngitte Application settes med server-side apply, og det bes om en sync av én eksakt revisjon uten prune. ServiceAccount-en railshot-product i produkt-API-et har både registrerings-bootstrapen operatøren har installert (create på Secrets, AppProjects og Applications i argocd; get, update og escalate på navngitte Roles) og get- og patch-rettigheter som legges til med eksakt navn for hvert validerte mål. create i Kubernetes kan ikke begrenses etter navn, så produktets inputvalidering holder også navnene innenfor omfanget.

  4. Argo CD · Applicationargocdkjøre · ta i bruk: ta i bruk på namespace<app namespace>

    Argo CD tar i bruk på det angitte namespacet i kundeklyngen med legitimasjonen fra det registrerte cluster-Secret-et. AppProject tillater bare namespace-avgrensede kinds og ingen ressurser på klyngenivå.

  5. Deployment · Pod · digest-image<app namespace>data: pull via digestGHCR

    Det publiserte digest-imaget hentes med et pull-Secret som refereres ved navn i samme namespace. Secret-verdier havner aldri i artefaktet eller config-Git.

Offentlig forespørselssti

Appforespørsler går leverandørens L7-inngang → nodens NodePort → Service → appens Pod. Ciliums håndheving av policy er en separat kontroll, ikke et ledd som bærer forespørselen. Veien inn til driftsdashbordet er en separat sti.

  1. Appbrukerdata: HTTPS 443Leverandørens L7-inngang

    Appbrukere når leverandørens L7-inngang via det registrerte hostnavnet. Hver leverandør implementerer sin egen inngang.

  2. Leverandørens L7-inngangdata: NodePortNodePort Service · Local<app namespace>

    Inngangen videresender til nodens private adresse og NodePort. NodePort er den som ble tildelt ved registrering av målet.

  3. NodePort Service · Local<app namespace>data: til PodDeployment · Pod · digest-image<app namespace>

    Service sender forespørselen til appens Pod (Deployment) på samme node. Med externalTrafficPolicy Local når kildeadressen uendret fram til NetworkPolicy-ens kontroll av registrerte CIDR-er.

  4. Cilium · Helm · VXLANkube-systemkjøre · ta i bruk: håndhev policyNetworkPolicy · bare angitte CIDR-er<app namespace>

    Cilium håndhever NetworkPolicy: ingress bare fra de registrerte CIDR-ene til appens port; ingen egress som standard, unntatt en godkjent databaseadresse. Skybrannmurer og vertsregler har fortsatt betydning.

  5. Railshot-brukerdata: dashbord · APIdashboard · nginxrailshot-system

    Brukere kommer gjennom driftsinngangen til nginx-dashbordet, og nginx står foran produkt-API-et. Dashbordets Service er bare en NodePort når en godkjent nodeport er angitt; API-et forblir ClusterIP.

Verifiser · observer

Utrullingsdommen hviler bare på Argo-status og kontrollen av den offentlige URL-en. Pod-diagnostikk, gjeldende logger og driftsmetrikker er separate signaler som aldri endrer den.

  1. produkt-API · cd.js → bridge.pyrailshot-systemobservere: revisjon · health · imagesArgo CD · Applicationargocd

    Deployed krever Applicationens sync-revisjon, Synced og Healthy, operation Succeeded og at image-referansene i statusen til Argo Application er lik digest-imagene til den gjennomgåtte Deploymenten. Dette er ikke en direkte port på Podens imageID, og en grønn Argo-status alene fastslår ikke samsvaret.

  2. produkt-API · cd.js → bridge.pyrailshot-systemobservere: offentlig HTTPS-kontrollLeverandørens L7-inngang

    Den registrerte offentlige URL-en kontrolleres uten omdirigeringer. Succeeded registreres bare med både Argo-dommen og denne kontrollen.

  3. produkt-API · cd.js → bridge.pyrailshot-systemobservere: Pod-diagnostikk · ikke dommenDeployment · Pod · digest-image<app namespace>

    Etter Argo-dommen og den offentlige kontrollen leses Deployment, ReplicaSets og Pods separat med den registrerte legitimasjonen, og imageID og beredskap legges til som en diagnose: ready, progressing eller unavailable. En mislykket eller avvikende diagnose endrer aldri dommen deployed eller succeeded.

  4. produkt-API · cd.js → bridge.pyrailshot-systemobservere: logg-tail · 100 linjer per PodDeployment · Pod · digest-image<app namespace>

    Bare for den gjeldende utrullede operasjonen, med den klarerte configen og den registrerte legitimasjonen. For hver gjeldende Pod (høyst tre) må den kjørende image-digesten være lik den forventede digesten; deretter leses opptil 100 maskerte linjer per Pod innenfor en bytegrense. Et eldre forsøk svarer superseded; uten konfigurasjon not_configured. Dette er ikke loggaggregering.

  5. Observasjons-VMobservere: scrape · NodePortsrailshot-observability

    Prometheus på observasjons-VM-en scraper node-exporter og kube-state-metrics gjennom to NodePorts som er begrenset av en brannmur. Manglende eller utdaterte verdier er ukjente, ikke 0.

  6. Observasjons-VMobservere: Blackbox probeLeverandørens L7-inngang

    probe_success=1 betyr en 2xx fra stedet proben kjører fra. Det beviser verken alle brukeres tilgang eller den utrullede versjonen, og det oppgraderer aldri published til deployed.

Operatørinstallasjon · registrering

Klyngeinstallasjon, registrerings-bootstrap og input for mål, Secrets og oppsettet for fornyelse av legitimasjon er operatørinput, aldri en del av tenant-appens payload.

  1. Operatør-bootstrapkjøre · ta i bruk: generer platform · Secretrailshot-system

    Operatøren genererer platform-deklarasjonen med render-platform.py og leverer den private driftskonfigurasjonen og Secrets. Den eksterne MCP-en tas bare med når imaget leveres, og den personlige gatewayen (WireGuard) bare med --personal.

  2. Operatør-bootstrapkjøre · ta i bruk: registrerings-bootstrapAppProject · cluster Secretargocd

    Operatøren installerer en Role for registrerings-bootstrap og en tom Role for registreringer i argocd og forbereder input for målene. Registreringshjelperne produkt-API-et kjører (environment.py, applications.py), skriver deretter Secret-et railshot-<target> med en avgrenset legitimasjon (clusterResources false, tillatte namespaces angitt) og legger de validerte eksakte navnene til i Role-en for registreringer. Registrering per app binder et namespace app-<id> til et AppProject med samme navn.

  3. Operatør-bootstrapkjøre · ta i bruk: installer K3s · CiliumCilium · Helm · VXLANkube-system

    install-k3s.sh installerer en K3s-server med én node (flannel, network policy, traefik og servicelb slått av; kube-proxy beholdt), og Cilium installeres som en Helm-release (kubeProxyReplacement false, VXLAN, Hubble slått av).

  4. fornyelses-CronJob · hver 2. timeargocdkjøre · ta i bruk: TokenRequest · 6 hrailshot-argocd SA · utstedelse av token<app namespace>

    CronJob-en railshot-credentials ber hver annen time om et nytt token på seks timer for kundens SA. Role-en på kundesiden tillater bare token create for sin egen SA. Seks timer er TTL for ett token, ikke når operatørens tilgang opphører.

Alle forbindelser med samme tykkelse. Velg en flyt for å fremheve bare dens vei, med nummererte steg.

  • Heltrukket · retningen forespørsler, bundler, images og deklarasjoner flyter
  • Stiplet · kjøreforespørsler, ta i bruk, installer, legitimasjon
  • Lang strek-prikk · lesing av status, logger, prober, metrikker; atskilt fra dommen
  • Kraftig svart linje · den valgte flyten; tallene angir rekkefølgen
  • Boks · et namespace, navnet i overskriften (ikke en node)
  • Indre chip · en komponent i det namespacet
  • Stiplet boks · utenfor klyngene
  • railshot-system · produkt
  • argocd · utrullingsmyndighet
  • railshot-build · rettigheter til vertens Docker
  • GitHub · kundeklynge

Plasseringsbeslutningen fra 2. oktober i docs/architecture (to rollenoder) og diagrammet i den offentlige README-filen er historikk; dette kartet følger deklarasjonene og koden ved 645e28a. Pilene viser årsak og retning, ikke bevis for at alle provider-stier er aktive nå.

Namespaces og noder
Et namespace er et navneområde: verken maskinvare eller i seg selv en sikkerhetsgrense. Rollene platform og build er planleggingsplassering via nodeSelector og taint; dette kartet fastsetter ikke antallet noder i driftsklyngen. Nodeplasseringen til Argo CD er også en separat kontroll.
Build-nodens rettigheter
Runner-Jobs kjører med hostNetwork, vertens Docker-socket, NET_ADMIN og root. Et namespace, en taint eller RBAC fjerner ikke rettighetene til vertens Docker, så dette er verken isolasjon på VM-administratornivå eller en sandkasse for vilkårlig kode.
Kundens namespace
Hvert registrerte mål bruker et namespace og et AppProject som ikke er standard (for eksempel tenant-demo eller app-<id> per app). Bare én tjenestes Deployment (automount av ServiceAccount-token slått av), NodePort-Service og NetworkPolicy samt en valgfri PVC eller migration-Job opprettes; Secrets refereres bare ved navn (pull-Secret-et og en godkjent DATABASE_URL) og opprettes aldri.
AWS-inngang
Route 53 Alias → delt ALB HTTPS 443 → kundenodens private adresse og NodePort. Mange apper gjenbruker én node, hver med sitt eget namespace, sin Application og sin NodePort.
GCP-inngang
Global EXTERNAL_MANAGED HTTPS LB → zonal GCE_VM_IP_PORT NEG → den private NodePorten til den eksisterende VM-en. Sertifikater kommer fra Certificate Manager med DNS-autorisasjon. Modulen eier verken VM-en eller VPC-en, og én VM forblir et enkelt feilpunkt.
OpenStack-inngang
Amphora TLS-lytter 443 med L7-policyer for Host og sti → HTTP NodePort. Standardadressen er en privat VIP; Octavia, K3s, databasen og DNS ligger utenfor modulen. Offentlig tilgjengelighet og Amphora-beredskap på stedet krever separat aksept, og ingen bruk på stedet er ennå verifisert med denne modulen.
På tvers av leverandører
De tre inngangene er separate implementeringer, uten automatisk failover eller replikering mellom leverandører. Kundeappklyngen er et eksempel på et registrert mål, ikke en påstand om at den samme utrullingen kjører på alle skyer samtidig.
Operatørvalg
Den personlige gatewayen (WireGuard) inngår i plattformen bare når operatøren slår på --personal; den er ikke en påkrevd sti for kundeskyer. I den støttede direct-modusen kan observasjons-VM-en dele driftens kontroll-VM.