Deploy aplikasi ke Kubernetes tanpa membuka API server ke publik. Kalian akan menghubungkan cluster lewat GitLab Agent, menjalankan kubectl dan helm upgrade langsung dari pipeline, dan menerapkan pola GitOps dengan ArgoCD serta Flux.

Di episode 15 sebelumnya kita mendeploy aplikasi ke server Linux lewat SSH dan Ansible. Sekarang kita naik satu level: Kubernetes. Bedanya fundamental — kita tidak lagi bicara satu host dengan satu process manager, melainkan sebuah cluster yang bisa memindahkan pod antar node, melakukan rolling update, dan menjaga aplikasi tetap hidup. Namun cluster ini juga punya permukaan serangan yang jauh lebih besar: API server Kubernetes adalah pintu yang jika dibuka ke internet, bisa disasar bot scanning dalam hitungan menit.
Karena itulah metode "lama" — mengekspos API server ke IP publik dan menaruh kubeconfig di runner — tidak lagi dianjurkan. Episode ini membahas GitLab Agent for Kubernetes (KAS): jembatan aman antara GitLab dan cluster kalian, cara deploy manifest dan Helm chart lewat pipeline, serta bagaimana ArgoCD dan Flux melengkapi alur GitOps.
Bayangkan rumah kalian: API server Kubernetes adalah pintu depannya. Setiap orang yang bisa menyentuh pintu itu bisa mencoba membuka kunci atau mengetuk berkali-kali (brute force). Menjaga pintu tetap tertutup adalah prinsip dasar: kontrol plane dan worker node sebaiknya berada di jaringan privat, dan kredensial kubeconfig tidak pernah menginap di dalam runner yang dipakai banyak project.
GitLab Agent menyelesaikan ini dengan pola outbound connection. Agent berjalan sebagai pod di dalam cluster dan membuat koneksi keluar ke server GitLab — bukan sebaliknya. Firewall tetap menutup port API server dari internet, namun pipeline GitLab tetap bisa mengirim perintah kubectl ke cluster. Analoginya dengan call center: alih-alih tim kalian harus datang ke gedung perusahaan, justru petugas perusahaan yang siap dihubungi lewat saluran yang selalu terbuka.
| Aspek | kubeconfig + API Server Public | GitLab Agent (KAS) |
|---|---|---|
| Arah koneksi | Inbound dari runner ke cluster | Outbound dari cluster ke GitLab |
| Port API server | Dibuka ke internet | Tertutup dari internet |
| Kredensial | Kubeconfig disimpan di runner | Token agent di Kubernetes Secret |
| Audit trail | Minim | Terlihat di halaman agent GitLab |
Langkah pertama adalah mendaftarkan agent di GitLab. Buka Operate → Kubernetes clusters, pilih Connect a cluster, dan pilih project yang akan memakai agent. GitLab membuatkan token agent. Konfigurasi agent disimpan di dalam repository sebagai file YAML:
ci_access:
projects:
- id: my-group/my-appBlok ci_access menentukan project mana yang berhak memakai agent ini lewat CI. Tanpa blok ini, project tidak bisa memanggil kubectl dari pipeline — inilah yang menjaga agent hanya dipakai oleh tim yang berwenang.
Selanjutnya pasang agent di cluster menggunakan Helm chart resmi:
helm repo add gitlab https://charts.gitlab.io
helm repo update
helm upgrade --install my-agent gitlab/gitlab-agent \
--namespace gitlab-agent \
--create-namespace \
--set config.kasAddress=wss://kas.gitlab.com \
--set config.token=<isi-dengan-token-agent>Nilai config.kasAddress adalah address server KAS GitLab — untuk GitLab.com adalah wss://kas.gitlab.com, sedangkan untuk instalasi self-hosted sesuaikan dengan domain KAS kalian. Begitu pod agent muncul di namespace gitlab-agent, status agent di halaman Operate berubah menjadi Connected.
Warning
Token agent adalah kredensial istimewa. Jangan commit token ke repository, jangan taruh di log, dan jangan tulis langsung di perintah install — gunakan Kubernetes Secret lalu rujuk lewat config.secretName. Jika token bocor, revoke di halaman agent dan ulangi install.
Dengan agent terhubung, pipeline GitLab otomatis menerima variabel KUBE_CONTEXT dan KUBE_NAMESPACE — asalkan job dijalankan di project yang punya akses ci_access. Ini kunci ajaib yang membuat kubectl bekerja tanpa menyimpan kubeconfig di mana pun:
deploy_manifest:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl apply -f k8s/deployment.yaml
- kubectl rollout status deployment/my-app --timeout=120s
environment:
name: production
url: https://myapp.example.comPerhatikan bahwa tidak ada kubectl config set-cluster atau upload file kubeconfig — semuanya diatur lewat context bawaan agent. Perintah kubectl rollout status membuat job menunggu sampai Deployment benar-benar stabil, jadi jika image baru gagal mulai (CrashLoopBackOff), job akan gagal dan pipeline berhenti sebelum dinyatakan sukses.
Untuk aplikasi dengan banyak komponen (service, ingress, configmap, secret), Helm adalah pilihan yang jauh lebih rapi. Kita bisa memakai agent yang sama untuk menjalankan helm upgrade --install:
deploy_helm:
stage: deploy
image: alpine/helm:latest
variables:
KUBE_CONTEXT: my-group/my-app:prod-agent
KUBE_NAMESPACE: production
script:
- helm dependency update ./chart
- helm upgrade --install my-app ./chart
--namespace production
--set image.tag=$CI_COMMIT_SHA
environment:
name: production
url: https://myapp.example.comFormat variabel KUBE_CONTEXT adalah path/project-utama:<nama-agent> — pada contoh ini project my-group/my-app memakai agent prod-agent. Nama release my-app, chart di folder ./chart, dan tag image diambil dari $CI_COMMIT_SHA sehingga setiap commit menghasilkan versi unik. Karena --install disertakan, perintah yang sama berfungsi untuk deploy pertama maupun upgrade berikutnya.
Tip
Gunakan satu agent per environment penting (misalnya agent terpisah untuk staging dan production). Dengan begitu batas ci_access tiap agent bisa dibedakan, dan kesalahan di staging tidak pernah memberi akses ke production.
Selain deploy langsung dari pipeline (push-based), ada pola GitOps: repository Git menjadi satu-satunya sumber kebenaran (single source of truth) untuk state cluster. Operator di dalam cluster yang menarik perubahan dari Git, bukan pipeline yang mendorong ke cluster.
ArgoCD dan Flux CD adalah dua implementasi paling populer. Keduanya bisa mengambil source langsung dari repository GitLab:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://gitlab.com/my-group/my-app.git
targetRevision: main
path: helm-chart
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: trueArgoCD akan membandingkan state di cluster dengan state di repository GitLab. Perubahan apa pun yang di-merge ke main akan ditarik dan disinkronkan ke cluster — menjadikan GitLab tuan rumah kode aplikasi sekaligus "remote config" bagi cluster.
Flux CD menggunakan custom resource serupa bernama GitRepository dan Kustomization, dengan prinsip yang sama. Di sinilah pola push-based (helm upgrade dari pipeline) dan pull-based (operator GitOps) bisa digabung: pipeline tetap membangun image dan menandai versi, sementara operator GitOps yang memutuskan kapan menerapkan versi tersebut — kontrol penuh di tangan operator, bukan bot.
Episode ini menghubungkan GitLab dengan Kubernetes dengan cara yang aman:
ci_access di .gitlab/agents/my-agent/config.yaml membatasi siapa yang boleh memakai agent.KUBE_CONTEXT dan KUBE_NAMESPACE membuat kubectl dan helm bekerja tanpa kubeconfig di runner.Sekarang kalian bisa mendeploy ke Kubernetes. Namun deploy saja tidak cukup — release besar tetap berisiko. Di episode 17 selanjutnya kita membahas progressive delivery: canary dan blue-green deployment, plus rollback otomatis ketika metrik memperingatkan kegagalan. Sampai jumpa!