Merangkai seluruh arsitektur dalam satu deployment utuh: PostgreSQL di atas RBD, upload media Laravel di CephFS RWX, dan opsi object S3 RGW — satu CephCluster tiga protokol. Termasuk manifest lengkap, migrasi & seeding, serta validasi akhir.

Tiga protokol sudah siap: RBD (episode 7), CephFS (episode 8), RGW/S3 (episode 9). Episode 10 merangkainya menjadi satu aplikasi utuh: Laravel lengkap dengan database persisten, media shared, dan opsi object storage.
Mengapa penting? Ini pembuktian tesis series: satu plataforma storage bisa menopang seluruh aplikasi. Kalian akan melihat manifest yang menggabungkan semuanya, migrasi berjalan, dan setiap lapisan bekerja tanpa saling mengganggu.
apiVersion: v1
kind: ConfigMap
metadata:
name: laravel-config
data:
DB_CONNECTION: pgsql
DB_HOST: postgres
DB_PORT: "5432"
DB_DATABASE: laravel
FILESYSTEM_DISK: local
APP_ENV: productionapiVersion: v1
kind: Secret
metadata:
name: laravel-secrets
type: Opaque
stringData:
DB_USERNAME: laravel
DB_PASSWORD: SecretPanjang123
APP_KEY: base64:xxxxapiVersion: apps/v1
kind: Deployment
metadata:
name: laravel
spec:
replicas: 3
selector:
matchLabels:
app: laravel
template:
metadata:
labels:
app: laravel
spec:
initContainers:
- name: seed-media
image: registry.example.com/laravel-app:latest
command: ["sh", "-c", "cp -r /app/storage-templates/. /var/www/html/storage/app/ || true"]
volumeMounts:
- name: media
mountPath: /var/www/html/storage/app
containers:
- name: app
image: registry.example.com/laravel-app:latest
volumeMounts:
- name: media
mountPath: /var/www/html/storage/app
- name: public-media
mountPath: /var/www/html/public/storage
envFrom:
- configMapRef:
name: laravel-config
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: laravel-secrets
key: DB_USERNAME
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: laravel-secrets
key: DB_PASSWORD
volumes:
- name: media
persistentVolumeClaim:
claimName: laravel-media
- name: public-media
persistentVolumeClaim:
claimName: laravel-mediaFinalnya sama dengan episode 7 — volumeClaimTemplates memakai SC rook-ceph-block.
apiVersion: v1
kind: Service
metadata:
name: laravel
spec:
selector:
app: laravel
ports:
- port: 80
targetPort: 9000apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: laravel
spec:
rules:
- host: app.internal.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: laravel
port:
number: 80apiVersion: batch/v1
kind: Job
metadata:
name: migrate
spec:
template:
spec:
restartPolicy: OnFailure
initContainers:
- name: wait-db
image: busybox:1.36
command: ["sh", "-c", "until nc -z postgres 5432; do sleep 2; done"]
containers:
- name: migrate
image: registry.example.com/laravel-app:latest
command: ["php", "artisan", "migrate", "--force"]
envFrom:
- configMapRef:
name: laravel-configPada init container (lihat deployment di atas), kita menyalin template file ke storage/app di CephFS — file langsung nampak di semua replica.
kubectl port-forward svc/laravel 8080:80.kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- ceph osd df
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- \
find /var/lib/ceph -name '*.jpg' 2>/dev/null | headceph osd df menunjukkan persebaran & utilisasi per OSD.
Warning
Urutan deploy penting: database → migrate → aplikasi. Jika migrate gagal, jangan lanjut ke Deployment. Gunakan log & status Job untuk memastikan setiap lapisan sehat sebelum berikutnya.
Inti yang harus dibawa pulang:
ceph -s HEALTH_OK.Di episode 11 selanjutnya kita akan membahas network Ceph: public & cluster network — memisahkan trafik client dan trafik internal OSD, memilih network provider pada Rook, menyusun network policy, dan mengamankan akses dashboard & RGW. Sampai jumpa di episode 11!