Topik ini mengumpulkan konsep yang dibahas sepanjang jalur menjadi rencana satu proyek utuh, yaitu aplikasi catatan dengan tiga service bernama api, web, dan database. Lingkupnya mencakup struktur direktori manifest, tabel dependensi antara service, urutan deployment yang aman, serta konfigurasi per lingkungan staging dan produksi. Konfigurasinya memisahkan base dan overlay, sehingga kedua lingkungan berbagi manifest asli yang sama.
Struktur direktori manifest#
Proyek multi-service membutuhkan banyak manifest, dan jumlahnya tumbuh seiring penambahan lingkungan. Penataan yang teruji adalah memisahkan manifest asli ke dalam base, lalu menampung perbedaan tiap lingkungan pada overlay, sebagaimana pola Kustomize. Dengan pemisahan itu, perubahan yang berlaku umum ditulis satu kali pada base, sedangkan perbedaan jumlah replika dan tag image ditulis pada overlay masing-masing lingkungan.
catatan-manifest/
├── base/
│ ├── database/
│ │ ├── statefulset.yaml
│ │ ├── service-headless.yaml
│ │ └── kustomization.yaml
│ ├── api/
│ │ ├── deployment.yaml
│ │ ├── service.yaml
│ │ └── kustomization.yaml
│ └── web/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── kustomization.yaml
└── overlays/
├── staging/
│ ├── kustomization.yaml
│ └── patch-replika.yaml
└── produksi/
├── kustomization.yaml
└── patch-replika.yamlSetiap service memiliki direktori sendiri di dalam base karena setiap service memiliki siklus rilis yang berbeda. Overlay hanya menyimpan kustomization.yaml beserta patch-nya, sehingga ukurannya kecil dan mudah ditinjau. Repositori manifest ini dipisahkan dari repositori kode aplikasi, dan pemisahan itu memudahkan controller GitOps menarik keadaan yang dinyatakan tanpa perlu menarik kode aplikasinya.
Struktur ini juga menetapkan siapa yang boleh mengubah apa. Base hanya berubah ketika rancangan service berubah, sedangkan overlay berubah ketika kebutuhan lingkungan berubah, misalnya penyesuaian jumlah replika saat lonjakan pengguna. Kedua jenis perubahan tersebut berbeda frekuensinya, dan pemisahan direktorinya membuat peninjau langsung mengetahui lingkup perubahan yang masuk.
Tabel dependensi antara service#
Dependensi antara service menentukan urutan deployment sekaligus desain probe. Service database menyimpan catatan dan berada paling bawah, service api mengakses database dan menyediakan endpoint HTTP, sedangkan service web menyajikan antarmuka dan memanggil api. Rangkaian ini dituliskan sebagai tabel agar keputusan urutannya dapat diperiksa ulang kapan pun.
| Service | Jenis workload | Bergantung pada | Alasan |
|---|---|---|---|
| database | StatefulSet | tidak ada | menyimpan catatan pada penyimpanan yang bertahan |
| api | Deployment | database | membaca dan menulis catatan melalui database |
| web | Deployment | api | mengambil data melalui endpoint HTTP api |
Dependensi tersebut juga dinyatakan sebagai berkas JSON yang dapat dibaca program, sehingga urutan deployment dapat dihitung ulang secara otomatis setiap kali struktur proyek berubah. Berkasnya berupa daftar service beserta jenis workload dan daftar dependensinya.
{
"aplikasi": "catatan",
"service": [
{"nama": "database", "jenis": "StatefulSet", "bergantung_pada": []},
{"nama": "api", "jenis": "Deployment", "bergantung_pada": ["database"]},
{"nama": "web", "jenis": "Deployment", "bergantung_pada": ["api"]}
]
}Jenis workload ikut dicatat karena memengaruhi penjadwalan. StatefulSet untuk database memberi nama Pod dan penyimpanan yang bertahan meskipun Pod diganti, sedangkan Deployment untuk api dan web memungkinkan Pod diganti sewaktu-waktu tanpa menyimpan keadaan di dalamnya.
Urutan deployment yang aman#
Urutan deployment yang aman mengikuti arah dependensi, yaitu lapisan data lebih dahulu, kemudian api, lalu web. Database harus siap sebelum api berjalan karena readiness probe api memeriksa koneksi ke database, dan api harus siap sebelum web berjalan karena halaman web memanggil endpoint api saat pertama diakses. Urutan ini dihitung dari berkas dependensi menggunakan pengurutan topologis, yakni pengelompokan menjadi lapisan berdasarkan dependensi yang sudah terpenuhi.
Skrip berikut membaca dependensi.json dari bundle, mengelompokkan service menjadi lapisan, dan mencetak urutan deployment yang aman. Pengurutan di dalam lapisan dibuat alfabetis agar keluarannya deterministik, dan skrip berhenti dengan error apabila ditemukan ketergantungan melingkar yang tidak dapat diselesaikan.
# Menghitung urutan deployment yang aman dari berkas dependensi.json.
# Service dikelompokkan menjadi lapisan: satu service hanya masuk lapisan
# ketika seluruh dependensinya sudah terdeploy pada lapisan sebelumnya.
# Urutan di dalam lapisan diurutkan alfabetis agar hasilnya deterministik.
import json
with open("dependensi.json", encoding="utf-8") as berkas:
data = json.load(berkas)
jenis = {s["nama"]: s["jenis"] for s in data["service"]}
dependensi = {s["nama"]: s["bergantung_pada"] for s in data["service"]}
print(f"Proyek: {data['aplikasi']}")
print(f"Service terdaftar: {', '.join(sorted(dependensi))}")
print()
terdeploy = set()
tersisa = dict(dependensi)
lapisan = []
while tersisa:
siap = sorted(n for n, d in tersisa.items() if set(d) <= terdeploy)
if not siap:
print(f"Terhenti pada lapisan {len(lapisan) + 1}: ketergantungan melingkar di {sorted(tersisa)}")
raise SystemExit(1)
lapisan.append(siap)
for nama in siap:
terdeploy.add(nama)
del tersisa[nama]
for nomor, kelompok in enumerate(lapisan, 1):
daftar = ", ".join(f"{n} ({jenis[n]})" for n in kelompok)
print(f"Lapisan {nomor}: {daftar}")
print()
urutan = [n for kelompok in lapisan for n in kelompok]
print("Urutan deployment yang aman: " + " -> ".join(urutan))Proyek: catatan
Service terdaftar: api, database, web
Lapisan 1: database (StatefulSet)
Lapisan 2: api (Deployment)
Lapisan 3: web (Deployment)
Urutan deployment yang aman: database -> api -> webPada keluaran di atas, database membentuk lapisan pertama karena tidak bergantung pada siapa pun, kemudian api dan web menyusul, masing-masing menempati satu lapisan. Apabila nanti ditambahkan service baru yang bergantung pada api dan web, service tersebut otomatis jatuh pada lapisan berikutnya tanpa mengubah skrip. Ketergantungan melingkar, misalnya api bergantung pada web dan web bergantung pada api sekaligus, menghentikan perhitungan dan menjadi sinyal bahwa rancangan dependensinya perlu ditinjau ulang.
Penerapan overlay dilakukan dengan satu perintah kubectl apply -k. Perintah tersebut menyusun objek menurut jenisnya, sedangkan kesiapan antara service dijaga oleh readiness probe yang memeriksa koneksi ke dependensinya. Contoh penerapan overlay staging beserta keluarannya adalah sebagai berikut.
# tidak-dijalankan
# menerapkan seluruh manifest hasil build overlay staging ke kluster
kubectl apply -k overlays/stagingstatefulset.apps/database created
service/database-headless created
deployment.apps/api created
service/api created
deployment.apps/web created
service/web createdKonfigurasi per lingkungan#
Manifest yang sama melayani staging dan produksi, dan perbedaan keduanya sebaiknya sesempit mungkin. Perbedaan yang lazim mencakup jumlah replika, level log, dan nama domain, sedangkan nilai yang sensitif seperti kredensial database tidak pernah masuk ke git. Tabel berikut merangkum contoh pembagian tersebut.
| Aspek | staging | produksi |
|---|---|---|
| Replika api | 1 | 3 |
| Replika web | 1 | 2 |
| Level log | debug | info |
| Domain | staging.catatan.example | catatan.example |
| Kredensial database | Secret pada namespace staging | Secret pada namespace produksi |
Perbedaan pada tabel dituliskan sebagai patch pada overlay, sehingga setiap perubahan dapat ditinjau sebelum masuk ke salah satu lingkungan. Setiap lingkungan mendapatkan namespace sendiri beserta Secret-nya, karena namespace adalah lingkup terkecil tempat Secret dapat dirujuk. ConfigMap menyimpan nilai yang tidak sensitif seperti level log, dan pemisahan ini menjadikan image yang sama berjalan pada kedua lingkungan tanpa dibangun ulang.
Ringkasan#
- Proyek multi-service ditata dengan base per service dan overlay per lingkungan, sehingga staging dan produksi berbagi manifest asli yang sama.
- Tabel dependensi dan berkas dependensi.json menyatakan arah kebergantungan antara service, yang menentukan urutan deployment sekaligus desain probe.
- Pengurutan topologis yang deterministik mengelompokkan deployment menjadi lapisan database, api, web, dan menghentikan perhitungan bila ketergantungan melingkar ditemukan.
- Konfigurasi per lingkungan berupa patch kecil pada overlay, sedangkan data sensitif dikelola sebagai Secret per namespace dan tidak masuk ke git.
Referensi#
- Managing Workloads — Kubernetes Documentation — Panduan resmi mengelola beban kerja Kubernetes, termasuk Deployment dan pola pembaruannya.
- kubectl Cheat Sheet — Kubernetes Documentation — Ringkasan perintah kubectl yang digunakan secara rutin saat mengerjakan proyek.