Masdika Loading..
Masdika.ID

DevOps Engineer

Cloud Engineer

System Administrator

  • Home
  • Portfolio
  • Services
  • Resume
  • Skills
  • Blog
  • Contact
Masdika.ID

DevOps Engineer

Cloud Engineer

System Administrator

Download CV

Recent Posts

  • Dari Laptop Bekas Jadi Server Pribadi: Cara Membangun Home Server Murah Menggunakan ISP MyRepublic dengan Public IP
  • Pembuatan Subnet dan Alokasi IP Address pada Amazon Web Service VPC
  • Instalasi dan Konfigurasi AWS CLI pada EC2 (Lab Guide)
  • Membangun Arsitektur Web + Database Highly Available di AWS (RDS Multi-AZ)
  • Cara Reset Password OpenBSD di Proxmox via VNC

Recent Comments

  1. Alif on Jangan Gunakan latest Tag pada Docker Images! Ini Alasannya
  2. Sahrull on Panduan Lengkap Anti-DDoS: Installasi Iptables, Hardening, dan Cloudflare Proxy
  3. VSTRA on Cara Cerdas Menguasai Kubernetes (K8s): Panduan Lengkap Orkestrasi Kontainer untuk Developer Modern
  4. Rikiy on Cara Mudah Deploy Website Node.js Menggunakan Docker
  5. Masdika.BIZ.ID on Disaster Recovery Cluster (DRC) WordPress dengan MariaDB Galera dan Load Balancer Caddy

Categories

  • Tutorial

Masdika.ID

  • About
  • Terms & Conditions
  • Privacy Policy
BLOG POST

Deploy Go REST API di Kubernetes (K3s) dengan PostgreSQL, SSL Cloudflare, dan Autoscaling

September 13, 2025 Tutorial by Masdika.ID
Deploy Go REST API di Kubernetes (K3s) dengan PostgreSQL, SSL Cloudflare, dan Autoscaling

Artikel ini akan membahas langkah end-to-end untuk membangun aplikasi Go REST API, membuat image Docker, lalu melakukan deployment di Kubernetes (K3s) lengkap dengan PostgreSQL sebagai database, SSL menggunakan Cloudflare DNS Challenge, hingga autoscaling dengan Horizontal Pod Autoscaler (HPA). Semua akan dijelaskan detail agar mudah dipahami. πŸ”₯

1️⃣ Persiapan Struktur Project

Sebelum memulai, silakan unduh script terlebih dahulu melalui repository berikut:
https://github.com/masdikaaa/go-rest-api-template

Struktur direktori project Go API kita adalah sebagai berikut:

.
β”œβ”€β”€ Caddyfile
β”œβ”€β”€ cmd
β”‚   └── main.go
β”œβ”€β”€ config
β”‚   └── postgres.go
β”œβ”€β”€ db
β”‚   └── init.sql
β”œβ”€β”€ deployment
β”‚   └── Dockerfile
β”œβ”€β”€ docker-compose.yaml
β”œβ”€β”€ go.mod
β”œβ”€β”€ go.sum
β”œβ”€β”€ internal
β”‚   β”œβ”€β”€ middleware
β”‚   β”‚   └── jwt.go
β”‚   β”œβ”€β”€ news
β”‚   β”‚   β”œβ”€β”€ dependency_injection
β”‚   β”‚   β”‚   └── news_di.go
β”‚   β”‚   β”œβ”€β”€ dto
β”‚   β”‚   β”œβ”€β”€ handler
β”‚   β”‚   β”œβ”€β”€ model
β”‚   β”‚   β”œβ”€β”€ repository
β”‚   β”‚   └── service
β”‚   └── user
β”‚       β”œβ”€β”€ dependency_injection
β”‚       β”œβ”€β”€ dto
β”‚       β”œβ”€β”€ handler
β”‚       β”œβ”€β”€ model
β”‚       β”œβ”€β”€ repository
β”‚       └── service
β”œβ”€β”€ kubernetes
β”‚   └── final.yaml
└── pkg
    β”œβ”€β”€ form-validation
    β”œβ”€β”€ id-generate
    └── response

πŸ“Œ File penting:

  • deployment/Dockerfile β†’ Docker build aplikasi Go.
  • db/init.sql β†’ Script untuk inisialisasi database PostgreSQL.
  • kubernetes/final.yaml β†’ Manifests Kubernetes lengkap.

2️⃣ Build dan Push Docker Image

Sebelum masuk ke Kubernetes, kita perlu membuat Docker image:

docker build -t masdika/go-api:latest -f deployment/Dockerfile .
docker push masdika/go-api:latest

Image masdika/go-api:latest sekarang sudah siap dipakai di Kubernetes. 🐳

3️⃣ File Kubernetes Lengkap (final.yaml)

Berikut file final.yaml yang berisi semua resource Kubernetes: namespace, PostgreSQL dengan PVC, Go API Deployment, Service, Ingress (SSL), hingga HPA.

# =============================
# Namespace
# =============================
apiVersion: v1
kind: Namespace
metadata:
  name: go-api
---
# =============================
# PersistentVolumeClaim (PVC) untuk Postgres
# =============================
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-pvc
  namespace: go-api
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: local-path   # biar jalan di K3s
---
# =============================
# Deployment PostgreSQL
# =============================
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
  namespace: go-api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:17
          env:
            - name: POSTGRES_DB
              value: go_rest_api
            - name: POSTGRES_USER
              value: masdika
            - name: POSTGRES_PASSWORD
              value: supersecretpassword
          ports:
            - containerPort: 5432
          resources:   # batasi resource
            requests:
              cpu: "200m"
              memory: "256Mi"
            limits:
              cpu: "1"
              memory: "1Gi"
          volumeMounts:
            - name: postgres-storage
              mountPath: /var/lib/postgresql/data
            - name: init-sql
              mountPath: /docker-entrypoint-initdb.d
      volumes:
        - name: postgres-storage
          persistentVolumeClaim:
            claimName: postgres-pvc
        - name: init-sql
          hostPath:
            path: /root/go-rest-api-template/db   # auto-import init.sql
