Topik ini membahas GitOps sebagai model deployment yang menjadikan repository git sebagai sumber kebenaran keadaan kluster dan menyerahkan penerapan perubahan kepada controller di dalam kluster. Lingkupnya mencakup prinsip sumber kebenaran, perbandingan model push dan pull, loop reconciliation pada Argo CD, serta simulasi deteksi drift sederhana yang dapat dijalankan ulang. Setelah topik ini dibaca, mekanisme penjagaan kesesuaian antara git dan kluster beserta alat utamanya sudah dapat dirancang.
Prinsip git sebagai sumber kebenaran#
Prinsip dasar GitOps adalah menyimpan seluruh keadaan kluster yang diinginkan di dalam git, berupa manifest, chart, dan values. Setiap perubahan keadaan berlangsung sebagai commit, sehingga riwayat git menjadi riwayat keadaan kluster. Perubahan masuk melalui pull request yang dapat ditinjau, dan keadaan kluster pada waktu tertentu selalu dapat dilacak kembali ke commit yang menyatakannya.
Prinsip kedua adalah perulangan yang berjalan terus. Sebuah controller di dalam kluster membaca keadaan yang dinyatakan git, membandingkannya dengan keadaan aktual, kemudian menggerakkan kluster menuju keadaan yang dinyatakan. Pola ini disebut loop reconciliation, yakni perulangan membandingkan dan memperbaiki yang mengikuti pola controller pada Kubernetes, tetapi diterapkan pada keseluruhan keadaan yang dikelola. Karena perbandingan berjalan terus, perubahan manual seperti kubectl edit tidak lagi menjadi cara sah untuk mengubah keadaan, melainkan menjadi selisih yang segera terdeteksi.
Komunitas OpenGitOps merangkum prinsip-prinsip tersebut menjadi empat butir, yaitu deklaratif, disimpan dalam git yang terversi dan imutabel, ditarik oleh agen secara otomatis, serta dijaga kesesuaiannya terus-menerus. Keempatnya menjadi batas uji apakah sebuah alur layak disebut GitOps atau hanya otomatisasi penerapan biasa.
Model push dan model pull#
Pada model push, pipeline CI/CD memegang peran penerapan. Pipeline membangun image, kemudian pada tahap akhirnya menjalankan kubectl atau helm dari luar kluster menuju API server. Kredensial kluster harus tersimpan pada sistem CI agar tahap tersebut dapat berjalan, sehingga setiap sistem CI yang menampungnya menjadi pemegang akses langsung ke kluster. Pipeline berhenti setelah perintah penerapan selesai, sehingga keadaan kluster setelahnya tidak lagi dipantau oleh siapa pun.
Pada model pull, controller di dalam kluster yang menarik perubahan dari git. Sistem CI hanya bertugas menguji kode dan mengunggah image, kemudian memperbarui tag pada repo manifest, sedangkan penerapan ke API server dilakukan controller yang tinggal di dalam kluster. Kredensial kluster tidak perlu meninggalkan kluster, dan perbandingan keadaan berjalan terus sehingga selisih dapat dikoreksi. Tabel berikut merangkum perbedaan keduanya.
| Aspek | Push (CI/CD tradisional) | Pull (GitOps) |
|---|---|---|
| Inisiatif penerapan | dari pipeline di luar kluster | dari controller di dalam kluster |
| Tempat kredensial kluster | tersimpan pada sistem CI | tetap berada di dalam kluster |
| Perubahan manual di kluster | tidak terdeteksi | terdeteksi sebagai drift dan dikoreksi |
| Pemantauan kesesuaian | berhenti setelah pipeline selesai | berjalan terus sebagai loop reconciliation |
Model pull tidak menghapus pipeline, melainkan memindahkan batas tanggung jawabnya. Pipeline tetap menguji kode dan menyiapkan image, sedangkan keputusan atas keadaan kluster berpindah ke repo manifest yang dibaca controller.
Loop reconciliation pada Argo CD#
Argo CD menjalankan loop reconciliation tersebut dari dalam kluster. Unit konfigurasinya adalah objek Application, yaitu Custom Resource Definition yang menyatakan sumber dan tujuan. Bagian sumber menyebut repository git, path, dan revisi, sedangkan bagian tujuan menyebut endpoint API kluster dan namespace. Controller merender manifest dari repo, membandingkannya dengan objek yang benar-benar berjalan, kemudian melaporkan statusnya sebagai Synced atau OutOfSync.
Berkas berikut mendeklarasikan Application untuk aplikasi catatan pada lingkungan staging. Bidang syncPolicy automated mengaktifkan sinkronisasi otomatis, dengan prune yang menghapus objek yang tidak lagi ada di git dan selfHeal yang memulihkan bidang yang diubah langsung di kluster.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: catatan-staging
namespace: argocd
spec:
project: default
source:
repoURL: https://git.example.com/tim/catatan-manifest.git
targetRevision: main
path: staging
destination:
server: https://kubernetes.default.svc
namespace: catatan-staging
syncPolicy:
automated:
prune: true
selfHeal: trueStatus OutOfSync muncul ketika keadaan aktual menyimpang dari keadaan yang dinyatakan. Perintah CLI Argo CD menampilkan status tersebut beserta kesehatannya, seperti pada contoh berikut.
# tidak-dijalankan
# menampilkan status sinkronisasi dan kesehatan aplikasi Argo CD
argocd app get catatan-stagingName: catatan-staging
Project: default
Server: https://kubernetes.default.svc
Namespace: catatan-staging
Repo: https://git.example.com/tim/catatan-manifest.git
Path: staging
Sync Status: Synced
Health Status: HealthyDiagram berikut merangkum alur model pull, mulai dari commit pada repo sampai loop pembandingan yang berjalan terus.
Pada diagram di atas, tidak ada komponen di luar kluster yang memegang kredensial penerapan. Perubahan hanya masuk sebagai commit, dan controller yang menyatukan keadaan kluster dengan repo, sehingga git berperan sebagai satu-satunya sumber perubahan.
Simulasi deteksi drift#
Mekanisme pembandingan Argo CD dapat ditiru dengan skrip kecil. Skrip berikut membaca application.yaml dari bundle, menampilkan pemetaan repo, path, dan tujuan kluster, kemudian membandingkan dua dictionary yang meniru keadaan git dan keadaan kluster. Selisih pada kunci mana pun dilaporkan sebagai drift, dan status akhir mengikuti temuan tersebut.
# Membaca Application Argo CD dari bundle, menampilkan pemetaan
# repo -> path -> tujuan kluster, lalu mendeteksi drift sederhana antara
# keadaan yang dinyatakan git dan keadaan yang terpantau di kluster.
import yaml
with open("application.yaml", encoding="utf-8") as berkas:
app = yaml.safe_load(berkas)
sumber = app["spec"]["source"]
tujuan = app["spec"]["destination"]
print(f"Aplikasi : {app['metadata']['name']}")
print(f"Repo git : {sumber['repoURL']}")
print(f"Path : {sumber['path']} (revisi {sumber['targetRevision']})")
print(f"Tujuan kluster : {tujuan['namespace']} pada {tujuan['server']}")
# keadaan yang diinginkan (git) dan keadaan yang terpantau di kluster
keadaan_git = {"replika_api": 3, "replika_web": 2, "versi_api": "1.4.0"}
keadaan_kluster = {"replika_api": 2, "replika_web": 2, "versi_api": "1.4.0"}
print()
print("Pembandingan keadaan git dan kluster:")
drift = False
for kunci in sorted(keadaan_git):
nilai_git = keadaan_git[kunci]
nilai_kluster = keadaan_kluster.get(kunci)
if nilai_git == nilai_kluster:
print(f" {kunci:13} sama ({nilai_git})")
else:
drift = True
print(f" {kunci:13} drift: git={nilai_git}, kluster={nilai_kluster}")
if drift:
print("Status: OutOfSync, controller akan menyinkronkan kembali")
else:
print("Status: Synced")Aplikasi : catatan-staging
Repo git : https://git.example.com/tim/catatan-manifest.git
Path : staging (revisi main)
Tujuan kluster : catatan-staging pada https://kubernetes.default.svc
Pembandingan keadaan git dan kluster:
replika_api drift: git=3, kluster=2
replika_web sama (2)
versi_api sama (1.4.0)
Status: OutOfSync, controller akan menyinkronkan kembaliPada keluaran di atas, replika_api berbeda antara kedua sisi. Git menyatakan tiga sedangkan kluster memuat dua, sehingga statusnya OutOfSync. Dengan selfHeal yang aktif, controller tidak berhenti pada pelaporan, melainkan mengembalikan jumlah replika sesuai git. Perilaku ini menegaskan perbedaan mendasar dengan model push. Perubahan manual di kluster diperlakukan sebagai selisih yang harus pulih, bukan sebagai perbaikan yang diakui. Pembandingan pada controller asli mencakup seluruh bidang objek, sehingga perubahan image, konfigurasi, maupun jumlah replika ikut terdeteksi, sedangkan simulasi di sini menyederhanakannya menjadi tiga kunci.
Ringkasan#
- GitOps menyimpan keadaan kluster yang diinginkan pada git sebagai sumber kebenaran, dan setiap perubahan berlangsung sebagai commit yang dapat ditinjau.
- Model push menerapkan perubahan dari luar kluster melalui pipeline CI/CD, sedangkan model pull menyerahkan penerapan kepada controller di dalam kluster.
- Objek Application pada Argo CD menyatakan source dan destination, kemudian controller menjalankan loop reconciliation yang membandingkan keadaan git dengan keadaan aktual.
- Perubahan manual pada kluster terdeteksi sebagai drift dan dikoreksi kembali sesuai git, sehingga git menjadi satu-satunya sumber perubahan.
Referensi#
- Argo CD Documentation — Argo Project — Dokumentasi resmi Argo CD, termasuk konsep Application, sinkronisasi, dan kebijakan syncPolicy.
- Flux Documentation — Flux project — Dokumentasi resmi Flux beserta model GitOps toolkit-nya.
- OpenGitOps — OpenGitOps — Definisi dan empat prinsip GitOps yang disepakati komunitas.