RAILSHOT.
Kembali ke ruang pamer

Railshot

AI deployment & operations platform

Men-deploy aplikasi web yang dibangun secara lokal ke lingkungan cloud dan on-premise yang telah disiapkan, lalu menjalankannya.

Platform AI untuk deployment dan operasi yang membawa aplikasi web yang dibangun secara lokal ke lingkungan cloud atau on-premise yang telah disiapkan dan terus menjalankannya.

2026.09.28 — 2026.10.04 · Selesai

Proyek tim · bagian saya: perencanaan dan implementasi CI, klaster CSP dan antarmuka Ansible, operasi, tinjauan kode dan integrasi tim

SoftBank Hackathon 2026 powered by KOREC & ProgatePeserta babak penyisihan · pengumuman seleksi final 2026.10.26 (per 2026.10.07)

  • WebDiimplementasikan · hackathon
  • Server MCPDiimplementasikan · jarak jauh · lokal

Klaster operasi dan klaster aplikasi pelanggan terpisah, dan jalur publik dipisahkan dari kendali deployment.

Di K3s operasi, dasbor, API produk, dan build controller ditempatkan di node berperan platform dan runner Job di node berperan build, sementara Argo CD menangani deployment. Aplikasi pelanggan berjalan di namespace yang ditentukan pada klaster K3s + Cilium satu node yang terpisah untuk setiap target terdaftar.

Peta klaster · digambar dari deklarasi dan kode pada commit publik 645e28a
Peta klaster operasi dan pelanggan RailshotKlaster K3s operasi dan sebuah klaster aplikasi pelanggan terdaftar. Di klaster operasi, namespace railshot-system menempatkan dasbor, API produk, MCP jarak jauh (hanya bila image-nya disediakan), dan build controller di node berperan platform; runner Job di namespace railshot-build mengambil job GitHub Actions di node berperan build yang diberi taint. Job rilis yang di-hosting GitHub memublikasikan bundle teruji ke GHCR. API produk meng-commit workload ke config Git dan melakukan sync Application di namespace argocd, lalu Argo CD menerapkan Deployment, NodePort Service, dan NetworkPolicy ke namespace terdaftar di klaster pelanggan. Permintaan aplikasi masuk lewat entri L7 penyedia ke NodePort dan Service node, lalu ke Pod aplikasi. Putusan deployment hanya bertumpu pada status Argo dan pemeriksaan URL publik; diagnostik Pod, log, dan metrik dibaca sebagai sinyal terpisah. Input instalasi dan pendaftaran operator dipisahkan dari payload aplikasi tenant.Pengguna Railshotdasbor · MCPBootstrap operatorinstal · daftar · SecretGHCRimage per digestRepositori config Gitworkload.json · revisionEntri L7 penyediaALB · GCP LB · AmphoraPengguna aplikasiHTTPS publikVM pengamatdi luar K3s pelanggan · Composerailshot-systemdashboard · nginxMCP jarak jauh · hanya dengan imagebuild controller · CronJobAPI produk · cd.js → bridge.pyargocdArgo CD · ApplicationAppProject · cluster SecretCronJob pembaruan · setiap 2 hrailshot-buildrunner Job · hostNetwork · Docker socketrailshot-deploy.ymlloop job · self-hosted runnerrelease job · GitHub-hosted<app namespace>Deployment · Pod · image per digestNodePort Service · LocalNetworkPolicy · CIDR terdaftarSA railshot-argocd · tokenkube-systemCilium · Helm · VXLANrailshot-observabilitynode-exporterkube-state-metricsKlaster operasi · K3sAWS · node per perannode berperan platformnodeSelectornode berperan buildNoSchedule taintGitHubActions · GHCRKlaster aplikasi pelanggan · contohsatu per target terdaftarSatu node K3s · serverCilium · kube-proxy dipertahankan1workflow_dispatch2isi ulang runner Job3ambil job4bundle teruji5 publikasi per digest · release job · GitHub-hosted → GHCR51workload commit · push2revision3 Application sync · API produk · cd.js → bridge.py → Argo CD · Application34terapkan ke namespace5tarik per digest1HTTPS 4432NodePort3 ke Pod · NodePort Service · Local → Deployment · Pod · image per digest34 tegakkan kebijakan · Cilium · Helm · VXLAN → NetworkPolicy · CIDR terdaftar45 dasbor · API · Pengguna Railshot → dashboard · nginx51 revisi · health · image · API produk · cd.js → bridge.py → Argo CD · Application12pemeriksaan HTTPS publik3diagnostik Pod · bukan putusan4tail log · 100 baris per Pod5scrape · NodePort6Blackbox probe1merender platform · Secret2bootstrap pendaftaran3instal K3s · Cilium4TokenRequest · 6 h

Build → publikasi image

API produk meminta eksekusi GitHub Actions, dan runner di node build mengambil serta memeriksa job tersebut. Hanya bundle yang lolos pemeriksaan yang sama yang dipublikasikan ke GHCR oleh job rilis yang di-hosting GitHub.

  1. API produk · cd.js → bridge.pyrailshot-systemeksekusi · terapkan: workflow_dispatchloop job · self-hosted runnerrailshot-deploy.yml

    API produk meminta eksekusi GitHub Actions dengan tenant, app, source commit, dan target. API tidak pernah memanggil runner Job secara langsung.

  2. build controller · CronJobrailshot-systemeksekusi · terapkan: isi ulang runner Jobrunner Job · hostNetwork · Docker socketrailshot-build

    CronJob build controller (setiap menit, di node platform) membuat runner Job di namespace railshot-build. Role-nya hanya mengizinkan get, list, dan create Job serta get, update, dan patch pada satu Secret pendaftaran runner; ia tidak dapat membuat namespace atau Secret lain.

  3. runner Job · hostNetwork · Docker socketrailshot-buildeksekusi · terapkan: ambil jobloop job · self-hosted runnerrailshot-deploy.yml

    Runner di node berperan build (hostname persis, toleration NoSchedule) mengambil job loop berdasarkan label self-hosted dan menjalankannya. Sumber pelanggan berjalan di kontainer build dan pemeriksaan Docker terbatas yang sudah ada.

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

    Job loop meninggalkan bundle yang lolos pemeriksaan yang sama, dan job rilis hanya mengambil bundle itu.

  5. release job · GitHub-hostedrailshot-deploy.ymldata: publikasi per digestGHCR

    Job rilis yang di-hosting GitHub (ubuntu-24.04) memublikasikan image dari bundle teruji ke GHCR tanpa build ulang. Publikasi image tidak pernah terjadi di dalam klaster aplikasi pelanggan.

Config Git → Argo → namespace pelanggan

Config Git membawa sumber daya yang diinginkan dan GHCR membawa byte image. Argo CD hanya menerapkan ke namespace pelanggan yang terdaftar.

  1. API produk · cd.js → bridge.pyrailshot-systemdata: workload commit · pushRepositori config Git

    cd.js menjalankan bridge.py, yang meng-commit dan push workload.json hanya bila catatan publikasi dan target terdaftar cocok, lalu membaca kembali revisi remote. Git membawa sumber daya yang diinginkan; GHCR membawa byte image.

  2. Repositori config Gitdata: revisionArgo CD · Applicationargocd

    Application hanya membaca repositori config, path, dan revisi terbatas miliknya.

  3. API produk · cd.js → bridge.pyrailshot-systemeksekusi · terapkan: Application syncArgo CD · Applicationargocd

    Application bernama disetel dengan server-side apply, dan sync untuk satu revisi yang persis diminta tanpa prune. ServiceAccount railshot-product milik API produk memegang izin bootstrap pendaftaran yang dipasang operator (create untuk Secret, AppProject, dan Application di argocd; get, update, dan escalate pada Role bernama) sekaligus izin get dan patch yang ditambahkan dengan nama persis untuk setiap target terverifikasi. create di Kubernetes tidak dapat dibatasi dengan nama, sehingga validasi input produk juga menjaga nama tetap dalam cakupan.

  4. Argo CD · Applicationargocdeksekusi · terapkan: terapkan ke namespace<app namespace>

    Argo CD menerapkan ke namespace yang ditentukan di klaster pelanggan dengan kredensial cluster Secret yang terdaftar. AppProject hanya mengizinkan kind bernamespace dan tidak mengizinkan sumber daya lingkup klaster.

  5. Deployment · Pod · image per digest<app namespace>data: tarik per digestGHCR

    Image digest yang dipublikasikan ditarik dengan pull Secret yang dirujuk lewat nama di namespace yang sama. Nilai Secret tidak pernah masuk ke artefak atau config Git.

Jalur permintaan publik