---
# =============================
# Service PostgreSQL
# =============================
apiVersion: v1
kind: Service
metadata:
  name: postgres
  namespace: go-api
spec:
  ports:
    - port: 5432
      targetPort: 5432
  selector:
    app: postgres
---
# =============================
# Deployment Go API
# =============================
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-api
  namespace: go-api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: go-api
  template:
    metadata:
      labels:
        app: go-api
    spec:
      initContainers:
        - name: wait-for-postgres
          image: busybox
          command: ['sh', '-c', 'until nc -z postgres 5432; do echo waiting for postgres; sleep 2; done;']
      containers:
        - name: go-api
          image: masdika/go-api:latest
          env:
            - name: POSTGRES_HOST
              value: "postgres"
            - name: POSTGRES_PORT
              value: "5432"
            - name: POSTGRES_USER
              value: "masdika"
            - name: POSTGRES_PASSWORD
              value: "supersecretpassword"
            - name: POSTGRES_DB
              value: "go_rest_api"
            - name: JWT_SECRET_KEY
              value: "verylongrandomjwtsecretkey"
            - name: CORS_ALLOW_ORIGINS
              value: "*"
          ports:
            - containerPort: 8080
          resources:   # penting buat autoscaling
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
---
# =============================
# Service Go API
# =============================
apiVersion: v1
kind: Service
metadata:
  name: go-api
  namespace: go-api
spec:
  ports:
    - port: 8080
      targetPort: 8080
  selector:
    app: go-api
---
# =============================
# PodDisruptionBudget API
# =============================
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: go-api-pdb
  namespace: go-api
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: go-api
---
# =============================
# PodDisruptionBudget PostgreSQL
# =============================
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: postgres-pdb
  namespace: go-api
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: postgres
---
# =============================
# ClusterIssuer untuk SSL
# =============================
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-cloudflare
spec:
  acme:
    email: me@masdika.biz.id
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-cloudflare-key
    solvers:
      - dns01:
          cloudflare:
            apiTokenSecretRef:
              name: cloudflare-api-token-secret
              key: api-token
---
# =============================
# Secret Cloudflare API Token
# =============================
apiVersion: v1
kind: Secret
metadata:
  name: cloudflare-api-token-secret
  namespace: cert-manager
type: Opaque
stringData:
  api-token: "ZJIgWpl5UddGLyoUfs2mxNJZbgxCeo4iAItbmKfL"
---
# =============================
# Ingress untuk Go API
# =============================
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: go-api-ingress
  namespace: go-api
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-cloudflare
spec:
  ingressClassName: traefik
  rules:
    - host: api.syslab.my.id
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: go-api
                port:
                  number: 8080
  tls:
    - hosts:
        - api.syslab.my.id
      secretName: go-api-tls
---
# =============================
# HPA untuk Go API
# =============================
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: go-api-hpa
  namespace: go-api
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: go-api
  minReplicas: 1
  maxReplicas: 5
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70

4️⃣ Deploy ke K3s

Jalankan perintah berikut untuk apply seluruh konfigurasi:

kubectl apply -f kubernetes/final.yaml

Cek pod apakah sudah jalan:

kubectl get pods -n go-api

Cek service:

kubectl get svc -n go-api

5️⃣ Verifikasi SSL

Gunakan kubectl describe certificate untuk memastikan SSL berhasil dibuat oleh cert-manager:

kubectl describe certificate go-api-tls -n go-api

Kalau sukses, coba akses API:

curl -k https://api.syslab.my.id/api/v1/users

6️⃣ Autoscaling

Kita sudah menambahkan HPA (HorizontalPodAutoscaler) pada Go API. Untuk melihat scaling berjalan:

kubectl get hpa -n go-api -w

Lalu lakukan load testing supaya CPU usage naik. Jika target CPU > 70%, maka pod akan otomatis bertambah. 🎯

πŸŽ‰ Kesimpulan

Dalam artikel ini kita sudah membahas:

  • Build Go REST API dengan Docker
  • Push image ke Docker Hub
  • Deploy PostgreSQL + Go API ke Kubernetes (K3s)
  • Tambah SSL dari Let’s Encrypt via Cloudflare DNS Challenge
  • Terapkan PodDisruptionBudget untuk HA minimal
  • Aktifkan autoscaling dengan HPA

Dengan setup ini, aplikasi Go REST API kamu sekarang production-ready: scalable, secure (HTTPS), dan resilient. πŸš€

Share:
Tags: autoscalingdockergolanghpakubernetesssl
Related Posts
Troubleshooting K3s: Semua Pod Rusak Setelah Reboot Karena CNI Flannel

Pendahuluan Bayangkan sebuah cluster Kubernetes yang kemarin masih berjalan normal. Semua service aktif, storage Longhorn stabil, dan aplikasi berjalan tanpa…

Membangun Jenkins Production Stabil dengan Inbound Agent dan Traefik SSL

Panduan ini menjelaskan instalasi Jenkins production menggunakan Docker + Traefik (SSL otomatis via DNS Challenge Cloudflare), dengan fokus utama pada…

Post navigation

Prev
Next
Write a comment Cancel Reply


Β© 2025 www.masdika.id β€” Semua hak cipta dilindungi