RAILSHOT.
Tilbage til salen

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.

28. september 2026 til 4. oktober 2026 · Afsluttet

Teamprojekt · min del: planlægning og implementering af CI, CSP-klynger og Ansible-grænseflade, drift, kodegennemgang og integration i teamet

SoftBank Hackathon 2026 powered by KOREC & ProgateDeltager i indledende runde · udvælgelse til finalen offentliggøres 26. oktober 2026 (pr. 7. oktober 2026)

  • WebImplementeret · hackathon
  • MCP-serverImplementeret · ekstern · lokal

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.

Klyngekort · tegnet ud fra deklarationer og kode ved offentlig commit 645e28a
Kort over Railshots drifts- og kundeklyngerDrifts-K3s-klyngen og en registreret kundeappklynge. I driftsklyngen placerer namespacet railshot-system dashboard, produkt-API, ekstern MCP (kun når dens image leveres) og build controller på noder med platform-rolle; runner-Jobs i namespacet railshot-build tager GitHub Actions-jobs på den taintede node med build-rolle. Et GitHub-hostet release-job publicerer den testede bundle til GHCR. Produkt-API'et committer workloaden til config-Git og synkroniserer en Application i namespacet argocd, og Argo CD anvender en Deployment, en NodePort-Service og en NetworkPolicy på det namespace, der er registreret i kundeklyngen. Appforespørgsler kommer ind gennem udbyderens L7-indgang til nodens NodePort og Service og derefter appens Pod. Udrulningsdommen hviler kun på Argo-status og kontrollen af den offentlige URL; Pod-diagnostik, logs og metrikker læses som separate signaler. Operatørens installations- og registreringsinput holdes adskilt fra tenant-appens payload.Railshot-brugerdashboard · MCPOperatør-bootstrapinstallér · registrér · SecretGHCRdigest-imagesconfig-Git-repositoryworkload.json · revisionUdbyderens L7-indgangALB · GCP LB · AmphoraAppbrugeroffentlig HTTPSObservations-VMuden for kundens K3s · Composerailshot-systemdashboard · nginxekstern MCP · kun 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 · kun angivne CIDR'errailshot-argocd SA · udstedelse af tokenkube-systemCilium · Helm · VXLANrailshot-observabilitynode-exporterkube-state-metricsDriftsklynge · K3sAWS · rollenodernoder med platform-rollenodeSelectornode med build-rolleNoSchedule taintGitHubActions · GHCRKundeappklynge · eksempelén pr. registreret målÉn K3s-node · serverCilium · kube-proxy bevaret1workflow_dispatch2genopfyld runner-Job3modtag job4testet bundle5 publicér via digest · release job · GitHub-hosted → GHCR51workload commit · push2revision3 Application sync · produkt-API · cd.js → bridge.py → Argo CD · Application34anvend på namespace5pull via digest1HTTPS 4432NodePort3 til Pod · NodePort Service · Local → Deployment · Pod · digest-image34 håndhæv policy · Cilium · Helm · VXLAN → NetworkPolicy · kun angivne CIDR'er45 dashboard · API · Railshot-bruger → dashboard · nginx51 revision · health · images · produkt-API · cd.js → bridge.py → Argo CD · Application12offentlig HTTPS-kontrol3Pod-diagnostik · ikke dommen4log-tail · 100 linjer pr. Pod5scrape · NodePorts6Blackbox probe1generér platform · Secret2registrerings-bootstrap3installér K3s · Cilium4TokenRequest · 6 h

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.

  1. produkt-API · cd.js → bridge.pyrailshot-systemkøre · anvende: workflow_dispatchloop job · self-hosted runnerrailshot-deploy.yml

    Produkt-API'et anmoder om en GitHub Actions-kørsel med tenant, app, source commit og target. API'et kalder aldrig et runner-Job direkte.

  2. build controller · CronJobrailshot-systemkøre · anvende: genopfyld runner-Jobrunner Job · hostNetwork · Docker socketrailshot-build

    Build 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.

  3. runner Job · hostNetwork · Docker socketrailshot-buildkøre · anvende: modtag jobloop job · self-hosted runnerrailshot-deploy.yml

    Runneren 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.

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

    Loop-jobbet efterlader den bundle, der bestod de samme kontroller, og release-jobbet tager kun den bundle.

  5. release job · GitHub-hostedrailshot-deploy.ymldata: publicér via digestGHCR

    Et 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.

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

    cd.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.

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

    Application læser kun sit begrænsede config-repository, sin sti og sin revision.

  3. produkt-API · cd.js → bridge.pyrailshot-systemkøre · anvende: Application syncArgo CD · Applicationargocd

    Den 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.

  4. Argo CD · Applicationargocdkø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.

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

    Det 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.

  1. Appbrugerdata: HTTPS 443Udbyderens L7-indgang

    Appbrugere når udbyderens L7-indgang via det registrerede hostname. Hver udbyder implementerer sin egen indgang.

  2. 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.

  3. 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.

  4. Cilium · Helm · VXLANkube-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.

  5. Railshot-brugerdata: dashboard · APIdashboard · nginxrailshot-system

    Brugere 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.

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

    Deployed 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.

  2. produkt-API · cd.js → bridge.pyrailshot-systemobservere: offentlig HTTPS-kontrolUdbyderens L7-indgang

    Den registrerede offentlige URL kontrolleres uden omdirigeringer. Succeeded registreres kun med både Argo-dommen og denne kontrol.

  3. produkt-API · cd.js → bridge.pyrailshot-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.

  4. produkt-API · cd.js → bridge.pyrailshot-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.

  5. 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.

  6. 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.

  1. 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.

  2. Operatør-bootstrapkøre · anvende: registrerings-bootstrapAppProject · cluster Secretargocd

    Operatø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.

  3. Operatør-bootstrapkøre · anvende: installér K3s · CiliumCilium · Helm · VXLANkube-system

    install-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).

  4. fornyelses-CronJob · hver 2. timeargocdkø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.