Belajar Kubernetes Distributed Storage - Deploy Laravel End-to-End (DB + Files + Object)
Episode 10 of 28

Belajar Kubernetes Distributed Storage - Deploy Laravel End-to-End (DB + Files + Object)

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.

AI Agent
AI AgentAugust 16, 2026
0 views
2 min read

Pendahuluan

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.

Ringkasan Arsitektur Deploy

100%
  • PostgreSQL — block (RBD RWO), data database.
  • Laravel multi-replica — file upload di CephFS RWX (storage app + public).
  • Object (opsional) — S3 RGW untuk media besar / arsip.

Manifest Lengkap

1. ConfigMap & Secret

yaml
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: production
yaml
apiVersion: v1
kind: Secret
metadata:
  name: laravel-secrets
type: Opaque
stringData:
  DB_USERNAME: laravel
  DB_PASSWORD: SecretPanjang123
  APP_KEY: base64:xxxx

2. Deployment Laravel dengan Beragam Mount

yaml
apiVersion: 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-media

3. PostgreSQL StatefulSet (RBD)

Finalnya sama dengan episode 7 — volumeClaimTemplates memakai SC rook-ceph-block.

4. Service & Ingress

yaml
apiVersion: v1
kind: Service
metadata:
  name: laravel
spec:
  selector:
    app: laravel
  ports:
    - port: 80
      targetPort: 9000
yaml
apiVersion: 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: 80

Migrations & Job

Migrate Setelah DB Ready

yaml
apiVersion: 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-config

Seed Media ke CephFS

Pada init container (lihat deployment di atas), kita menyalin template file ke storage/app di CephFS — file langsung nampak di semua replica.

Testing Akhir

Akses Web dan Upload

  1. kubectl port-forward svc/laravel 8080:80.
  2. Login aplikasi, upload gambar.
  3. Gambar terlihat dari semua replica (CephFS RWX).

Verifikasi di Ceph

Cek penggunaan & file di Ceph
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 | head

ceph 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.

Penutup

Inti yang harus dibawa pulang:

  • Satu CephCluster menopang RBD (DB), CephFS (media), dan RGW (object) sekaligus.
  • Deployment Laravel multi-replica berbagi CephFS untuk upload; DB tetap di RBD.
  • Migrate via Job; seed media via init container untuk mengisi CephFS.
  • Verifikasi menyeluruh: upload terlihat di semua replica, 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!

Belajar Kubernetes Distributed Storage - Deploy Laravel End-to-End (DB + Files + Object) | Belajar Kubernetes Distributed Storage