Zero-downtime deployment ของ Go app บน Kubernetes

Sharing is caring!

Deploy แอปพลิเคชัน Go สู่ Kubernetes โดยไม่ต้องหยุดระบบ (zero downtime) พร้อมเทคนิค rolling update, healthcheck, readiness probe และ lifecycle hook


Zero-downtime deployment คืออะไร?

คือการ deploy ระบบใหม่โดยที่ผู้ใช้งานไม่รู้สึกว่า service หยุดชั่วคราวหรือเกิด downtime เลย ในระดับ production เราต้องให้ระบบพร้อมใช้งานตลอดเวลา ซึ่ง Kubernetes มีฟีเจอร์มากมายที่ช่วยให้เราทำได้


องค์ประกอบสำคัญ

  • Rolling Update Strategy
  • Readiness & Liveness Probe
  • Graceful Shutdown (lifecycle hook)
  • Healthcheck endpoint
  • Resource limit ที่เหมาะสม

ตัวอย่าง Go App สำหรับ Deployment

package main

import (
  "fmt"
  "log"
  "net/http"
  "os"
  "os/signal"
  "syscall"
  "time"
)

func main() {
  mux := http.NewServeMux()
  mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusOK)
    fmt.Fprintln(w, "ok")
  })

  server := &http.Server{
    Addr:    ":8080",
    Handler: mux,
  }

  go func() {
    log.Println("Server started")
    if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
      log.Fatalf("Listen error: %v", err)
    }
  }()

  quit := make(chan os.Signal, 1)
  signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
  <-quit

  log.Println("Graceful shutdown...")
  ctx, cancel := time.WithTimeout(context.Background(), 5*time.Second)
  defer cancel()
  server.Shutdown(ctx)
}

Deploy บน Kubernetes

1. สร้าง Dockerfile

FROM golang:1.20 as builder
WORKDIR /app
COPY . .
RUN go build -o server .

FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/server .
EXPOSE 8080
CMD ["./server"]

2. เขียน Deployment YAML

apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-app
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: go-app
  template:
    metadata:
      labels:
        app: go-app
    spec:
      containers:
        - name: go-app
          image: myregistry/go-app:latest
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5
          lifecycle:
            preStop:
              exec:
                command: ["sleep", "5"]

Key สำคัญ:

  • readinessProbe บอก Kubernetes ว่า container นี้ “พร้อมให้รับ traffic” แล้วหรือยัง
  • lifecycle.preStop รอ 5 วิให้ service ปิดก่อนตัด connection
  • rollingUpdate ใช้แทน recreate เพื่อป้องกัน downtime

ตรวจสอบด้วย kubectl

kubectl get pods
kubectl describe pod go-app-xxxxx
kubectl rollout status deployment/go-app

การอัปเดต version ใหม่

kubectl set image deployment/go-app go-app=myregistry/go-app:v2

Rollback หากมีปัญหา

kubectl rollout undo deployment/go-app

Best Practices เพิ่มเติม

  • ไม่ใช้ latest tag จริงในการ deploy (ใช้ tag แบบ v1.0.1)
  • ใช้ CI/CD เช่น GitHub Actions, ArgoCD
  • Log แบบ structured และ monitor readiness probe

สรุป

การทำ zero-downtime deployment บน Kubernetes เป็นเรื่องที่สำคัญสำหรับระบบ production ที่มีผู้ใช้จำนวนมาก ด้วยการใช้ rolling update, readiness probe และ graceful shutdown อย่างเหมาะสม จะช่วยให้ผู้ใช้งานไม่รู้สึกถึงการ deploy เลย


คำค้น (SEO Keywords)

  • Zero downtime Kubernetes
  • Go graceful shutdown
  • Kubernetes readiness probe
  • Rolling update Go app
  • K8s deployment best practices
  • Go web server on Kubernetes
  • Production deployment K8s

Leave a Reply

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *