全部产品
Search
文档中心

:Gunakan preStop hook untuk menghentikan pod secara mulus selama pembaruan bergulir pod backend dari ALB Ingress

更新时间:Jul 02, 2025

Anda dapat menggunakan preStop hook untuk menghentikan pod backend yang terkait dengan Application Load Balancer (ALB) Ingress secara mulus. Hook ini memastikan bahwa pod hanya dimatikan setelah sepenuhnya dihapus, memungkinkan pergantian trafik yang lancar dan mencegah gangguan layanan selama pembaruan bergulir.

Prasyarat

Cara kerjanya

Siklus hidup Pod

Pod dapat berisi jenis kontainer berikut:

  • Kontainer init: Kontainer init berjalan sebelum kontainer utama untuk menyelesaikan operasi inisialisasi tertentu.

  • Kontainer utama: Kontainer utama menjalankan proses aplikasi.

Gambar berikut menunjukkan siklus hidup sebuah pod.

  1. Jalankan kontainer init: Kontainer init berjalan sebelum kontainer utama untuk menyelesaikan operasi inisialisasi tertentu.

  2. Jalankan kontainer utama:

    1. Kontainer utama memanggil fungsi hook postStart setelah kontainer dimulai.

    2. Sistem melakukan pemeriksaan liveness (liveness probe) dan pemeriksaan readiness (readiness probe) pada kontainer utama.

    3. Kontainer utama memanggil fungsi hook preStop sebelum kontainer dihentikan.

Prosedur penghentian pod dan prosedur pembaruan aturan routing trafik

Saat Anda menghapus pod, sistem menjalankan prosedur penghentian pod dan prosedur pembaruan aturan routing trafik secara bersamaan. Berikut adalah penjelasan prosedur-prosedur tersebut:

Prosedur penghentian pod

  1. kube-apiserver menerima permintaan penghapusan dan menandai pod sebagai Terminating.

  2. Jika hook preStop dikonfigurasikan untuk pod, sistem mengeksekusi hook preStop.

  3. Klaster mengirim sinyal SIGTERM ke kontainer.

  4. Sistem menunggu hingga kontainer dihentikan atau hingga proses shutdown yang halus dari pod habis waktu.

    Catatan

    Periode grace default (terminationGracePeriodSeconds) dari pod adalah 30 detik.

  5. Jika pod tidak dihentikan dalam periode grace, sistem mengirim sinyal SIGKILL ke kontainer.

  6. Pod dihapus.

Prosedur pembaruan aturan routing trafik

  1. kube-apiserver menerima permintaan penghapusan dan menandai pod sebagai Terminating.

  2. Kontroler endpoint menghapus alamat IP pod dari endpoint.

  3. Kontroler ALB Ingress menyelaraskan server backend dan menghapus titik akhir Layanan dari grup server backend. Dengan cara ini, trafik tidak lagi diarahkan ke pod yang dihapus.

Gunakan hook preStop untuk menghentikan pod secara mulus

Selama pembaruan bergulir, jika pod lama tidak dihentikan secara mulus, kode status berikut mungkin dikembalikan saat Anda mengirim permintaan ke layanan. Hal ini dapat mengganggu ketersediaan layanan.

Kode status

Penyebab

504

Pod lama sedang memproses permintaan non-idempoten ketika pod dihapus.

502

Pod lama dihapus setelah menerima sinyal SIGTERM dari sistem. Namun, penyelarasan belum selesai oleh kontroler ALB Ingress ketika pod lama dihapus. Akibatnya, pod masih ada di grup server backend ketika permintaan diproses.

Untuk mencegah masalah di atas, lakukan langkah-langkah berikut:

Tambahkan hook preStop ke Deployment untuk menentukan durasi tidur yang dimulai setelah kube-apiserver menerima permintaan penghapusan. Durasi tidur memastikan periode waktu yang cukup bagi kontroler ALB Ingress untuk menyelaraskan server backend dan menghapus pod lama dari grup server backend sebelum pod menerima sinyal SIGTERM. Dengan cara ini, pod dapat dihentikan secara mulus untuk mencegah gangguan layanan selama pembaruan bergulir dan restart.

Periode grace default (terminationGracePeriodSeconds) dari pod adalah 30 detik. Ini menunjukkan bahwa pod dapat terus berjalan selama 30 detik setelah menerima sinyal SIGTERM. Jika jumlah durasi shutdown program dan waktu yang diperlukan untuk menyelesaikan operasi yang didefinisikan oleh hook preStop melebihi 30 detik, shutdown yang halus dari pod akan habis waktu. Setelah periode grace berakhir, kubelet menunggu 2 detik dan mengirim sinyal SIGKILL ke pod untuk menghentikan pod secara paksa.