Permintaan aplikasi berjalan entri L7 penyedia → NodePort node → Service → Pod aplikasi. Penegakan kebijakan Cilium adalah kendali terpisah, bukan lompatan yang membawa permintaan. Jalan masuk ke dasbor operasi adalah jalur terpisah.

  1. Pengguna aplikasidata: HTTPS 443Entri L7 penyedia

    Pengguna aplikasi mencapai entri L7 penyedia lewat hostname terdaftar. Setiap penyedia mengimplementasikan entrinya sendiri.

  2. Entri L7 penyediadata: NodePortNodePort Service · Local<app namespace>

    Entri meneruskan ke alamat privat dan NodePort node. NodePort adalah yang dialokasikan saat pendaftaran target.

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

    Service mengirim permintaan ke Pod aplikasi (Deployment) di node yang sama. Dengan externalTrafficPolicy Local, alamat sumber mencapai pemeriksaan CIDR terdaftar NetworkPolicy tanpa berubah.

  4. Cilium · Helm · VXLANkube-systemeksekusi · terapkan: tegakkan kebijakanNetworkPolicy · CIDR terdaftar<app namespace>

    Cilium menegakkan NetworkPolicy: ingress hanya dari CIDR terdaftar ke port aplikasi; tanpa egress secara bawaan, kecuali alamat basis data yang disetujui. Firewall cloud dan aturan host tetap penting.

  5. Pengguna Railshotdata: dasbor · APIdashboard · nginxrailshot-system

    Pengguna datang lewat entri operasi ke dasbor nginx, dan nginx berada di depan API produk. Service dasbor menjadi NodePort hanya bila node port yang disetujui diberikan; API tetap ClusterIP.

Verifikasi · observasi

Putusan deployment hanya bertumpu pada status Argo dan pemeriksaan URL publik. Diagnostik Pod, log saat ini, dan metrik operasi adalah sinyal terpisah yang tidak pernah mengubahnya.

  1. API produk · cd.js → bridge.pyrailshot-systemamati: revisi · health · imageArgo CD · Applicationargocd

    Status deployed memerlukan revisi sync Application, Synced dan Healthy, operation Succeeded, dan referensi image yang tercatat di status Argo Application sama dengan image digest Deployment yang telah ditinjau. Ini bukan gerbang imageID Pod secara langsung, dan status hijau Argo saja tidak menetapkan kecocokan itu.

  2. API produk · cd.js → bridge.pyrailshot-systemamati: pemeriksaan HTTPS publikEntri L7 penyedia

    URL publik terdaftar diperiksa tanpa redirect. Succeeded hanya dicatat bila ada putusan Argo sekaligus pemeriksaan ini.

  3. API produk · cd.js → bridge.pyrailshot-systemamati: diagnostik Pod · bukan putusanDeployment · Pod · image per digest<app namespace>

    Setelah putusan Argo dan pemeriksaan publik, Deployment, ReplicaSet, dan Pod dibaca terpisah dengan kredensial terdaftar, dan imageID serta kesiapan ditambahkan sebagai diagnostik ready, progressing, atau unavailable. Diagnostik yang gagal atau berbeda tidak pernah mengubah putusan deployed atau succeeded.

  4. API produk · cd.js → bridge.pyrailshot-systemamati: tail log · 100 baris per PodDeployment · Pod · image per digest<app namespace>

    Hanya untuk operation yang sedang ter-deploy, dengan config tepercaya dan kredensial terdaftar. Untuk setiap Pod saat ini (paling banyak tiga), digest image yang berjalan harus sama dengan digest yang diharapkan; lalu hingga 100 baris tersamarkan per Pod dibaca dalam batas byte. Percobaan yang lebih lama menjawab superseded; tanpa konfigurasi, not_configured. Ini bukan agregasi log.

  5. VM pengamatamati: scrape · NodePortrailshot-observability

    Prometheus di VM pengamat melakukan scrape node-exporter dan kube-state-metrics melalui dua NodePort yang dibatasi firewall. Nilai yang hilang atau basi berarti tidak diketahui, bukan nol.

  6. VM pengamatamati: Blackbox probeEntri L7 penyedia

    probe_success=1 berarti 2xx di lokasi probe itu. Ini tidak membuktikan akses setiap pengguna maupun versi yang ter-deploy, dan tidak pernah menaikkan published menjadi deployed.

Instalasi · pendaftaran operator

Instalasi klaster, bootstrap pendaftaran dan input target, Secret, serta penyiapan pembaruan kredensial adalah input operator, tidak pernah bagian dari payload aplikasi tenant.

  1. Bootstrap operatoreksekusi · terapkan: merender platform · Secretrailshot-system

    Operator merender deklarasi platform dengan render-platform.py dan menyediakan config operasi dan Secret privat. MCP jarak jauh hanya disertakan bila image-nya disediakan, gateway pribadi (WireGuard) hanya dengan --personal.

  2. Bootstrap operatoreksekusi · terapkan: bootstrap pendaftaranAppProject · cluster Secretargocd

    Operator memasang Role bootstrap pendaftaran dan Role registrations kosong di argocd serta menyiapkan input target. Helper pendaftaran yang dijalankan API produk (environment.py, applications.py) kemudian menulis Secret railshot-<target> dengan kredensial bercakupan (clusterResources false, namespace yang diizinkan dicantumkan) dan menambahkan nama persis yang telah divalidasi ke Role registrations. Pendaftaran per aplikasi mengikat namespace app-<id> ke AppProject dengan nama yang sama.

  3. Bootstrap operatoreksekusi · terapkan: instal K3s · CiliumCilium · Helm · VXLANkube-system

    install-k3s.sh memasang server K3s satu node (flannel, network policy, traefik, dan servicelb nonaktif; kube-proxy dipertahankan), dan Cilium dipasang sebagai Helm release (kubeProxyReplacement false, VXLAN, Hubble nonaktif).

  4. CronJob pembaruan · setiap 2 hargocdeksekusi · terapkan: TokenRequest · 6 hSA railshot-argocd · token<app namespace>

    CronJob railshot-credentials meminta token enam jam baru untuk SA pelanggan setiap dua jam. Role di sisi pelanggan hanya mengizinkan create token untuk SA-nya sendiri. Enam jam adalah TTL satu token, bukan saat akses operator berakhir.

