RAILSHOT.
Tillbaka till salen

Railshot

AI deployment & operations platform

Driftsätt en lokalt byggd webbapp i förberedda moln- och on-premises-miljöer och driv den sedan.

En AI-plattform för driftsättning och drift som tar en lokalt byggd webbapp till förberedda moln- eller on-premises-miljöer och håller den igång.

28 september 2026 till 4 oktober 2026 · Avslutat

Teamprojekt · min del: planering och implementation av CI, CSP-kluster och Ansible-gränssnitt, drift, kodgranskning och integration i teamet

SoftBank Hackathon 2026 powered by KOREC & ProgateDeltagare i kvalomgången · uttagning till finalen tillkännages 26 oktober 2026 (per 7 oktober 2026)

  • WebbImplementerad · hackathon
  • MCP-serverImplementerad · fjärr · lokal

Drift- och kundappkluster är åtskilda, och den publika vägen hålls åtskild från driftsättningsstyrningen.

I drift-K3s placeras dashboard, produkt-API och build controller på noder med platform-roll och runner-Jobs på en nod med build-roll, medan Argo CD sköter driftsättningen. Kundappar körs i ett angivet namespace i ett separat K3s + Cilium-kluster med en nod för varje registrerat mål.

Klusterkarta · ritad utifrån deklarationer och kod vid offentlig commit 645e28a
Karta över Railshots drift- och kundklusterDrift-K3s-klustret och ett registrerat kundappkluster. I driftklustret placerar namespacet railshot-system dashboard, produkt-API, fjärr-MCP (bara när dess image tillhandahålls) och build controller på noder med platform-roll; runner-Jobs i namespacet railshot-build tar GitHub Actions-jobb på den taintade noden med build-roll. Ett GitHub-hostat release-jobb publicerar den testade bundlen till GHCR. Produkt-API:et committar arbetslasten till config-Git och synkar en Application i namespacet argocd, och Argo CD tillämpar en Deployment, en NodePort-Service och en NetworkPolicy på det namespace som registrerats i kundklustret. Appförfrågningar kommer in via leverantörens L7-ingång till nodens NodePort och Service och sedan appens Pod. Driftsättningsdomen vilar bara på Argo-status och kontrollen av den publika URL:en; Pod-diagnostik, loggar och mätvärden läses som separata signaler. Operatörens installations- och registreringsindata hålls åtskilda från tenant-appens payload.Railshot-användaredashboard · MCPOperatörsbootstrapinstallera · registrera · SecretGHCRdigest-imagesconfig-Git-repositoryworkload.json · revisionLeverantörens L7-ingångALB · GCP LB · AmphoraAppanvändarepublik HTTPSObservations-VMutanför kundens K3s · Composerailshot-systemdashboard · nginxfjärr-MCP · bara med en imagebuild controller · CronJobprodukt-API · cd.js → bridge.pyargocdArgo CD · ApplicationAppProject · cluster Secretförnyelse-CronJob · varannan timmerailshot-buildrunner Job · hostNetwork · Docker socketrailshot-deploy.ymlloop job · self-hosted runnerrelease job · GitHub-hosted<app namespace>Deployment · Pod · digest-imageNodePort Service · LocalNetworkPolicy · endast angivna CIDR:errailshot-argocd SA · tokenutfärdandekube-systemCilium · Helm · VXLANrailshot-observabilitynode-exporterkube-state-metricsDriftkluster · K3sAWS · rollnodernoder med platform-rollnodeSelectornod med build-rollNoSchedule taintGitHubActions · GHCRKundappkluster · exempelett per registrerat målEn K3s-nod · serverCilium · kube-proxy behållen1workflow_dispatch2fyll på runner-Job3ta emot jobb4testad bundle5 publicera via digest · release job · GitHub-hosted → GHCR51workload commit · push2revision3 Application sync · produkt-API · cd.js → bridge.py → Argo CD · Application34tillämpa på namespace5pull via digest1HTTPS 4432NodePort3 till Pod · NodePort Service · Local → Deployment · Pod · digest-image34 tillämpa policy · Cilium · Helm · VXLAN → NetworkPolicy · endast angivna CIDR:er45 dashboard · API · Railshot-användare → dashboard · nginx51 revision · health · images · produkt-API · cd.js → bridge.py → Argo CD · Application12publik HTTPS-kontroll3Pod-diagnostik · inte domen4logg-tail · 100 rader per Pod5scrape · NodePorts6Blackbox probe1generera platform · Secret2registreringsbootstrap3installera K3s · Cilium4TokenRequest · 6 h