Catatan

Dalam kasus ini, kami sarankan Anda meningkatkan periode grace (terminationGracePeriodSeconds) untuk memastikan periode waktu yang cukup untuk menyelesaikan operasi di atas.

Langkah 1: Konfigurasikan hook preStop untuk pod

  1. Buat file bernama tea-service.yaml dan salin konten berikut ke file tersebut. File ini mencakup hook preStop yang ditambahkan untuk memastikan penghentian pod yang mulus.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: tea
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: tea
      template:
        metadata:
          labels:
            app: tea
        spec:
          containers:
          - name: tea
            image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginxdemos:latest
            ports:
            - containerPort: 80
            lifecycle:  # Tentukan fungsi hook preStop yang memerlukan kube-apiserver menunggu 10 detik sebelum mengirim sinyal SIGTERM ke pod.
              preStop:  # Konfigurasi hook preStop.
                exec:  # Jalankan operasi yang didefinisikan oleh hook preStop dengan menjalankan perintah.
                  command:  # Perintah untuk dijalankan.
                  - /bin/sh
                  - -c
                  - "sleep 10"  # Tidur selama 10 detik.
          terminationGracePeriodSeconds: 45  # Tentukan periode grace dari pod.
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: tea-svc
    spec:
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: tea
      type: NodePort
  2. Jalankan perintah berikut untuk menerapkan Deployment uji dan Layanan uji:

    kubectl apply -f tea-service.yaml
  3. Buat file bernama tea-ingress.yaml dan salin konten berikut ke file tersebut. File ini digunakan untuk membuat Ingress.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: tea-ingress
    spec:
      ingressClassName: alb
      rules:
       - host: demo.ingress.top
         http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: tea-svc
                port:
                  number: 80
  4. Jalankan perintah berikut untuk membuat Ingress:

    kubectl apply -f tea-ingress.yaml
  5. Jalankan perintah berikut untuk menanyakan parameter ADDRESS dari ALB Ingress:

    kubectl get ingress

    Output yang diharapkan:

    NAME                    CLASS   HOSTS                     ADDRESS                                              PORTS   AGE
    tea-ingress             alb     demo.ingress.top          alb-110zvs5nhsvfv*****.cn-chengdu.alb.aliyuncs.com   80      7m5s

Langkah 2: Uji apakah hook preStop berfungsi

  1. Jalankan skrip uji.

    1. Buat skrip bernama test.sh dan salin konten berikut ke skrip tersebut. Skrip ini digunakan untuk menguji ketersediaan layanan dengan mengirim permintaan ke layanan NGINX setiap detik dan mencatat kode status yang dikembalikan.

      #!/bin/bash
      HOST="demo.ingress.top"
      DNS="alb-110zvs5nhsvfv*****.cn-chengdu.alb.aliyuncs.com"   # Atur nilai ini menjadi nilai parameter ADDRESS dari ALB Ingress.
      printf "Response Code|| TIME \n" >> log.txt
      
      while true; do
        RESPONSE=$(curl -H Host:$HOST  -s -o /dev/null -w "%{http_code}" -m 1  http://$DNS/)
        TIMESTAMP=$(date +%Y-%m-%d_%H:%M:%S)
        echo "$TIMESTAMP - $RESPONSE" >> log.txt
        sleep 1
      done
    2. Jalankan perintah berikut untuk mengeksekusi skrip test.sh:

      bash test.sh
  2. Jalankan perintah berikut untuk memulai pembaruan bergulir untuk aplikasi dan menerapkan ulang aplikasi:

    kubectl rollout restart deploy tea 
  3. Verifikasi pembaruan.

    1. Jumlah pod replika sebelum pembaruan bergulir adalah tiga.

      image

    2. Selama penyebaran ulang, dua pod lama masih berjalan ketika pod baru belum siap untuk memproses permintaan.

      image

    3. Setelah pod baru siap untuk memproses permintaan dan ditambahkan ke grup server backend dari instance ALB, pod lama dihentikan.

      image

    4. Setelah semua pod lama menyelesaikan fungsi hook preStop atau shutdown yang halus dari pod habis waktu, kubectl mengirim sinyal ke pod lama untuk menghentikannya. Setelah pod dihentikan, pembaruan bergulir selesai.

      image

  4. Lihat hasil eksekusi skrip uji. Jika 200 dikembalikan untuk setiap permintaan, tidak ada gangguan layanan yang terjadi selama pembaruan bergulir.

    Jalankan perintah berikut untuk melihat hasil eksekusi skrip uji:

    cat log.txt

    Output yang diharapkan:

    image

Referensi