Setiap koneksi dengan bobot yang sama. Pilih alur untuk menyorot hanya jalurnya, dengan langkah bernomor.

  • Garis utuh · arah aliran permintaan, bundle, image, dan deklarasi
  • Garis putus · permintaan eksekusi, terapkan, instal, kredensial
  • Garis titik-strip panjang · membaca status, log, probe, metrik; terpisah dari putusan
  • Garis hitam tebal · alur yang dipilih; angka menunjukkan urutan
  • Kotak · namespace, namanya di bagian kepala (bukan node)
  • Chip dalam · komponen di namespace itu
  • Kotak putus-putus · di luar klaster
  • railshot-system · produk
  • argocd · otoritas deployment
  • railshot-build · otoritas Docker host
  • GitHub · klaster pelanggan

Keputusan penempatan October 2 di docs/architecture (dua node peran) dan diagram README publik adalah riwayat; peta ini mengikuti deklarasi dan kode pada 645e28a. Panah menunjukkan sebab dan arah, bukan bukti bahwa setiap jalur penyedia aktif sekarang.

Namespace dan node
Namespace adalah lingkup penamaan: bukan perangkat keras, dan dengan sendirinya bukan batas keamanan. Peran platform dan build adalah penempatan penjadwalan lewat nodeSelector dan taint; peta ini tidak menetapkan jumlah node klaster operasi. Penempatan node Argo CD juga merupakan pemeriksaan tersendiri.
Otoritas node build
Runner Job berjalan dengan hostNetwork, socket Docker host, NET_ADMIN, dan root. Namespace, taint, atau RBAC tidak menghapus otoritas Docker host, sehingga ini bukan isolasi administrator VM maupun sandbox untuk kode sembarang.
Namespace pelanggan
Setiap target terdaftar memakai namespace dan AppProject non-bawaan (misalnya tenant-demo, atau app-<id> per aplikasi). Hanya Deployment satu layanan (automount token ServiceAccount nonaktif), NodePort Service, dan NetworkPolicy, ditambah PVC atau migration Job opsional, yang dibuat; Secret hanya dirujuk lewat nama (pull Secret dan DATABASE_URL yang disetujui), tidak pernah dibuat.
Entri AWS
Route 53 Alias → ALB bersama HTTPS 443 → alamat privat dan NodePort node pelanggan. Banyak aplikasi memakai ulang satu node, masing-masing dengan namespace, Application, dan NodePort sendiri.
Entri GCP
Global EXTERNAL_MANAGED HTTPS LB → zonal GCE_VM_IP_PORT NEG → NodePort privat VM yang ada. Sertifikat berasal dari Certificate Manager dengan DNS authorization. Modul tidak memiliki VM maupun VPC, dan satu VM tetap menjadi titik kegagalan tunggal.
Entri OpenStack
Amphora TLS listener 443 dengan kebijakan L7 Host dan path → HTTP NodePort. Alamat bawaannya VIP privat; Octavia, K3s, basis data, dan DNS berada di luar modul. Keterjangkauan publik dan kesiapan Amphora di lokasi memerlukan penerimaan tersendiri, dan belum ada penerapan di lokasi yang diverifikasi dengan modul ini.
Antarpenyedia
Ketiga entri adalah implementasi terpisah, tanpa failover atau replikasi otomatis antarpenyedia. Klaster aplikasi pelanggan adalah contoh target terdaftar, bukan klaim bahwa deployment yang sama berjalan di setiap cloud sekaligus.
Opsi operator
Gateway pribadi (WireGuard) bergabung ke platform hanya bila operator mengaktifkan --personal; ini bukan jalur wajib untuk cloud pelanggan. Dalam mode direct yang didukung, VM pengamat dapat berbagi dengan VM kontrol operasi.