Bygge → publicera image

Produkt-API:et begär en GitHub Actions-körning, och runnern på build-noden tar jobbet och kontrollerar det. Bara en bundle som klarade samma kontroller publiceras till GHCR av ett GitHub-hostat release-jobb.

  1. produkt-API · cd.js → bridge.pyrailshot-systemköra · tillämpa: workflow_dispatchloop job · self-hosted runnerrailshot-deploy.yml

    Produkt-API:et begär en GitHub Actions-körning med tenant, app, source commit och target. API:et anropar aldrig ett runner-Job direkt.

  2. build controller · CronJobrailshot-systemköra · tillämpa: fyll på runner-Jobrunner Job · hostNetwork · Docker socketrailshot-build

    Build controllerns CronJob (varje minut, på en platform-nod) skapar runner-Jobs i namespacet railshot-build. Dess Role tillåter bara get, list och create på Jobs samt get, update och patch på det enda Secret för runner-registrering; den kan inte skapa namespaces eller andra Secrets.

  3. runner Job · hostNetwork · Docker socketrailshot-buildköra · tillämpa: ta emot jobbloop job · self-hosted runnerrailshot-deploy.yml

    Runnern på noden med build-roll (exakt hostname, NoSchedule-toleration) tar loop-jobbet utifrån dess self-hosted-etiketter och kör det. Kundens källkod körs i de befintliga begränsade Docker-containrarna för bygge och kontroll.

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

    Loop-jobbet lämnar den bundle som klarade samma kontroller, och release-jobbet tar bara den bundlen.

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

    Ett GitHub-hostat release-jobb (ubuntu-24.04) publicerar den testade bundlens image till GHCR utan att bygga om den. Publicering av images sker aldrig inuti kundappklustret.

Config-Git → Argo → kundens namespace

Config-Git bär de önskade resurserna och GHCR image-byten. Argo CD tillämpar bara på det registrerade kund-namespacet.

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

    cd.js kör bridge.py, som bara committar och pushar workload.json när publiceringsloggen och det registrerade målet stämmer överens, och sedan läser tillbaka fjärr-revisionen. Git bär de önskade resurserna; GHCR bär image-byten.

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

    Application läser bara sitt begränsade config-repository, sin sökväg och sin revision.

  3. produkt-API · cd.js → bridge.pyrailshot-systemköra · tillämpa: Application syncArgo CD · Applicationargocd

    Den namngivna Application sätts med server-side apply, och en sync av en exakt revision begärs utan prune. Produkt-API:ets ServiceAccount railshot-product har både den registrerings-bootstrap som operatören installerat (create på Secrets, AppProjects och Applications i argocd; get, update och escalate på namngivna Roles) och get- och patch-rättigheter som läggs till med exakt namn för varje validerat mål. Kubernetes create kan inte begränsas efter namn, så produktens indatavalidering håller också namnen inom omfånget.

  4. Argo CD · Applicationargocdköra · tillämpa: tillämpa på namespace<app namespace>

    Argo CD tillämpar på det angivna namespacet i kundklustret med autentiseringsuppgiften från det registrerade cluster-Secret. AppProject tillåter bara namespace-avgränsade kinds och inga resurser på klusternivå.

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

    Den publicerade digest-imagen hämtas med ett pull-Secret som refereras med namn i samma namespace. Secret-värden hamnar aldrig i artefakten eller config-Git.

Publik förfrågningsväg

Appförfrågningar går leverantörens L7-ingång → nodens NodePort → Service → appens Pod. Ciliums tillämpning av policy är en separat kontroll, inte ett steg som bär förfrågan. Vägen in till driftdashboarden är en separat väg.

  1. Appanvändaredata: HTTPS 443Leverantörens L7-ingång

    Appanvändare når leverantörens L7-ingång via det registrerade hostnamnet. Varje leverantör implementerar sin egen ingång.

  2. Leverantörens L7-ingångdata: NodePortNodePort Service · Local<app namespace>

    Ingången vidarebefordrar till nodens privata adress och NodePort. NodePort är den som tilldelades vid registreringen av målet.

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

    Service skickar förfrågan till appens Pod (Deployment) på samma nod. Med externalTrafficPolicy Local når källadressen oförändrad fram till NetworkPolicyns kontroll av registrerade CIDR:er.

  4. Cilium · Helm · VXLANkube-systemköra · tillämpa: tillämpa policyNetworkPolicy · endast angivna CIDR:er<app namespace>

    Cilium tillämpar NetworkPolicy: ingress bara från de registrerade CIDR:erna till appens port; ingen egress som standard, utom en godkänd databasadress. Molnbrandväggar och värdregler spelar fortfarande roll.

  5. Railshot-användaredata: dashboard · APIdashboard · nginxrailshot-system

    Användare kommer via driftingången till nginx-dashboarden, och nginx står framför produkt-API:et. Dashboardens Service är en NodePort bara när en godkänd nodport anges; API:et förblir ClusterIP.

Verifiera · observera

Driftsättningsdomen vilar bara på Argo-status och kontrollen av den publika URL:en. Pod-diagnostik, aktuella loggar och driftmätvärden är separata signaler som aldrig ändrar den.

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

    Deployed kräver Applicationens sync-revision, Synced och Healthy, operation Succeeded och att image-referenserna i Argo Applicationens status är lika med den granskade Deploymentens digest-images. Det är ingen direkt grind på Poddens imageID, och en grön Argo-status ensam fastställer inte överensstämmelsen.

  2. produkt-API · cd.js → bridge.pyrailshot-systemobservera: publik HTTPS-kontrollLeverantörens L7-ingång

    Den registrerade publika URL:en kontrolleras utan omdirigeringar. Succeeded registreras bara med både Argo-domen och denna kontroll.

  3. produkt-API · cd.js → bridge.pyrailshot-systemobservera: Pod-diagnostik · inte domenDeployment · Pod · digest-image<app namespace>

    Efter Argo-domen och den publika kontrollen läses Deployment, ReplicaSets och Pods separat med den registrerade autentiseringsuppgiften, och imageID och beredskap läggs till som diagnos: ready, progressing eller unavailable. En misslyckad eller avvikande diagnos ändrar aldrig domen deployed eller succeeded.

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

    Bara för den för närvarande driftsatta operationen, med den betrodda configen och den registrerade autentiseringsuppgiften. För varje aktuell Pod (högst tre) måste den körande image-digesten vara lika med den förväntade digesten; därefter läses upp till 100 maskerade rader per Pod inom en bytegräns. Ett äldre försök svarar superseded; utan konfiguration not_configured. Det är inte loggaggregering.

  5. Observations-VMobservera: scrape · NodePortsrailshot-observability

    Prometheus på observations-VM:en scrapar node-exporter och kube-state-metrics via två NodePorts som begränsas av en brandvägg. Saknade eller inaktuella värden är okända, inte noll.

  6. Observations-VMobservera: Blackbox probeLeverantörens L7-ingång

    probe_success=1 betyder en 2xx från den plats där proben körs. Det bevisar varken alla användares åtkomst eller den driftsatta versionen, och det uppgraderar aldrig published till deployed.

Operatörsinstallation · registrering

Klusterinstallation, registreringsbootstrap och indata för mål, Secrets och uppsättningen för förnyelse av autentiseringsuppgifter är operatörsindata, aldrig en del av tenant-appens payload.

  1. Operatörsbootstrapköra · tillämpa: generera platform · Secretrailshot-system

    Operatören genererar platform-deklarationen med render-platform.py och tillhandahåller den privata driftkonfigurationen och Secrets. Fjärr-MCP:n ingår bara när dess image tillhandahålls, och den personliga gatewayen (WireGuard) bara med --personal.

  2. Operatörsbootstrapköra · tillämpa: registreringsbootstrapAppProject · cluster Secretargocd

    Operatören installerar en Role för registreringsbootstrap och en tom Role för registreringar i argocd och förbereder indata för målen. Registreringshjälparna som produkt-API:et kör (environment.py, applications.py) skriver sedan Secret railshot-<target> med en avgränsad autentiseringsuppgift (clusterResources false, tillåtna namespaces angivna) och lägger till de validerade exakta namnen i registreringarnas Role. Registrering per app binder ett namespace app-<id> till ett AppProject med samma namn.

  3. Operatörsbootstrapköra · tillämpa: installera K3s · CiliumCilium · Helm · VXLANkube-system

    install-k3s.sh installerar en K3s-server med en nod (flannel, network policy, traefik och servicelb avstängda; kube-proxy behållen), och Cilium installeras som en Helm-release (kubeProxyReplacement false, VXLAN, Hubble avstängd).

  4. förnyelse-CronJob · varannan timmeargocdköra · tillämpa: TokenRequest · 6 hrailshot-argocd SA · tokenutfärdande<app namespace>

    CronJob railshot-credentials begär varannan timme en ny token på sex timmar för kundens SA. Role på kundsidan tillåter bara token create för dess egen SA. Sex timmar är en tokens TTL, inte när operatörens åtkomst upphör.

Alla kopplingar med samma tjocklek. Välj ett flöde för att bara markera dess väg, med numrerade steg.

  • Heldragen · riktningen som förfrågningar, bundles, images och deklarationer flödar i
  • Streckad · körbegäran, tillämpa, installera, autentiseringsuppgifter
  • Lång streck-punkt · läsning av status, loggar, prober, mätvärden; skilt från domen
  • Kraftig svart linje · det valda flödet; siffrorna anger ordningen
  • Ruta · ett namespace, namnet i rubriken (inte en nod)
  • Inre chip · en komponent i det namespacet
  • Streckad ruta · utanför klustren
  • railshot-system · produkt
  • argocd · driftsättningsbefogenhet
  • railshot-build · behörighet till värdens Docker
  • GitHub · kundkluster

Placeringsbeslutet från 2 oktober i docs/architecture (två rollnoder) och diagrammet i den offentliga README-filen är historik; denna karta följer deklarationerna och koden vid 645e28a. Pilarna visar orsak och riktning, inte bevis för att alla provider-vägar är aktiva nu.

Namespaces och noder
Ett namespace är ett namnområde: varken hårdvara eller i sig en säkerhetsgräns. Rollerna platform och build är schemaläggningsplacering via nodeSelector och taint; denna karta fastställer inte antalet noder i driftklustret. Argo CD:s nodplacering är också en separat kontroll.
Build-nodens behörighet
Runner-Jobs körs med hostNetwork, värdens Docker-socket, NET_ADMIN och root. Ett namespace, en taint eller RBAC tar inte bort behörigheten till värdens Docker, så detta är varken isolering på VM-administratörsnivå eller en sandlåda för godtycklig kod.
Kundens namespace
Varje registrerat mål använder ett namespace och ett AppProject som inte är standard (till exempel tenant-demo eller app-<id> per app). Bara en tjänsts Deployment (automount av ServiceAccount-token avstängd), NodePort-Service och NetworkPolicy samt en valfri PVC eller ett migration-Job skapas; Secrets refereras bara med namn (pull-Secret och en godkänd DATABASE_URL) och skapas aldrig.
AWS-ingång
Route 53 Alias → delad ALB HTTPS 443 → kundnodens privata adress och NodePort. Många appar återanvänder en nod, var och en med sitt eget namespace, sin Application och sin NodePort.
GCP-ingång
Global EXTERNAL_MANAGED HTTPS LB → zonal GCE_VM_IP_PORT NEG → den befintliga VM:ens privata NodePort. Certifikat kommer från Certificate Manager med DNS-auktorisering. Modulen äger varken VM:en eller VPC:n, och en VM förblir en enskild felpunkt.
OpenStack-ingång
Amphora TLS-lyssnare 443 med L7-policyer för Host och sökväg → HTTP NodePort. Standardadressen är en privat VIP; Octavia, K3s, databasen och DNS ligger utanför modulen. Publik nåbarhet och Amphora-beredskap på plats kräver separat acceptans, och ingen tillämpning på plats har ännu verifierats med denna modul.
Mellan leverantörer
De tre ingångarna är separata implementationer, utan automatisk failover eller replikering mellan leverantörer. Kundappklustret är ett exempel på ett registrerat mål, inget påstående om att samma driftsättning körs i alla moln samtidigt.
Operatörsval
Den personliga gatewayen (WireGuard) ingår i plattformen bara när operatören aktiverar --personal; den är ingen obligatorisk väg för kundmoln. I det stödda direct-läget kan observations-VM:en dela driftens kontroll-VM.